1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Mesa 3-D graphics library
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5bf215546Sopenharmony_ci * Copyright (C) 2009  VMware, Inc.   All Rights Reserved.
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
10bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
12bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included
15bf215546Sopenharmony_ci * in all copies or substantial portions of the Software.
16bf215546Sopenharmony_ci *
17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
24bf215546Sopenharmony_ci */
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include "glheader.h"
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "accum.h"
29bf215546Sopenharmony_ci#include "arrayobj.h"
30bf215546Sopenharmony_ci#include "attrib.h"
31bf215546Sopenharmony_ci#include "blend.h"
32bf215546Sopenharmony_ci#include "buffers.h"
33bf215546Sopenharmony_ci#include "bufferobj.h"
34bf215546Sopenharmony_ci#include "context.h"
35bf215546Sopenharmony_ci#include "depth.h"
36bf215546Sopenharmony_ci#include "enable.h"
37bf215546Sopenharmony_ci#include "enums.h"
38bf215546Sopenharmony_ci#include "fog.h"
39bf215546Sopenharmony_ci#include "hint.h"
40bf215546Sopenharmony_ci#include "light.h"
41bf215546Sopenharmony_ci#include "lines.h"
42bf215546Sopenharmony_ci#include "macros.h"
43bf215546Sopenharmony_ci#include "matrix.h"
44bf215546Sopenharmony_ci#include "multisample.h"
45bf215546Sopenharmony_ci#include "pixelstore.h"
46bf215546Sopenharmony_ci#include "points.h"
47bf215546Sopenharmony_ci#include "polygon.h"
48bf215546Sopenharmony_ci#include "shared.h"
49bf215546Sopenharmony_ci#include "scissor.h"
50bf215546Sopenharmony_ci#include "stencil.h"
51bf215546Sopenharmony_ci#include "texobj.h"
52bf215546Sopenharmony_ci#include "texparam.h"
53bf215546Sopenharmony_ci#include "texstate.h"
54bf215546Sopenharmony_ci#include "varray.h"
55bf215546Sopenharmony_ci#include "viewport.h"
56bf215546Sopenharmony_ci#include "mtypes.h"
57bf215546Sopenharmony_ci#include "state.h"
58bf215546Sopenharmony_ci#include "hash.h"
59bf215546Sopenharmony_ci#include <stdbool.h>
60bf215546Sopenharmony_ci#include "util/u_memory.h"
61bf215546Sopenharmony_ci#include "api_exec_decl.h"
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci#include "state_tracker/st_cb_texture.h"
64bf215546Sopenharmony_ci#include "state_tracker/st_manager.h"
65bf215546Sopenharmony_ci#include "state_tracker/st_sampler_view.h"
66bf215546Sopenharmony_ci
67bf215546Sopenharmony_cistatic inline bool
68bf215546Sopenharmony_cicopy_texture_attribs(struct gl_texture_object *dst,
69bf215546Sopenharmony_ci                     const struct gl_texture_object *src,
70bf215546Sopenharmony_ci                     gl_texture_index tex)
71bf215546Sopenharmony_ci{
72bf215546Sopenharmony_ci   /* All pushed fields have no effect on texture buffers. */
73bf215546Sopenharmony_ci   if (tex == TEXTURE_BUFFER_INDEX)
74bf215546Sopenharmony_ci      return false;
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci   /* Sampler fields have no effect on MSAA textures. */
77bf215546Sopenharmony_ci   if (tex != TEXTURE_2D_MULTISAMPLE_INDEX &&
78bf215546Sopenharmony_ci       tex != TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX) {
79bf215546Sopenharmony_ci      memcpy(&dst->Sampler.Attrib, &src->Sampler.Attrib,
80bf215546Sopenharmony_ci             sizeof(src->Sampler.Attrib));
81bf215546Sopenharmony_ci   }
82bf215546Sopenharmony_ci   memcpy(&dst->Attrib, &src->Attrib, sizeof(src->Attrib));
83bf215546Sopenharmony_ci   return true;
84bf215546Sopenharmony_ci}
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_civoid GLAPIENTRY
88bf215546Sopenharmony_ci_mesa_PushAttrib(GLbitfield mask)
89bf215546Sopenharmony_ci{
90bf215546Sopenharmony_ci   struct gl_attrib_node *head;
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_ci   if (MESA_VERBOSE & VERBOSE_API)
95bf215546Sopenharmony_ci      _mesa_debug(ctx, "glPushAttrib %x\n", (int) mask);
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci   if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) {
98bf215546Sopenharmony_ci      _mesa_error(ctx, GL_STACK_OVERFLOW, "glPushAttrib");
99bf215546Sopenharmony_ci      return;
100bf215546Sopenharmony_ci   }
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_ci   head = ctx->AttribStack[ctx->AttribStackDepth];
103bf215546Sopenharmony_ci   if (unlikely(!head)) {
104bf215546Sopenharmony_ci      head = CALLOC_STRUCT(gl_attrib_node);
105bf215546Sopenharmony_ci      if (unlikely(!head)) {
106bf215546Sopenharmony_ci         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
107bf215546Sopenharmony_ci         return;
108bf215546Sopenharmony_ci      }
109bf215546Sopenharmony_ci      ctx->AttribStack[ctx->AttribStackDepth] = head;
110bf215546Sopenharmony_ci   }
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci   head->Mask = mask;
113bf215546Sopenharmony_ci   head->OldPopAttribStateMask = ctx->PopAttribState;
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_ci   if (mask & GL_ACCUM_BUFFER_BIT)
116bf215546Sopenharmony_ci      memcpy(&head->Accum, &ctx->Accum, sizeof(head->Accum));
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci   if (mask & GL_COLOR_BUFFER_BIT) {
119bf215546Sopenharmony_ci      memcpy(&head->Color, &ctx->Color, sizeof(struct gl_colorbuffer_attrib));
120bf215546Sopenharmony_ci      /* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */
121bf215546Sopenharmony_ci      for (unsigned i = 0; i < ctx->Const.MaxDrawBuffers; i ++)
122bf215546Sopenharmony_ci         head->Color.DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i];
123bf215546Sopenharmony_ci   }
124bf215546Sopenharmony_ci
125bf215546Sopenharmony_ci   if (mask & GL_CURRENT_BIT) {
126bf215546Sopenharmony_ci      FLUSH_CURRENT(ctx, 0);
127bf215546Sopenharmony_ci      memcpy(&head->Current, &ctx->Current, sizeof(head->Current));
128bf215546Sopenharmony_ci   }
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_ci   if (mask & GL_DEPTH_BUFFER_BIT)
131bf215546Sopenharmony_ci      memcpy(&head->Depth, &ctx->Depth, sizeof(head->Depth));
132bf215546Sopenharmony_ci
133bf215546Sopenharmony_ci   if (mask & GL_ENABLE_BIT) {
134bf215546Sopenharmony_ci      struct gl_enable_attrib_node *attr = &head->Enable;
135bf215546Sopenharmony_ci      GLuint i;
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_ci      /* Copy enable flags from all other attributes into the enable struct. */
138bf215546Sopenharmony_ci      attr->AlphaTest = ctx->Color.AlphaEnabled;
139bf215546Sopenharmony_ci      attr->AutoNormal = ctx->Eval.AutoNormal;
140bf215546Sopenharmony_ci      attr->Blend = ctx->Color.BlendEnabled;
141bf215546Sopenharmony_ci      attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled;
142bf215546Sopenharmony_ci      attr->ColorMaterial = ctx->Light.ColorMaterialEnabled;
143bf215546Sopenharmony_ci      attr->CullFace = ctx->Polygon.CullFlag;
144bf215546Sopenharmony_ci      attr->DepthClampNear = ctx->Transform.DepthClampNear;
145bf215546Sopenharmony_ci      attr->DepthClampFar = ctx->Transform.DepthClampFar;
146bf215546Sopenharmony_ci      attr->DepthTest = ctx->Depth.Test;
147bf215546Sopenharmony_ci      attr->Dither = ctx->Color.DitherFlag;
148bf215546Sopenharmony_ci      attr->Fog = ctx->Fog.Enabled;
149bf215546Sopenharmony_ci      for (i = 0; i < ctx->Const.MaxLights; i++) {
150bf215546Sopenharmony_ci         attr->Light[i] = ctx->Light.Light[i].Enabled;
151bf215546Sopenharmony_ci      }
152bf215546Sopenharmony_ci      attr->Lighting = ctx->Light.Enabled;
153bf215546Sopenharmony_ci      attr->LineSmooth = ctx->Line.SmoothFlag;
154bf215546Sopenharmony_ci      attr->LineStipple = ctx->Line.StippleFlag;
155bf215546Sopenharmony_ci      attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled;
156bf215546Sopenharmony_ci      attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled;
157bf215546Sopenharmony_ci      attr->Map1Color4 = ctx->Eval.Map1Color4;
158bf215546Sopenharmony_ci      attr->Map1Index = ctx->Eval.Map1Index;
159bf215546Sopenharmony_ci      attr->Map1Normal = ctx->Eval.Map1Normal;
160bf215546Sopenharmony_ci      attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1;
161bf215546Sopenharmony_ci      attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2;
162bf215546Sopenharmony_ci      attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3;
163bf215546Sopenharmony_ci      attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4;
164bf215546Sopenharmony_ci      attr->Map1Vertex3 = ctx->Eval.Map1Vertex3;
165bf215546Sopenharmony_ci      attr->Map1Vertex4 = ctx->Eval.Map1Vertex4;
166bf215546Sopenharmony_ci      attr->Map2Color4 = ctx->Eval.Map2Color4;
167bf215546Sopenharmony_ci      attr->Map2Index = ctx->Eval.Map2Index;
168bf215546Sopenharmony_ci      attr->Map2Normal = ctx->Eval.Map2Normal;
169bf215546Sopenharmony_ci      attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1;
170bf215546Sopenharmony_ci      attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2;
171bf215546Sopenharmony_ci      attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3;
172bf215546Sopenharmony_ci      attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4;
173bf215546Sopenharmony_ci      attr->Map2Vertex3 = ctx->Eval.Map2Vertex3;
174bf215546Sopenharmony_ci      attr->Map2Vertex4 = ctx->Eval.Map2Vertex4;
175bf215546Sopenharmony_ci      attr->Normalize = ctx->Transform.Normalize;
176bf215546Sopenharmony_ci      attr->RasterPositionUnclipped = ctx->Transform.RasterPositionUnclipped;
177bf215546Sopenharmony_ci      attr->PointSmooth = ctx->Point.SmoothFlag;
178bf215546Sopenharmony_ci      attr->PointSprite = ctx->Point.PointSprite;
179bf215546Sopenharmony_ci      attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint;
180bf215546Sopenharmony_ci      attr->PolygonOffsetLine = ctx->Polygon.OffsetLine;
181bf215546Sopenharmony_ci      attr->PolygonOffsetFill = ctx->Polygon.OffsetFill;
182bf215546Sopenharmony_ci      attr->PolygonSmooth = ctx->Polygon.SmoothFlag;
183bf215546Sopenharmony_ci      attr->PolygonStipple = ctx->Polygon.StippleFlag;
184bf215546Sopenharmony_ci      attr->RescaleNormals = ctx->Transform.RescaleNormals;
185bf215546Sopenharmony_ci      attr->Scissor = ctx->Scissor.EnableFlags;
186bf215546Sopenharmony_ci      attr->Stencil = ctx->Stencil.Enabled;
187bf215546Sopenharmony_ci      attr->StencilTwoSide = ctx->Stencil.TestTwoSide;
188bf215546Sopenharmony_ci      attr->MultisampleEnabled = ctx->Multisample.Enabled;
189bf215546Sopenharmony_ci      attr->SampleAlphaToCoverage = ctx->Multisample.SampleAlphaToCoverage;
190bf215546Sopenharmony_ci      attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne;
191bf215546Sopenharmony_ci      attr->SampleCoverage = ctx->Multisample.SampleCoverage;
192bf215546Sopenharmony_ci      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
193bf215546Sopenharmony_ci         attr->Texture[i] = ctx->Texture.FixedFuncUnit[i].Enabled;
194bf215546Sopenharmony_ci         attr->TexGen[i] = ctx->Texture.FixedFuncUnit[i].TexGenEnabled;
195bf215546Sopenharmony_ci      }
196bf215546Sopenharmony_ci      /* GL_ARB_vertex_program */
197bf215546Sopenharmony_ci      attr->VertexProgram = ctx->VertexProgram.Enabled;
198bf215546Sopenharmony_ci      attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled;
199bf215546Sopenharmony_ci      attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled;
200bf215546Sopenharmony_ci
201bf215546Sopenharmony_ci      /* GL_ARB_fragment_program */
202bf215546Sopenharmony_ci      attr->FragmentProgram = ctx->FragmentProgram.Enabled;
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_ci      /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
205bf215546Sopenharmony_ci      attr->sRGBEnabled = ctx->Color.sRGBEnabled;
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ci      /* GL_NV_conservative_raster */
208bf215546Sopenharmony_ci      attr->ConservativeRasterization = ctx->ConservativeRasterization;
209bf215546Sopenharmony_ci   }
210bf215546Sopenharmony_ci
211bf215546Sopenharmony_ci   if (mask & GL_EVAL_BIT)
212bf215546Sopenharmony_ci      memcpy(&head->Eval, &ctx->Eval, sizeof(head->Eval));
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_ci   if (mask & GL_FOG_BIT)
215bf215546Sopenharmony_ci      memcpy(&head->Fog, &ctx->Fog, sizeof(head->Fog));
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_ci   if (mask & GL_HINT_BIT)
218bf215546Sopenharmony_ci      memcpy(&head->Hint, &ctx->Hint, sizeof(head->Hint));
219bf215546Sopenharmony_ci
220bf215546Sopenharmony_ci   if (mask & GL_LIGHTING_BIT) {
221bf215546Sopenharmony_ci      FLUSH_CURRENT(ctx, 0);   /* flush material changes */
222bf215546Sopenharmony_ci      memcpy(&head->Light, &ctx->Light, sizeof(head->Light));
223bf215546Sopenharmony_ci   }
224bf215546Sopenharmony_ci
225bf215546Sopenharmony_ci   if (mask & GL_LINE_BIT)
226bf215546Sopenharmony_ci      memcpy(&head->Line, &ctx->Line, sizeof(head->Line));
227bf215546Sopenharmony_ci
228bf215546Sopenharmony_ci   if (mask & GL_LIST_BIT)
229bf215546Sopenharmony_ci      memcpy(&head->List, &ctx->List, sizeof(head->List));
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci   if (mask & GL_PIXEL_MODE_BIT) {
232bf215546Sopenharmony_ci      memcpy(&head->Pixel, &ctx->Pixel, sizeof(struct gl_pixel_attrib));
233bf215546Sopenharmony_ci      /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */
234bf215546Sopenharmony_ci      head->Pixel.ReadBuffer = ctx->ReadBuffer->ColorReadBuffer;
235bf215546Sopenharmony_ci   }
236bf215546Sopenharmony_ci
237bf215546Sopenharmony_ci   if (mask & GL_POINT_BIT)
238bf215546Sopenharmony_ci      memcpy(&head->Point, &ctx->Point, sizeof(head->Point));
239bf215546Sopenharmony_ci
240bf215546Sopenharmony_ci   if (mask & GL_POLYGON_BIT)
241bf215546Sopenharmony_ci      memcpy(&head->Polygon, &ctx->Polygon, sizeof(head->Polygon));
242bf215546Sopenharmony_ci
243bf215546Sopenharmony_ci   if (mask & GL_POLYGON_STIPPLE_BIT) {
244bf215546Sopenharmony_ci      memcpy(&head->PolygonStipple, &ctx->PolygonStipple,
245bf215546Sopenharmony_ci             sizeof(head->PolygonStipple));
246bf215546Sopenharmony_ci   }
247bf215546Sopenharmony_ci
248bf215546Sopenharmony_ci   if (mask & GL_SCISSOR_BIT)
249bf215546Sopenharmony_ci      memcpy(&head->Scissor, &ctx->Scissor, sizeof(head->Scissor));
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_ci   if (mask & GL_STENCIL_BUFFER_BIT)
252bf215546Sopenharmony_ci      memcpy(&head->Stencil, &ctx->Stencil, sizeof(head->Stencil));
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci   if (mask & GL_TEXTURE_BIT) {
255bf215546Sopenharmony_ci      GLuint u, tex;
256bf215546Sopenharmony_ci
257bf215546Sopenharmony_ci      _mesa_lock_context_textures(ctx);
258bf215546Sopenharmony_ci
259bf215546Sopenharmony_ci      /* copy/save the bulk of texture state here */
260bf215546Sopenharmony_ci      head->Texture.CurrentUnit = ctx->Texture.CurrentUnit;
261bf215546Sopenharmony_ci      memcpy(&head->Texture.FixedFuncUnit, &ctx->Texture.FixedFuncUnit,
262bf215546Sopenharmony_ci             sizeof(ctx->Texture.FixedFuncUnit));
263bf215546Sopenharmony_ci
264bf215546Sopenharmony_ci      /* Copy/save contents of default texture objects. They are almost
265bf215546Sopenharmony_ci       * always bound, so this can be done unconditionally.
266bf215546Sopenharmony_ci       *
267bf215546Sopenharmony_ci       * We save them separately, so that we don't have to save them in every
268bf215546Sopenharmony_ci       * texture unit where they are bound. This decreases CPU overhead.
269bf215546Sopenharmony_ci       */
270bf215546Sopenharmony_ci      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
271bf215546Sopenharmony_ci         struct gl_texture_object *dst = &head->Texture.SavedDefaultObj[tex];
272bf215546Sopenharmony_ci         struct gl_texture_object *src = ctx->Shared->DefaultTex[tex];
273bf215546Sopenharmony_ci
274bf215546Sopenharmony_ci         copy_texture_attribs(dst, src, tex);
275bf215546Sopenharmony_ci      }
276bf215546Sopenharmony_ci
277bf215546Sopenharmony_ci      /* copy state/contents of the currently bound texture objects */
278bf215546Sopenharmony_ci      unsigned num_tex_used = ctx->Texture.NumCurrentTexUsed;
279bf215546Sopenharmony_ci      for (u = 0; u < num_tex_used; u++) {
280bf215546Sopenharmony_ci         head->Texture.LodBias[u] = ctx->Texture.Unit[u].LodBias;
281bf215546Sopenharmony_ci         head->Texture.LodBiasQuantized[u] = ctx->Texture.Unit[u].LodBiasQuantized;
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ci         for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
284bf215546Sopenharmony_ci            struct gl_texture_object *dst = &head->Texture.SavedObj[u][tex];
285bf215546Sopenharmony_ci            struct gl_texture_object *src = ctx->Texture.Unit[u].CurrentTex[tex];
286bf215546Sopenharmony_ci
287bf215546Sopenharmony_ci            dst->Name = src->Name;
288bf215546Sopenharmony_ci
289bf215546Sopenharmony_ci            /* Default texture targets are saved separately above. */
290bf215546Sopenharmony_ci            if (src->Name != 0)
291bf215546Sopenharmony_ci               copy_texture_attribs(dst, src, tex);
292bf215546Sopenharmony_ci         }
293bf215546Sopenharmony_ci      }
294bf215546Sopenharmony_ci      head->Texture.NumTexSaved = num_tex_used;
295bf215546Sopenharmony_ci      _mesa_unlock_context_textures(ctx);
296bf215546Sopenharmony_ci   }
297bf215546Sopenharmony_ci
298bf215546Sopenharmony_ci   if (mask & GL_TRANSFORM_BIT)
299bf215546Sopenharmony_ci      memcpy(&head->Transform, &ctx->Transform, sizeof(head->Transform));
300bf215546Sopenharmony_ci
301bf215546Sopenharmony_ci   if (mask & GL_VIEWPORT_BIT) {
302bf215546Sopenharmony_ci      memcpy(&head->Viewport.ViewportArray, &ctx->ViewportArray,
303bf215546Sopenharmony_ci             sizeof(struct gl_viewport_attrib)*ctx->Const.MaxViewports);
304bf215546Sopenharmony_ci
305bf215546Sopenharmony_ci      head->Viewport.SubpixelPrecisionBias[0] = ctx->SubpixelPrecisionBias[0];
306bf215546Sopenharmony_ci      head->Viewport.SubpixelPrecisionBias[1] = ctx->SubpixelPrecisionBias[1];
307bf215546Sopenharmony_ci   }
308bf215546Sopenharmony_ci
309bf215546Sopenharmony_ci   /* GL_ARB_multisample */
310bf215546Sopenharmony_ci   if (mask & GL_MULTISAMPLE_BIT_ARB)
311bf215546Sopenharmony_ci      memcpy(&head->Multisample, &ctx->Multisample, sizeof(head->Multisample));
312bf215546Sopenharmony_ci
313bf215546Sopenharmony_ci   ctx->AttribStackDepth++;
314bf215546Sopenharmony_ci   ctx->PopAttribState = 0;
315bf215546Sopenharmony_ci}
316bf215546Sopenharmony_ci
317bf215546Sopenharmony_ci
318bf215546Sopenharmony_ci#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) do {  \
319bf215546Sopenharmony_ci      if ((VALUE) != (NEWVALUE))                     \
320bf215546Sopenharmony_ci         _mesa_set_enable(ctx, ENUM, (NEWVALUE));    \
321bf215546Sopenharmony_ci   } while (0)
322bf215546Sopenharmony_ci
323bf215546Sopenharmony_ci#define TEST_AND_UPDATE_BIT(VALUE, NEW_VALUE, BIT, ENUM) do {                 \
324bf215546Sopenharmony_ci      if (((VALUE) & BITFIELD_BIT(BIT)) != ((NEW_VALUE) & BITFIELD_BIT(BIT))) \
325bf215546Sopenharmony_ci         _mesa_set_enable(ctx, ENUM, ((NEW_VALUE) >> (BIT)) & 0x1);           \
326bf215546Sopenharmony_ci   } while (0)
327bf215546Sopenharmony_ci
328bf215546Sopenharmony_ci#define TEST_AND_UPDATE_INDEX(VALUE, NEW_VALUE, INDEX, ENUM) do {                 \
329bf215546Sopenharmony_ci      if (((VALUE) & BITFIELD_BIT(INDEX)) != ((NEW_VALUE) & BITFIELD_BIT(INDEX))) \
330bf215546Sopenharmony_ci         _mesa_set_enablei(ctx, ENUM, INDEX, ((NEW_VALUE) >> (INDEX)) & 0x1);     \
331bf215546Sopenharmony_ci   } while (0)
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_ci
334bf215546Sopenharmony_cistatic void
335bf215546Sopenharmony_cipop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib_node *enable)
336bf215546Sopenharmony_ci{
337bf215546Sopenharmony_ci   GLuint i;
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST);
340bf215546Sopenharmony_ci   if (ctx->Color.BlendEnabled != enable->Blend) {
341bf215546Sopenharmony_ci      if (ctx->Extensions.EXT_draw_buffers2) {
342bf215546Sopenharmony_ci         for (unsigned i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
343bf215546Sopenharmony_ci            TEST_AND_UPDATE_INDEX(ctx->Color.BlendEnabled, enable->Blend,
344bf215546Sopenharmony_ci                                  i, GL_BLEND);
345bf215546Sopenharmony_ci         }
346bf215546Sopenharmony_ci      } else {
347bf215546Sopenharmony_ci         _mesa_set_enable(ctx, GL_BLEND, (enable->Blend & 1));
348bf215546Sopenharmony_ci      }
349bf215546Sopenharmony_ci   }
350bf215546Sopenharmony_ci
351bf215546Sopenharmony_ci   if (ctx->Transform.ClipPlanesEnabled != enable->ClipPlanes) {
352bf215546Sopenharmony_ci      for (unsigned i = 0; i < ctx->Const.MaxClipPlanes; i++) {
353bf215546Sopenharmony_ci         TEST_AND_UPDATE_BIT(ctx->Transform.ClipPlanesEnabled,
354bf215546Sopenharmony_ci                             enable->ClipPlanes, i, GL_CLIP_PLANE0 + i);
355bf215546Sopenharmony_ci      }
356bf215546Sopenharmony_ci   }
357bf215546Sopenharmony_ci
358bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial,
359bf215546Sopenharmony_ci                   GL_COLOR_MATERIAL);
360bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
361bf215546Sopenharmony_ci
362bf215546Sopenharmony_ci   if (!ctx->Extensions.AMD_depth_clamp_separate) {
363bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar,
364bf215546Sopenharmony_ci                      enable->DepthClampNear && enable->DepthClampFar,
365bf215546Sopenharmony_ci                      GL_DEPTH_CLAMP);
366bf215546Sopenharmony_ci   } else {
367bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Transform.DepthClampNear, enable->DepthClampNear,
368bf215546Sopenharmony_ci                      GL_DEPTH_CLAMP_NEAR_AMD);
369bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Transform.DepthClampFar, enable->DepthClampFar,
370bf215546Sopenharmony_ci                      GL_DEPTH_CLAMP_FAR_AMD);
371bf215546Sopenharmony_ci   }
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST);
374bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER);
375bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG);
376bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING);
377bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH);
378bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple,
379bf215546Sopenharmony_ci                   GL_LINE_STIPPLE);
380bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp,
381bf215546Sopenharmony_ci                   GL_INDEX_LOGIC_OP);
382bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp,
383bf215546Sopenharmony_ci                   GL_COLOR_LOGIC_OP);
384bf215546Sopenharmony_ci
385bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4);
386bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX);
387bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL);
388bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1,
389bf215546Sopenharmony_ci                   GL_MAP1_TEXTURE_COORD_1);
390bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2,
391bf215546Sopenharmony_ci                   GL_MAP1_TEXTURE_COORD_2);
392bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3,
393bf215546Sopenharmony_ci                   GL_MAP1_TEXTURE_COORD_3);
394bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4,
395bf215546Sopenharmony_ci                   GL_MAP1_TEXTURE_COORD_4);
396bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3,
397bf215546Sopenharmony_ci                   GL_MAP1_VERTEX_3);
398bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4,
399bf215546Sopenharmony_ci                   GL_MAP1_VERTEX_4);
400bf215546Sopenharmony_ci
401bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4);
402bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX);
403bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL);
404bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1,
405bf215546Sopenharmony_ci                   GL_MAP2_TEXTURE_COORD_1);
406bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2,
407bf215546Sopenharmony_ci                   GL_MAP2_TEXTURE_COORD_2);
408bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3,
409bf215546Sopenharmony_ci                   GL_MAP2_TEXTURE_COORD_3);
410bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4,
411bf215546Sopenharmony_ci                   GL_MAP2_TEXTURE_COORD_4);
412bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3,
413bf215546Sopenharmony_ci                   GL_MAP2_VERTEX_3);
414bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4,
415bf215546Sopenharmony_ci                   GL_MAP2_VERTEX_4);
416bf215546Sopenharmony_ci
417bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Eval.AutoNormal, enable->AutoNormal, GL_AUTO_NORMAL);
418bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE);
419bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals,
420bf215546Sopenharmony_ci                   GL_RESCALE_NORMAL_EXT);
421bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Transform.RasterPositionUnclipped,
422bf215546Sopenharmony_ci                   enable->RasterPositionUnclipped,
423bf215546Sopenharmony_ci                   GL_RASTER_POSITION_UNCLIPPED_IBM);
424bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth,
425bf215546Sopenharmony_ci                   GL_POINT_SMOOTH);
426bf215546Sopenharmony_ci   if (ctx->Extensions.ARB_point_sprite) {
427bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite,
428bf215546Sopenharmony_ci                      GL_POINT_SPRITE);
429bf215546Sopenharmony_ci   }
430bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint,
431bf215546Sopenharmony_ci                   GL_POLYGON_OFFSET_POINT);
432bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine,
433bf215546Sopenharmony_ci                   GL_POLYGON_OFFSET_LINE);
434bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill,
435bf215546Sopenharmony_ci                   GL_POLYGON_OFFSET_FILL);
436bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth,
437bf215546Sopenharmony_ci                   GL_POLYGON_SMOOTH);
438bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple,
439bf215546Sopenharmony_ci                   GL_POLYGON_STIPPLE);
440bf215546Sopenharmony_ci   if (ctx->Scissor.EnableFlags != enable->Scissor) {
441bf215546Sopenharmony_ci      unsigned i;
442bf215546Sopenharmony_ci
443bf215546Sopenharmony_ci      for (i = 0; i < ctx->Const.MaxViewports; i++) {
444bf215546Sopenharmony_ci         TEST_AND_UPDATE_INDEX(ctx->Scissor.EnableFlags, enable->Scissor,
445bf215546Sopenharmony_ci                               i, GL_SCISSOR_TEST);
446bf215546Sopenharmony_ci      }
447bf215546Sopenharmony_ci   }
448bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST);
449bf215546Sopenharmony_ci   if (ctx->Extensions.EXT_stencil_two_side) {
450bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, enable->StencilTwoSide,
451bf215546Sopenharmony_ci                      GL_STENCIL_TEST_TWO_SIDE_EXT);
452bf215546Sopenharmony_ci   }
453bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled,
454bf215546Sopenharmony_ci                   GL_MULTISAMPLE_ARB);
455bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage,
456bf215546Sopenharmony_ci                   enable->SampleAlphaToCoverage,
457bf215546Sopenharmony_ci                   GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
458bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne,
459bf215546Sopenharmony_ci                   enable->SampleAlphaToOne,
460bf215546Sopenharmony_ci                   GL_SAMPLE_ALPHA_TO_ONE_ARB);
461bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Multisample.SampleCoverage,
462bf215546Sopenharmony_ci                   enable->SampleCoverage,
463bf215546Sopenharmony_ci                   GL_SAMPLE_COVERAGE_ARB);
464bf215546Sopenharmony_ci   /* GL_ARB_vertex_program */
465bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->VertexProgram.Enabled,
466bf215546Sopenharmony_ci                   enable->VertexProgram,
467bf215546Sopenharmony_ci                   GL_VERTEX_PROGRAM_ARB);
468bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->VertexProgram.PointSizeEnabled,
469bf215546Sopenharmony_ci                   enable->VertexProgramPointSize,
470bf215546Sopenharmony_ci                   GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
471bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->VertexProgram.TwoSideEnabled,
472bf215546Sopenharmony_ci                   enable->VertexProgramTwoSide,
473bf215546Sopenharmony_ci                   GL_VERTEX_PROGRAM_TWO_SIDE_ARB);
474bf215546Sopenharmony_ci
475bf215546Sopenharmony_ci   /* GL_ARB_fragment_program */
476bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->FragmentProgram.Enabled,
477bf215546Sopenharmony_ci                   enable->FragmentProgram,
478bf215546Sopenharmony_ci                   GL_FRAGMENT_PROGRAM_ARB);
479bf215546Sopenharmony_ci
480bf215546Sopenharmony_ci   /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
481bf215546Sopenharmony_ci   TEST_AND_UPDATE(ctx->Color.sRGBEnabled, enable->sRGBEnabled,
482bf215546Sopenharmony_ci                   GL_FRAMEBUFFER_SRGB);
483bf215546Sopenharmony_ci
484bf215546Sopenharmony_ci   /* GL_NV_conservative_raster */
485bf215546Sopenharmony_ci   if (ctx->Extensions.NV_conservative_raster) {
486bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->ConservativeRasterization,
487bf215546Sopenharmony_ci                      enable->ConservativeRasterization,
488bf215546Sopenharmony_ci                      GL_CONSERVATIVE_RASTERIZATION_NV);
489bf215546Sopenharmony_ci   }
490bf215546Sopenharmony_ci
491bf215546Sopenharmony_ci   const unsigned curTexUnitSave = ctx->Texture.CurrentUnit;
492bf215546Sopenharmony_ci
493bf215546Sopenharmony_ci   /* texture unit enables */
494bf215546Sopenharmony_ci   for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
495bf215546Sopenharmony_ci      const GLbitfield enabled = enable->Texture[i];
496bf215546Sopenharmony_ci      const GLbitfield gen_enabled = enable->TexGen[i];
497bf215546Sopenharmony_ci      const struct gl_fixedfunc_texture_unit *unit = &ctx->Texture.FixedFuncUnit[i];
498bf215546Sopenharmony_ci      const GLbitfield old_enabled = unit->Enabled;
499bf215546Sopenharmony_ci      const GLbitfield old_gen_enabled = unit->TexGenEnabled;
500bf215546Sopenharmony_ci
501bf215546Sopenharmony_ci      if (old_enabled == enabled && old_gen_enabled == gen_enabled)
502bf215546Sopenharmony_ci         continue;
503bf215546Sopenharmony_ci
504bf215546Sopenharmony_ci      ctx->Texture.CurrentUnit = i;
505bf215546Sopenharmony_ci
506bf215546Sopenharmony_ci      if (old_enabled != enabled) {
507bf215546Sopenharmony_ci         TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_1D_INDEX, GL_TEXTURE_1D);
508bf215546Sopenharmony_ci         TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_2D_INDEX, GL_TEXTURE_2D);
509bf215546Sopenharmony_ci         TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_3D_INDEX, GL_TEXTURE_3D);
510bf215546Sopenharmony_ci         if (ctx->Extensions.NV_texture_rectangle) {
511bf215546Sopenharmony_ci            TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_RECT_INDEX,
512bf215546Sopenharmony_ci                                GL_TEXTURE_RECTANGLE);
513bf215546Sopenharmony_ci         }
514bf215546Sopenharmony_ci         TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_CUBE_INDEX,
515bf215546Sopenharmony_ci                             GL_TEXTURE_CUBE_MAP);
516bf215546Sopenharmony_ci      }
517bf215546Sopenharmony_ci
518bf215546Sopenharmony_ci      if (old_gen_enabled != gen_enabled) {
519bf215546Sopenharmony_ci         TEST_AND_UPDATE_BIT(old_gen_enabled, gen_enabled, 0, GL_TEXTURE_GEN_S);
520bf215546Sopenharmony_ci         TEST_AND_UPDATE_BIT(old_gen_enabled, gen_enabled, 1, GL_TEXTURE_GEN_T);
521bf215546Sopenharmony_ci         TEST_AND_UPDATE_BIT(old_gen_enabled, gen_enabled, 2, GL_TEXTURE_GEN_R);
522bf215546Sopenharmony_ci         TEST_AND_UPDATE_BIT(old_gen_enabled, gen_enabled, 3, GL_TEXTURE_GEN_Q);
523bf215546Sopenharmony_ci      }
524bf215546Sopenharmony_ci   }
525bf215546Sopenharmony_ci
526bf215546Sopenharmony_ci   ctx->Texture.CurrentUnit = curTexUnitSave;
527bf215546Sopenharmony_ci}
528bf215546Sopenharmony_ci
529bf215546Sopenharmony_ci
530bf215546Sopenharmony_ci/**
531bf215546Sopenharmony_ci * Pop/restore texture attribute/group state.
532bf215546Sopenharmony_ci */
533bf215546Sopenharmony_cistatic void
534bf215546Sopenharmony_cipop_texture_group(struct gl_context *ctx, struct gl_texture_attrib_node *texstate)
535bf215546Sopenharmony_ci{
536bf215546Sopenharmony_ci   GLuint u;
537bf215546Sopenharmony_ci
538bf215546Sopenharmony_ci   _mesa_lock_context_textures(ctx);
539bf215546Sopenharmony_ci
540bf215546Sopenharmony_ci   /* Restore fixed-function texture unit states. */
541bf215546Sopenharmony_ci   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
542bf215546Sopenharmony_ci      const struct gl_fixedfunc_texture_unit *unit =
543bf215546Sopenharmony_ci         &texstate->FixedFuncUnit[u];
544bf215546Sopenharmony_ci      struct gl_fixedfunc_texture_unit *destUnit =
545bf215546Sopenharmony_ci         &ctx->Texture.FixedFuncUnit[u];
546bf215546Sopenharmony_ci
547bf215546Sopenharmony_ci      ctx->Texture.CurrentUnit = u;
548bf215546Sopenharmony_ci
549bf215546Sopenharmony_ci      /* Fast path for other drivers. */
550bf215546Sopenharmony_ci      memcpy(destUnit, unit, sizeof(*unit));
551bf215546Sopenharmony_ci      destUnit->_CurrentCombine = NULL;
552bf215546Sopenharmony_ci      ctx->Texture.Unit[u].LodBias = texstate->LodBias[u];
553bf215546Sopenharmony_ci      ctx->Texture.Unit[u].LodBiasQuantized = texstate->LodBiasQuantized[u];
554bf215546Sopenharmony_ci   }
555bf215546Sopenharmony_ci
556bf215546Sopenharmony_ci   /* Restore saved textures. */
557bf215546Sopenharmony_ci   unsigned num_tex_saved = texstate->NumTexSaved;
558bf215546Sopenharmony_ci   for (u = 0; u < num_tex_saved; u++) {
559bf215546Sopenharmony_ci      gl_texture_index tgt;
560bf215546Sopenharmony_ci
561bf215546Sopenharmony_ci      ctx->Texture.CurrentUnit = u;
562bf215546Sopenharmony_ci
563bf215546Sopenharmony_ci      /* Restore texture object state for each target */
564bf215546Sopenharmony_ci      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
565bf215546Sopenharmony_ci         const struct gl_texture_object *savedObj = &texstate->SavedObj[u][tgt];
566bf215546Sopenharmony_ci         struct gl_texture_object *texObj =
567bf215546Sopenharmony_ci            _mesa_get_tex_unit(ctx, u)->CurrentTex[tgt];
568bf215546Sopenharmony_ci         bool is_msaa = tgt == TEXTURE_2D_MULTISAMPLE_INDEX ||
569bf215546Sopenharmony_ci                        tgt == TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX;
570bf215546Sopenharmony_ci
571bf215546Sopenharmony_ci         /* According to the OpenGL 4.6 Compatibility Profile specification,
572bf215546Sopenharmony_ci          * table 23.17, GL_TEXTURE_BINDING_2D_MULTISAMPLE and
573bf215546Sopenharmony_ci          * GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY do not belong in the
574bf215546Sopenharmony_ci          * texture attrib group.
575bf215546Sopenharmony_ci          */
576bf215546Sopenharmony_ci         if (!is_msaa && texObj->Name != savedObj->Name) {
577bf215546Sopenharmony_ci            /* We don't need to check whether the texture target is supported,
578bf215546Sopenharmony_ci             * because we wouldn't get in this conditional block if it wasn't.
579bf215546Sopenharmony_ci             */
580bf215546Sopenharmony_ci            _mesa_BindTexture_no_error(texObj->Target, savedObj->Name);
581bf215546Sopenharmony_ci            texObj = _mesa_get_tex_unit(ctx, u)->CurrentTex[tgt];
582bf215546Sopenharmony_ci         }
583bf215546Sopenharmony_ci
584bf215546Sopenharmony_ci         /* Default texture object states are restored separately below. */
585bf215546Sopenharmony_ci         if (texObj->Name == 0)
586bf215546Sopenharmony_ci            continue;
587bf215546Sopenharmony_ci
588bf215546Sopenharmony_ci         /* But in the MSAA case, where the currently-bound object is not the
589bf215546Sopenharmony_ci          * default state, we should still restore the saved default object's
590bf215546Sopenharmony_ci          * data when that's what was saved initially.
591bf215546Sopenharmony_ci          */
592bf215546Sopenharmony_ci         if (savedObj->Name == 0)
593bf215546Sopenharmony_ci            savedObj = &texstate->SavedDefaultObj[tgt];
594bf215546Sopenharmony_ci
595bf215546Sopenharmony_ci         if (!copy_texture_attribs(texObj, savedObj, tgt))
596bf215546Sopenharmony_ci            continue;
597bf215546Sopenharmony_ci
598bf215546Sopenharmony_ci         st_texture_release_all_sampler_views(st_context(ctx), texObj);
599bf215546Sopenharmony_ci      }
600bf215546Sopenharmony_ci   }
601bf215546Sopenharmony_ci
602bf215546Sopenharmony_ci   /* Restore textures in units that were not used before glPushAttrib (thus
603bf215546Sopenharmony_ci    * they were not saved) but were used after glPushAttrib. Revert
604bf215546Sopenharmony_ci    * the bindings to Name = 0.
605bf215546Sopenharmony_ci    */
606bf215546Sopenharmony_ci   unsigned num_tex_changed = ctx->Texture.NumCurrentTexUsed;
607bf215546Sopenharmony_ci   for (u = num_tex_saved; u < num_tex_changed; u++) {
608bf215546Sopenharmony_ci      ctx->Texture.CurrentUnit = u;
609bf215546Sopenharmony_ci
610bf215546Sopenharmony_ci      for (gl_texture_index tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
611bf215546Sopenharmony_ci         struct gl_texture_object *texObj =
612bf215546Sopenharmony_ci            _mesa_get_tex_unit(ctx, u)->CurrentTex[tgt];
613bf215546Sopenharmony_ci         bool is_msaa = tgt == TEXTURE_2D_MULTISAMPLE_INDEX ||
614bf215546Sopenharmony_ci                        tgt == TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX;
615bf215546Sopenharmony_ci
616bf215546Sopenharmony_ci         /* According to the OpenGL 4.6 Compatibility Profile specification,
617bf215546Sopenharmony_ci          * table 23.17, GL_TEXTURE_BINDING_2D_MULTISAMPLE and
618bf215546Sopenharmony_ci          * GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY do not belong in the
619bf215546Sopenharmony_ci          * texture attrib group.
620bf215546Sopenharmony_ci          */
621bf215546Sopenharmony_ci         if (!is_msaa && texObj->Name != 0) {
622bf215546Sopenharmony_ci            /* We don't need to check whether the texture target is supported,
623bf215546Sopenharmony_ci             * because we wouldn't get in this conditional block if it wasn't.
624bf215546Sopenharmony_ci             */
625bf215546Sopenharmony_ci            _mesa_BindTexture_no_error(texObj->Target, 0);
626bf215546Sopenharmony_ci         }
627bf215546Sopenharmony_ci      }
628bf215546Sopenharmony_ci   }
629bf215546Sopenharmony_ci
630bf215546Sopenharmony_ci   /* Restore default texture object states. */
631bf215546Sopenharmony_ci   for (gl_texture_index tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
632bf215546Sopenharmony_ci      struct gl_texture_object *dst = ctx->Shared->DefaultTex[tex];
633bf215546Sopenharmony_ci      const struct gl_texture_object *src = &texstate->SavedDefaultObj[tex];
634bf215546Sopenharmony_ci
635bf215546Sopenharmony_ci      copy_texture_attribs(dst, src, tex);
636bf215546Sopenharmony_ci   }
637bf215546Sopenharmony_ci
638bf215546Sopenharmony_ci   _mesa_ActiveTexture(GL_TEXTURE0_ARB + texstate->CurrentUnit);
639bf215546Sopenharmony_ci   _mesa_unlock_context_textures(ctx);
640bf215546Sopenharmony_ci}
641bf215546Sopenharmony_ci
642bf215546Sopenharmony_ci
643bf215546Sopenharmony_ci#define TEST_AND_CALL1(FIELD, CALL) do { \
644bf215546Sopenharmony_ci      if (ctx->FIELD != attr->FIELD)     \
645bf215546Sopenharmony_ci         _mesa_##CALL(attr->FIELD);      \
646bf215546Sopenharmony_ci   } while (0)
647bf215546Sopenharmony_ci
648bf215546Sopenharmony_ci#define TEST_AND_CALL1_SEL(FIELD, CALL, SEL) do { \
649bf215546Sopenharmony_ci      if (ctx->FIELD != attr->FIELD)              \
650bf215546Sopenharmony_ci         _mesa_##CALL(SEL, attr->FIELD);          \
651bf215546Sopenharmony_ci   } while (0)
652bf215546Sopenharmony_ci
653bf215546Sopenharmony_ci#define TEST_AND_CALL2(FIELD1, FIELD2, CALL) do {                     \
654bf215546Sopenharmony_ci      if (ctx->FIELD1 != attr->FIELD1 || ctx->FIELD2 != attr->FIELD2) \
655bf215546Sopenharmony_ci         _mesa_##CALL(attr->FIELD1, attr->FIELD2);                    \
656bf215546Sopenharmony_ci   } while (0)
657bf215546Sopenharmony_ci
658bf215546Sopenharmony_ci
659bf215546Sopenharmony_ci/*
660bf215546Sopenharmony_ci * This function is kind of long just because we have to call a lot
661bf215546Sopenharmony_ci * of device driver functions to update device driver state.
662bf215546Sopenharmony_ci *
663bf215546Sopenharmony_ci * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions
664bf215546Sopenharmony_ci * in order to restore GL state.  This isn't terribly efficient but it
665bf215546Sopenharmony_ci * ensures that dirty flags and any derived state gets updated correctly.
666bf215546Sopenharmony_ci * We could at least check if the value to restore equals the current value
667bf215546Sopenharmony_ci * and then skip the Mesa call.
668bf215546Sopenharmony_ci */
669bf215546Sopenharmony_civoid GLAPIENTRY
670bf215546Sopenharmony_ci_mesa_PopAttrib(void)
671bf215546Sopenharmony_ci{
672bf215546Sopenharmony_ci   struct gl_attrib_node *attr;
673bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
674bf215546Sopenharmony_ci   FLUSH_VERTICES(ctx, 0, 0);
675bf215546Sopenharmony_ci
676bf215546Sopenharmony_ci   if (ctx->AttribStackDepth == 0) {
677bf215546Sopenharmony_ci      _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopAttrib");
678bf215546Sopenharmony_ci      return;
679bf215546Sopenharmony_ci   }
680bf215546Sopenharmony_ci
681bf215546Sopenharmony_ci   ctx->AttribStackDepth--;
682bf215546Sopenharmony_ci   attr = ctx->AttribStack[ctx->AttribStackDepth];
683bf215546Sopenharmony_ci
684bf215546Sopenharmony_ci   unsigned mask = attr->Mask;
685bf215546Sopenharmony_ci
686bf215546Sopenharmony_ci   /* Flush current attribs. This must be done before PopAttribState is
687bf215546Sopenharmony_ci    * applied.
688bf215546Sopenharmony_ci    */
689bf215546Sopenharmony_ci   if (mask & GL_CURRENT_BIT)
690bf215546Sopenharmony_ci      FLUSH_CURRENT(ctx, 0);
691bf215546Sopenharmony_ci
692bf215546Sopenharmony_ci   /* Only restore states that have been changed since glPushAttrib. */
693bf215546Sopenharmony_ci   mask &= ctx->PopAttribState;
694bf215546Sopenharmony_ci
695bf215546Sopenharmony_ci   if (mask & GL_ACCUM_BUFFER_BIT) {
696bf215546Sopenharmony_ci      _mesa_ClearAccum(attr->Accum.ClearColor[0],
697bf215546Sopenharmony_ci                       attr->Accum.ClearColor[1],
698bf215546Sopenharmony_ci                       attr->Accum.ClearColor[2],
699bf215546Sopenharmony_ci                       attr->Accum.ClearColor[3]);
700bf215546Sopenharmony_ci   }
701bf215546Sopenharmony_ci
702bf215546Sopenharmony_ci   if (mask & GL_COLOR_BUFFER_BIT) {
703bf215546Sopenharmony_ci      TEST_AND_CALL1(Color.ClearIndex, ClearIndex);
704bf215546Sopenharmony_ci      _mesa_ClearColor(attr->Color.ClearColor.f[0],
705bf215546Sopenharmony_ci                       attr->Color.ClearColor.f[1],
706bf215546Sopenharmony_ci                       attr->Color.ClearColor.f[2],
707bf215546Sopenharmony_ci                       attr->Color.ClearColor.f[3]);
708bf215546Sopenharmony_ci      TEST_AND_CALL1(Color.IndexMask, IndexMask);
709bf215546Sopenharmony_ci      if (ctx->Color.ColorMask != attr->Color.ColorMask) {
710bf215546Sopenharmony_ci         if (!ctx->Extensions.EXT_draw_buffers2) {
711bf215546Sopenharmony_ci            _mesa_ColorMask(GET_COLORMASK_BIT(attr->Color.ColorMask, 0, 0),
712bf215546Sopenharmony_ci                            GET_COLORMASK_BIT(attr->Color.ColorMask, 0, 1),
713bf215546Sopenharmony_ci                            GET_COLORMASK_BIT(attr->Color.ColorMask, 0, 2),
714bf215546Sopenharmony_ci                            GET_COLORMASK_BIT(attr->Color.ColorMask, 0, 3));
715bf215546Sopenharmony_ci         } else {
716bf215546Sopenharmony_ci            for (unsigned i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
717bf215546Sopenharmony_ci               _mesa_ColorMaski(i,
718bf215546Sopenharmony_ci                                GET_COLORMASK_BIT(attr->Color.ColorMask, i, 0),
719bf215546Sopenharmony_ci                                GET_COLORMASK_BIT(attr->Color.ColorMask, i, 1),
720bf215546Sopenharmony_ci                                GET_COLORMASK_BIT(attr->Color.ColorMask, i, 2),
721bf215546Sopenharmony_ci                                GET_COLORMASK_BIT(attr->Color.ColorMask, i, 3));
722bf215546Sopenharmony_ci            }
723bf215546Sopenharmony_ci         }
724bf215546Sopenharmony_ci      }
725bf215546Sopenharmony_ci      if (memcmp(ctx->Color.DrawBuffer, attr->Color.DrawBuffer,
726bf215546Sopenharmony_ci                 sizeof(attr->Color.DrawBuffer))) {
727bf215546Sopenharmony_ci         /* Need to determine if more than one color output is
728bf215546Sopenharmony_ci          * specified.  If so, call glDrawBuffersARB, else call
729bf215546Sopenharmony_ci          * glDrawBuffer().  This is a subtle, but essential point
730bf215546Sopenharmony_ci          * since GL_FRONT (for example) is illegal for the former
731bf215546Sopenharmony_ci          * function, but legal for the later.
732bf215546Sopenharmony_ci          */
733bf215546Sopenharmony_ci         GLboolean multipleBuffers = GL_FALSE;
734bf215546Sopenharmony_ci         GLuint i;
735bf215546Sopenharmony_ci
736bf215546Sopenharmony_ci         for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) {
737bf215546Sopenharmony_ci            if (attr->Color.DrawBuffer[i] != GL_NONE) {
738bf215546Sopenharmony_ci               multipleBuffers = GL_TRUE;
739bf215546Sopenharmony_ci               break;
740bf215546Sopenharmony_ci            }
741bf215546Sopenharmony_ci         }
742bf215546Sopenharmony_ci         /* Call the API_level functions, not _mesa_drawbuffers()
743bf215546Sopenharmony_ci          * since we need to do error checking on the pop'd
744bf215546Sopenharmony_ci          * GL_DRAW_BUFFER.
745bf215546Sopenharmony_ci          * Ex: if GL_FRONT were pushed, but we're popping with a
746bf215546Sopenharmony_ci          * user FBO bound, GL_FRONT will be illegal and we'll need
747bf215546Sopenharmony_ci          * to record that error.  Per OpenGL ARB decision.
748bf215546Sopenharmony_ci          */
749bf215546Sopenharmony_ci         if (multipleBuffers) {
750bf215546Sopenharmony_ci            GLenum buffers[MAX_DRAW_BUFFERS];
751bf215546Sopenharmony_ci
752bf215546Sopenharmony_ci            for (unsigned i = 0; i < ctx->Const.MaxDrawBuffers; i++)
753bf215546Sopenharmony_ci               buffers[i] = attr->Color.DrawBuffer[i];
754bf215546Sopenharmony_ci
755bf215546Sopenharmony_ci            _mesa_DrawBuffers(ctx->Const.MaxDrawBuffers, buffers);
756bf215546Sopenharmony_ci         } else {
757bf215546Sopenharmony_ci            _mesa_DrawBuffer(attr->Color.DrawBuffer[0]);
758bf215546Sopenharmony_ci         }
759bf215546Sopenharmony_ci      }
760bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Color.AlphaEnabled, attr->Color.AlphaEnabled,
761bf215546Sopenharmony_ci                      GL_ALPHA_TEST);
762bf215546Sopenharmony_ci      TEST_AND_CALL2(Color.AlphaFunc, Color.AlphaRefUnclamped, AlphaFunc);
763bf215546Sopenharmony_ci      if (ctx->Color.BlendEnabled != attr->Color.BlendEnabled) {
764bf215546Sopenharmony_ci         if (ctx->Extensions.EXT_draw_buffers2) {
765bf215546Sopenharmony_ci            for (unsigned i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
766bf215546Sopenharmony_ci               TEST_AND_UPDATE_INDEX(ctx->Color.BlendEnabled,
767bf215546Sopenharmony_ci                                     attr->Color.BlendEnabled, i, GL_BLEND);
768bf215546Sopenharmony_ci            }
769bf215546Sopenharmony_ci         }
770bf215546Sopenharmony_ci         else {
771bf215546Sopenharmony_ci            TEST_AND_UPDATE(ctx->Color.BlendEnabled & 0x1,
772bf215546Sopenharmony_ci                            attr->Color.BlendEnabled & 0x1, GL_BLEND);
773bf215546Sopenharmony_ci         }
774bf215546Sopenharmony_ci      }
775bf215546Sopenharmony_ci      if (ctx->Color._BlendFuncPerBuffer ||
776bf215546Sopenharmony_ci          ctx->Color._BlendEquationPerBuffer) {
777bf215546Sopenharmony_ci         /* set blend per buffer */
778bf215546Sopenharmony_ci         GLuint buf;
779bf215546Sopenharmony_ci         for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) {
780bf215546Sopenharmony_ci            _mesa_BlendFuncSeparateiARB(buf, attr->Color.Blend[buf].SrcRGB,
781bf215546Sopenharmony_ci                                     attr->Color.Blend[buf].DstRGB,
782bf215546Sopenharmony_ci                                     attr->Color.Blend[buf].SrcA,
783bf215546Sopenharmony_ci                                     attr->Color.Blend[buf].DstA);
784bf215546Sopenharmony_ci            _mesa_BlendEquationSeparateiARB(buf,
785bf215546Sopenharmony_ci                                         attr->Color.Blend[buf].EquationRGB,
786bf215546Sopenharmony_ci                                         attr->Color.Blend[buf].EquationA);
787bf215546Sopenharmony_ci         }
788bf215546Sopenharmony_ci      }
789bf215546Sopenharmony_ci      else {
790bf215546Sopenharmony_ci         /* set same blend modes for all buffers */
791bf215546Sopenharmony_ci         _mesa_BlendFuncSeparate(attr->Color.Blend[0].SrcRGB,
792bf215546Sopenharmony_ci                                    attr->Color.Blend[0].DstRGB,
793bf215546Sopenharmony_ci                                    attr->Color.Blend[0].SrcA,
794bf215546Sopenharmony_ci                                    attr->Color.Blend[0].DstA);
795bf215546Sopenharmony_ci         /* This special case is because glBlendEquationSeparateEXT
796bf215546Sopenharmony_ci          * cannot take GL_LOGIC_OP as a parameter.
797bf215546Sopenharmony_ci          */
798bf215546Sopenharmony_ci         if (attr->Color.Blend[0].EquationRGB ==
799bf215546Sopenharmony_ci             attr->Color.Blend[0].EquationA) {
800bf215546Sopenharmony_ci            TEST_AND_CALL1(Color.Blend[0].EquationRGB, BlendEquation);
801bf215546Sopenharmony_ci         }
802bf215546Sopenharmony_ci         else {
803bf215546Sopenharmony_ci            TEST_AND_CALL2(Color.Blend[0].EquationRGB,
804bf215546Sopenharmony_ci                           Color.Blend[0].EquationA, BlendEquationSeparate);
805bf215546Sopenharmony_ci         }
806bf215546Sopenharmony_ci      }
807bf215546Sopenharmony_ci      _mesa_BlendColor(attr->Color.BlendColorUnclamped[0],
808bf215546Sopenharmony_ci                       attr->Color.BlendColorUnclamped[1],
809bf215546Sopenharmony_ci                       attr->Color.BlendColorUnclamped[2],
810bf215546Sopenharmony_ci                       attr->Color.BlendColorUnclamped[3]);
811bf215546Sopenharmony_ci      TEST_AND_CALL1(Color.LogicOp, LogicOp);
812bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled,
813bf215546Sopenharmony_ci                      attr->Color.ColorLogicOpEnabled, GL_COLOR_LOGIC_OP);
814bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled,
815bf215546Sopenharmony_ci                      attr->Color.IndexLogicOpEnabled, GL_INDEX_LOGIC_OP);
816bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Color.DitherFlag, attr->Color.DitherFlag,
817bf215546Sopenharmony_ci                      GL_DITHER);
818bf215546Sopenharmony_ci      if (ctx->Extensions.ARB_color_buffer_float) {
819bf215546Sopenharmony_ci         TEST_AND_CALL1_SEL(Color.ClampFragmentColor, ClampColor,
820bf215546Sopenharmony_ci                            GL_CLAMP_FRAGMENT_COLOR);
821bf215546Sopenharmony_ci      }
822bf215546Sopenharmony_ci      if (ctx->Extensions.ARB_color_buffer_float || ctx->Version >= 30) {
823bf215546Sopenharmony_ci         TEST_AND_CALL1_SEL(Color.ClampReadColor, ClampColor,
824bf215546Sopenharmony_ci                            GL_CLAMP_READ_COLOR);
825bf215546Sopenharmony_ci      }
826bf215546Sopenharmony_ci      /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
827bf215546Sopenharmony_ci      if (ctx->Extensions.EXT_framebuffer_sRGB) {
828bf215546Sopenharmony_ci         TEST_AND_UPDATE(ctx->Color.sRGBEnabled, attr->Color.sRGBEnabled,
829bf215546Sopenharmony_ci                         GL_FRAMEBUFFER_SRGB);
830bf215546Sopenharmony_ci      }
831bf215546Sopenharmony_ci   }
832bf215546Sopenharmony_ci
833bf215546Sopenharmony_ci   if (mask & GL_CURRENT_BIT) {
834bf215546Sopenharmony_ci      memcpy(&ctx->Current, &attr->Current,
835bf215546Sopenharmony_ci             sizeof(struct gl_current_attrib));
836bf215546Sopenharmony_ci      ctx->NewState |= _NEW_CURRENT_ATTRIB;
837bf215546Sopenharmony_ci   }
838bf215546Sopenharmony_ci
839bf215546Sopenharmony_ci   if (mask & GL_DEPTH_BUFFER_BIT) {
840bf215546Sopenharmony_ci      TEST_AND_CALL1(Depth.Func, DepthFunc);
841bf215546Sopenharmony_ci      TEST_AND_CALL1(Depth.Clear, ClearDepth);
842bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Depth.Test, attr->Depth.Test, GL_DEPTH_TEST);
843bf215546Sopenharmony_ci      TEST_AND_CALL1(Depth.Mask, DepthMask);
844bf215546Sopenharmony_ci      if (ctx->Extensions.EXT_depth_bounds_test) {
845bf215546Sopenharmony_ci         TEST_AND_UPDATE(ctx->Depth.BoundsTest, attr->Depth.BoundsTest,
846bf215546Sopenharmony_ci                         GL_DEPTH_BOUNDS_TEST_EXT);
847bf215546Sopenharmony_ci         TEST_AND_CALL2(Depth.BoundsMin, Depth.BoundsMax, DepthBoundsEXT);
848bf215546Sopenharmony_ci      }
849bf215546Sopenharmony_ci   }
850bf215546Sopenharmony_ci
851bf215546Sopenharmony_ci   if (mask & GL_ENABLE_BIT)
852bf215546Sopenharmony_ci      pop_enable_group(ctx, &attr->Enable);
853bf215546Sopenharmony_ci
854bf215546Sopenharmony_ci   if (mask & GL_EVAL_BIT) {
855bf215546Sopenharmony_ci      memcpy(&ctx->Eval, &attr->Eval, sizeof(struct gl_eval_attrib));
856bf215546Sopenharmony_ci      vbo_exec_update_eval_maps(ctx);
857bf215546Sopenharmony_ci   }
858bf215546Sopenharmony_ci
859bf215546Sopenharmony_ci   if (mask & GL_FOG_BIT) {
860bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Fog.Enabled, attr->Fog.Enabled, GL_FOG);
861bf215546Sopenharmony_ci      _mesa_Fogfv(GL_FOG_COLOR, attr->Fog.Color);
862bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Fog.Density, Fogf, GL_FOG_DENSITY);
863bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Fog.Start, Fogf, GL_FOG_START);
864bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Fog.End, Fogf, GL_FOG_END);
865bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Fog.Index, Fogf, GL_FOG_INDEX);
866bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Fog.Mode, Fogi, GL_FOG_MODE);
867bf215546Sopenharmony_ci   }
868bf215546Sopenharmony_ci
869bf215546Sopenharmony_ci   if (mask & GL_HINT_BIT) {
870bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Hint.PerspectiveCorrection, Hint, GL_PERSPECTIVE_CORRECTION_HINT);
871bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Hint.PointSmooth, Hint, GL_POINT_SMOOTH_HINT);
872bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Hint.LineSmooth, Hint, GL_LINE_SMOOTH_HINT);
873bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Hint.PolygonSmooth, Hint, GL_POLYGON_SMOOTH_HINT);
874bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Hint.Fog, Hint, GL_FOG_HINT);
875bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Hint.TextureCompression, Hint, GL_TEXTURE_COMPRESSION_HINT_ARB);
876bf215546Sopenharmony_ci   }
877bf215546Sopenharmony_ci
878bf215546Sopenharmony_ci   if (mask & GL_LIGHTING_BIT) {
879bf215546Sopenharmony_ci      GLuint i;
880bf215546Sopenharmony_ci      /* lighting enable */
881bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Light.Enabled, attr->Light.Enabled, GL_LIGHTING);
882bf215546Sopenharmony_ci      /* per-light state */
883bf215546Sopenharmony_ci      if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top))
884bf215546Sopenharmony_ci         _math_matrix_analyse(ctx->ModelviewMatrixStack.Top);
885bf215546Sopenharmony_ci
886bf215546Sopenharmony_ci      /* Fast path for other drivers. */
887bf215546Sopenharmony_ci      ctx->NewState |= _NEW_LIGHT_CONSTANTS | _NEW_FF_VERT_PROGRAM;
888bf215546Sopenharmony_ci
889bf215546Sopenharmony_ci      memcpy(ctx->Light.LightSource, attr->Light.LightSource,
890bf215546Sopenharmony_ci             sizeof(attr->Light.LightSource));
891bf215546Sopenharmony_ci      memcpy(&ctx->Light.Model, &attr->Light.Model,
892bf215546Sopenharmony_ci             sizeof(attr->Light.Model));
893bf215546Sopenharmony_ci
894bf215546Sopenharmony_ci      for (i = 0; i < ctx->Const.MaxLights; i++) {
895bf215546Sopenharmony_ci         TEST_AND_UPDATE(ctx->Light.Light[i].Enabled,
896bf215546Sopenharmony_ci                         attr->Light.Light[i].Enabled,
897bf215546Sopenharmony_ci                         GL_LIGHT0 + i);
898bf215546Sopenharmony_ci         memcpy(&ctx->Light.Light[i], &attr->Light.Light[i],
899bf215546Sopenharmony_ci                sizeof(struct gl_light));
900bf215546Sopenharmony_ci      }
901bf215546Sopenharmony_ci      /* shade model */
902bf215546Sopenharmony_ci      TEST_AND_CALL1(Light.ShadeModel, ShadeModel);
903bf215546Sopenharmony_ci      /* color material */
904bf215546Sopenharmony_ci      TEST_AND_CALL2(Light.ColorMaterialFace, Light.ColorMaterialMode,
905bf215546Sopenharmony_ci                     ColorMaterial);
906bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled,
907bf215546Sopenharmony_ci                      attr->Light.ColorMaterialEnabled, GL_COLOR_MATERIAL);
908bf215546Sopenharmony_ci      /* Shininess material is used by the fixed-func vertex program. */
909bf215546Sopenharmony_ci      ctx->NewState |= _NEW_MATERIAL | _NEW_FF_VERT_PROGRAM;
910bf215546Sopenharmony_ci      memcpy(&ctx->Light.Material, &attr->Light.Material,
911bf215546Sopenharmony_ci             sizeof(struct gl_material));
912bf215546Sopenharmony_ci      if (ctx->Extensions.ARB_color_buffer_float) {
913bf215546Sopenharmony_ci         TEST_AND_CALL1_SEL(Light.ClampVertexColor, ClampColor, GL_CLAMP_VERTEX_COLOR_ARB);
914bf215546Sopenharmony_ci      }
915bf215546Sopenharmony_ci   }
916bf215546Sopenharmony_ci
917bf215546Sopenharmony_ci   if (mask & GL_LINE_BIT) {
918bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Line.SmoothFlag, attr->Line.SmoothFlag, GL_LINE_SMOOTH);
919bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Line.StippleFlag, attr->Line.StippleFlag, GL_LINE_STIPPLE);
920bf215546Sopenharmony_ci      TEST_AND_CALL2(Line.StippleFactor, Line.StipplePattern, LineStipple);
921bf215546Sopenharmony_ci      TEST_AND_CALL1(Line.Width, LineWidth);
922bf215546Sopenharmony_ci   }
923bf215546Sopenharmony_ci
924bf215546Sopenharmony_ci   if (mask & GL_LIST_BIT)
925bf215546Sopenharmony_ci      memcpy(&ctx->List, &attr->List, sizeof(struct gl_list_attrib));
926bf215546Sopenharmony_ci
927bf215546Sopenharmony_ci   if (mask & GL_PIXEL_MODE_BIT) {
928bf215546Sopenharmony_ci      memcpy(&ctx->Pixel, &attr->Pixel, sizeof(struct gl_pixel_attrib));
929bf215546Sopenharmony_ci      /* XXX what other pixel state needs to be set by function calls? */
930bf215546Sopenharmony_ci      _mesa_ReadBuffer(ctx->Pixel.ReadBuffer);
931bf215546Sopenharmony_ci      ctx->NewState |= _NEW_PIXEL;
932bf215546Sopenharmony_ci   }
933bf215546Sopenharmony_ci
934bf215546Sopenharmony_ci   if (mask & GL_POINT_BIT) {
935bf215546Sopenharmony_ci      TEST_AND_CALL1(Point.Size, PointSize);
936bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Point.SmoothFlag, attr->Point.SmoothFlag, GL_POINT_SMOOTH);
937bf215546Sopenharmony_ci      _mesa_PointParameterfv(GL_DISTANCE_ATTENUATION_EXT, attr->Point.Params);
938bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Point.MinSize, PointParameterf, GL_POINT_SIZE_MIN_EXT);
939bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Point.MaxSize, PointParameterf, GL_POINT_SIZE_MAX_EXT);
940bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Point.Threshold, PointParameterf, GL_POINT_FADE_THRESHOLD_SIZE_EXT);
941bf215546Sopenharmony_ci
942bf215546Sopenharmony_ci      if (ctx->Extensions.ARB_point_sprite) {
943bf215546Sopenharmony_ci         if (ctx->Point.CoordReplace != attr->Point.CoordReplace) {
944bf215546Sopenharmony_ci            ctx->NewState |= _NEW_POINT | _NEW_FF_VERT_PROGRAM;
945bf215546Sopenharmony_ci            ctx->Point.CoordReplace = attr->Point.CoordReplace;
946bf215546Sopenharmony_ci         }
947bf215546Sopenharmony_ci         TEST_AND_UPDATE(ctx->Point.PointSprite, attr->Point.PointSprite,
948bf215546Sopenharmony_ci                         GL_POINT_SPRITE);
949bf215546Sopenharmony_ci
950bf215546Sopenharmony_ci         if ((ctx->API == API_OPENGL_COMPAT && ctx->Version >= 20)
951bf215546Sopenharmony_ci             || ctx->API == API_OPENGL_CORE)
952bf215546Sopenharmony_ci            TEST_AND_CALL1_SEL(Point.SpriteOrigin, PointParameterf, GL_POINT_SPRITE_COORD_ORIGIN);
953bf215546Sopenharmony_ci      }
954bf215546Sopenharmony_ci   }
955bf215546Sopenharmony_ci
956bf215546Sopenharmony_ci   if (mask & GL_POLYGON_BIT) {
957bf215546Sopenharmony_ci      TEST_AND_CALL1(Polygon.CullFaceMode, CullFace);
958bf215546Sopenharmony_ci      TEST_AND_CALL1(Polygon.FrontFace, FrontFace);
959bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Polygon.FrontMode, PolygonMode, GL_FRONT);
960bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Polygon.BackMode, PolygonMode, GL_BACK);
961bf215546Sopenharmony_ci      _mesa_polygon_offset_clamp(ctx,
962bf215546Sopenharmony_ci                                 attr->Polygon.OffsetFactor,
963bf215546Sopenharmony_ci                                 attr->Polygon.OffsetUnits,
964bf215546Sopenharmony_ci                                 attr->Polygon.OffsetClamp);
965bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, attr->Polygon.SmoothFlag, GL_POLYGON_SMOOTH);
966bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Polygon.StippleFlag, attr->Polygon.StippleFlag, GL_POLYGON_STIPPLE);
967bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Polygon.CullFlag, attr->Polygon.CullFlag, GL_CULL_FACE);
968bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, attr->Polygon.OffsetPoint,
969bf215546Sopenharmony_ci                      GL_POLYGON_OFFSET_POINT);
970bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Polygon.OffsetLine, attr->Polygon.OffsetLine,
971bf215546Sopenharmony_ci                      GL_POLYGON_OFFSET_LINE);
972bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Polygon.OffsetFill, attr->Polygon.OffsetFill,
973bf215546Sopenharmony_ci                      GL_POLYGON_OFFSET_FILL);
974bf215546Sopenharmony_ci   }
975bf215546Sopenharmony_ci
976bf215546Sopenharmony_ci   if (mask & GL_POLYGON_STIPPLE_BIT) {
977bf215546Sopenharmony_ci      memcpy(ctx->PolygonStipple, attr->PolygonStipple, 32*sizeof(GLuint));
978bf215546Sopenharmony_ci
979bf215546Sopenharmony_ci      ctx->NewDriverState |= ST_NEW_POLY_STIPPLE;
980bf215546Sopenharmony_ci   }
981bf215546Sopenharmony_ci
982bf215546Sopenharmony_ci   if (mask & GL_SCISSOR_BIT) {
983bf215546Sopenharmony_ci      unsigned i;
984bf215546Sopenharmony_ci
985bf215546Sopenharmony_ci      for (i = 0; i < ctx->Const.MaxViewports; i++) {
986bf215546Sopenharmony_ci         _mesa_set_scissor(ctx, i,
987bf215546Sopenharmony_ci                           attr->Scissor.ScissorArray[i].X,
988bf215546Sopenharmony_ci                           attr->Scissor.ScissorArray[i].Y,
989bf215546Sopenharmony_ci                           attr->Scissor.ScissorArray[i].Width,
990bf215546Sopenharmony_ci                           attr->Scissor.ScissorArray[i].Height);
991bf215546Sopenharmony_ci         TEST_AND_UPDATE_INDEX(ctx->Scissor.EnableFlags,
992bf215546Sopenharmony_ci                               attr->Scissor.EnableFlags, i, GL_SCISSOR_TEST);
993bf215546Sopenharmony_ci      }
994bf215546Sopenharmony_ci      if (ctx->Extensions.EXT_window_rectangles) {
995bf215546Sopenharmony_ci         STATIC_ASSERT(sizeof(struct gl_scissor_rect) ==
996bf215546Sopenharmony_ci                       4 * sizeof(GLint));
997bf215546Sopenharmony_ci         _mesa_WindowRectanglesEXT(
998bf215546Sopenharmony_ci               attr->Scissor.WindowRectMode, attr->Scissor.NumWindowRects,
999bf215546Sopenharmony_ci               (const GLint *)attr->Scissor.WindowRects);
1000bf215546Sopenharmony_ci      }
1001bf215546Sopenharmony_ci   }
1002bf215546Sopenharmony_ci
1003bf215546Sopenharmony_ci   if (mask & GL_STENCIL_BUFFER_BIT) {
1004bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Stencil.Enabled, attr->Stencil.Enabled,
1005bf215546Sopenharmony_ci                      GL_STENCIL_TEST);
1006bf215546Sopenharmony_ci      TEST_AND_CALL1(Stencil.Clear, ClearStencil);
1007bf215546Sopenharmony_ci      if (ctx->Extensions.EXT_stencil_two_side) {
1008bf215546Sopenharmony_ci         TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, attr->Stencil.TestTwoSide,
1009bf215546Sopenharmony_ci                         GL_STENCIL_TEST_TWO_SIDE_EXT);
1010bf215546Sopenharmony_ci         _mesa_ActiveStencilFaceEXT(attr->Stencil.ActiveFace
1011bf215546Sopenharmony_ci                                    ? GL_BACK : GL_FRONT);
1012bf215546Sopenharmony_ci      }
1013bf215546Sopenharmony_ci      /* front state */
1014bf215546Sopenharmony_ci      _mesa_StencilFuncSeparate(GL_FRONT,
1015bf215546Sopenharmony_ci                                attr->Stencil.Function[0],
1016bf215546Sopenharmony_ci                                attr->Stencil.Ref[0],
1017bf215546Sopenharmony_ci                                attr->Stencil.ValueMask[0]);
1018bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Stencil.WriteMask[0], StencilMaskSeparate, GL_FRONT);
1019bf215546Sopenharmony_ci      _mesa_StencilOpSeparate(GL_FRONT, attr->Stencil.FailFunc[0],
1020bf215546Sopenharmony_ci                              attr->Stencil.ZFailFunc[0],
1021bf215546Sopenharmony_ci                              attr->Stencil.ZPassFunc[0]);
1022bf215546Sopenharmony_ci      /* back state */
1023bf215546Sopenharmony_ci      _mesa_StencilFuncSeparate(GL_BACK,
1024bf215546Sopenharmony_ci                                attr->Stencil.Function[1],
1025bf215546Sopenharmony_ci                                attr->Stencil.Ref[1],
1026bf215546Sopenharmony_ci                                attr->Stencil.ValueMask[1]);
1027bf215546Sopenharmony_ci      TEST_AND_CALL1_SEL(Stencil.WriteMask[1], StencilMaskSeparate, GL_BACK);
1028bf215546Sopenharmony_ci      _mesa_StencilOpSeparate(GL_BACK, attr->Stencil.FailFunc[1],
1029bf215546Sopenharmony_ci                              attr->Stencil.ZFailFunc[1],
1030bf215546Sopenharmony_ci                              attr->Stencil.ZPassFunc[1]);
1031bf215546Sopenharmony_ci   }
1032bf215546Sopenharmony_ci
1033bf215546Sopenharmony_ci   if (mask & GL_TRANSFORM_BIT) {
1034bf215546Sopenharmony_ci      GLuint i;
1035bf215546Sopenharmony_ci      TEST_AND_CALL1(Transform.MatrixMode, MatrixMode);
1036bf215546Sopenharmony_ci      if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top))
1037bf215546Sopenharmony_ci         _math_matrix_analyse(ctx->ProjectionMatrixStack.Top);
1038bf215546Sopenharmony_ci
1039bf215546Sopenharmony_ci      ctx->NewState |= _NEW_TRANSFORM;
1040bf215546Sopenharmony_ci      ctx->NewDriverState |= ST_NEW_CLIP_STATE;
1041bf215546Sopenharmony_ci
1042bf215546Sopenharmony_ci      /* restore clip planes */
1043bf215546Sopenharmony_ci      for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
1044bf215546Sopenharmony_ci         const GLfloat *eyePlane = attr->Transform.EyeUserPlane[i];
1045bf215546Sopenharmony_ci         COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane);
1046bf215546Sopenharmony_ci         TEST_AND_UPDATE_BIT(ctx->Transform.ClipPlanesEnabled,
1047bf215546Sopenharmony_ci                             attr->Transform.ClipPlanesEnabled, i,
1048bf215546Sopenharmony_ci                             GL_CLIP_PLANE0 + i);
1049bf215546Sopenharmony_ci      }
1050bf215546Sopenharmony_ci
1051bf215546Sopenharmony_ci      /* normalize/rescale */
1052bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Transform.Normalize, attr->Transform.Normalize,
1053bf215546Sopenharmony_ci                      GL_NORMALIZE);
1054bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Transform.RescaleNormals,
1055bf215546Sopenharmony_ci                      attr->Transform.RescaleNormals, GL_RESCALE_NORMAL_EXT);
1056bf215546Sopenharmony_ci
1057bf215546Sopenharmony_ci      if (!ctx->Extensions.AMD_depth_clamp_separate) {
1058bf215546Sopenharmony_ci         TEST_AND_UPDATE(ctx->Transform.DepthClampNear &&
1059bf215546Sopenharmony_ci                         ctx->Transform.DepthClampFar,
1060bf215546Sopenharmony_ci                         attr->Transform.DepthClampNear &&
1061bf215546Sopenharmony_ci                         attr->Transform.DepthClampFar, GL_DEPTH_CLAMP);
1062bf215546Sopenharmony_ci      } else {
1063bf215546Sopenharmony_ci         TEST_AND_UPDATE(ctx->Transform.DepthClampNear,
1064bf215546Sopenharmony_ci                         attr->Transform.DepthClampNear,
1065bf215546Sopenharmony_ci                         GL_DEPTH_CLAMP_NEAR_AMD);
1066bf215546Sopenharmony_ci         TEST_AND_UPDATE(ctx->Transform.DepthClampFar,
1067bf215546Sopenharmony_ci                         attr->Transform.DepthClampFar,
1068bf215546Sopenharmony_ci                         GL_DEPTH_CLAMP_FAR_AMD);
1069bf215546Sopenharmony_ci      }
1070bf215546Sopenharmony_ci
1071bf215546Sopenharmony_ci      if (ctx->Extensions.ARB_clip_control) {
1072bf215546Sopenharmony_ci         TEST_AND_CALL2(Transform.ClipOrigin, Transform.ClipDepthMode,
1073bf215546Sopenharmony_ci                        ClipControl);
1074bf215546Sopenharmony_ci      }
1075bf215546Sopenharmony_ci   }
1076bf215546Sopenharmony_ci
1077bf215546Sopenharmony_ci   if (mask & GL_TEXTURE_BIT) {
1078bf215546Sopenharmony_ci      pop_texture_group(ctx, &attr->Texture);
1079bf215546Sopenharmony_ci      ctx->NewState |= _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE |
1080bf215546Sopenharmony_ci                       _NEW_FF_VERT_PROGRAM | _NEW_FF_FRAG_PROGRAM;
1081bf215546Sopenharmony_ci   }
1082bf215546Sopenharmony_ci
1083bf215546Sopenharmony_ci   if (mask & GL_VIEWPORT_BIT) {
1084bf215546Sopenharmony_ci      unsigned i;
1085bf215546Sopenharmony_ci
1086bf215546Sopenharmony_ci      for (i = 0; i < ctx->Const.MaxViewports; i++) {
1087bf215546Sopenharmony_ci         const struct gl_viewport_attrib *vp = &attr->Viewport.ViewportArray[i];
1088bf215546Sopenharmony_ci
1089bf215546Sopenharmony_ci         if (memcmp(&ctx->ViewportArray[i].X, &vp->X, sizeof(float) * 6)) {
1090bf215546Sopenharmony_ci            ctx->NewState |= _NEW_VIEWPORT;
1091bf215546Sopenharmony_ci            ctx->NewDriverState |= ST_NEW_VIEWPORT;
1092bf215546Sopenharmony_ci
1093bf215546Sopenharmony_ci            memcpy(&ctx->ViewportArray[i].X, &vp->X, sizeof(float) * 6);
1094bf215546Sopenharmony_ci
1095bf215546Sopenharmony_ci            if (ctx->invalidate_on_gl_viewport)
1096bf215546Sopenharmony_ci               st_manager_invalidate_drawables(ctx);
1097bf215546Sopenharmony_ci         }
1098bf215546Sopenharmony_ci      }
1099bf215546Sopenharmony_ci
1100bf215546Sopenharmony_ci      if (ctx->Extensions.NV_conservative_raster) {
1101bf215546Sopenharmony_ci         GLuint biasx = attr->Viewport.SubpixelPrecisionBias[0];
1102bf215546Sopenharmony_ci         GLuint biasy = attr->Viewport.SubpixelPrecisionBias[1];
1103bf215546Sopenharmony_ci         _mesa_SubpixelPrecisionBiasNV(biasx, biasy);
1104bf215546Sopenharmony_ci      }
1105bf215546Sopenharmony_ci   }
1106bf215546Sopenharmony_ci
1107bf215546Sopenharmony_ci   if (mask & GL_MULTISAMPLE_BIT_ARB) {
1108bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Multisample.Enabled,
1109bf215546Sopenharmony_ci                      attr->Multisample.Enabled,
1110bf215546Sopenharmony_ci                      GL_MULTISAMPLE);
1111bf215546Sopenharmony_ci
1112bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Multisample.SampleCoverage,
1113bf215546Sopenharmony_ci                      attr->Multisample.SampleCoverage,
1114bf215546Sopenharmony_ci                      GL_SAMPLE_COVERAGE);
1115bf215546Sopenharmony_ci
1116bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage,
1117bf215546Sopenharmony_ci                      attr->Multisample.SampleAlphaToCoverage,
1118bf215546Sopenharmony_ci                      GL_SAMPLE_ALPHA_TO_COVERAGE);
1119bf215546Sopenharmony_ci
1120bf215546Sopenharmony_ci      TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne,
1121bf215546Sopenharmony_ci                      attr->Multisample.SampleAlphaToOne,
1122bf215546Sopenharmony_ci                      GL_SAMPLE_ALPHA_TO_ONE);
1123bf215546Sopenharmony_ci
1124bf215546Sopenharmony_ci      TEST_AND_CALL2(Multisample.SampleCoverageValue,
1125bf215546Sopenharmony_ci                     Multisample.SampleCoverageInvert, SampleCoverage);
1126bf215546Sopenharmony_ci
1127bf215546Sopenharmony_ci      TEST_AND_CALL1(Multisample.SampleAlphaToCoverageDitherControl,
1128bf215546Sopenharmony_ci                     AlphaToCoverageDitherControlNV);
1129bf215546Sopenharmony_ci   }
1130bf215546Sopenharmony_ci
1131bf215546Sopenharmony_ci   ctx->PopAttribState = attr->OldPopAttribStateMask;
1132bf215546Sopenharmony_ci}
1133bf215546Sopenharmony_ci
1134bf215546Sopenharmony_ci
1135bf215546Sopenharmony_ci/**
1136bf215546Sopenharmony_ci * Copy gl_pixelstore_attrib from src to dst, updating buffer
1137bf215546Sopenharmony_ci * object refcounts.
1138bf215546Sopenharmony_ci */
1139bf215546Sopenharmony_cistatic void
1140bf215546Sopenharmony_cicopy_pixelstore(struct gl_context *ctx,
1141bf215546Sopenharmony_ci                struct gl_pixelstore_attrib *dst,
1142bf215546Sopenharmony_ci                const struct gl_pixelstore_attrib *src)
1143bf215546Sopenharmony_ci{
1144bf215546Sopenharmony_ci   dst->Alignment = src->Alignment;
1145bf215546Sopenharmony_ci   dst->RowLength = src->RowLength;
1146bf215546Sopenharmony_ci   dst->SkipPixels = src->SkipPixels;
1147bf215546Sopenharmony_ci   dst->SkipRows = src->SkipRows;
1148bf215546Sopenharmony_ci   dst->ImageHeight = src->ImageHeight;
1149bf215546Sopenharmony_ci   dst->SkipImages = src->SkipImages;
1150bf215546Sopenharmony_ci   dst->SwapBytes = src->SwapBytes;
1151bf215546Sopenharmony_ci   dst->LsbFirst = src->LsbFirst;
1152bf215546Sopenharmony_ci   dst->Invert = src->Invert;
1153bf215546Sopenharmony_ci   _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
1154bf215546Sopenharmony_ci}
1155bf215546Sopenharmony_ci
1156bf215546Sopenharmony_ci
1157bf215546Sopenharmony_ci#define GL_CLIENT_PACK_BIT (1<<20)
1158bf215546Sopenharmony_ci#define GL_CLIENT_UNPACK_BIT (1<<21)
1159bf215546Sopenharmony_ci
1160bf215546Sopenharmony_cistatic void
1161bf215546Sopenharmony_cicopy_vertex_attrib_array(struct gl_context *ctx,
1162bf215546Sopenharmony_ci                         struct gl_array_attributes *dst,
1163bf215546Sopenharmony_ci                         const struct gl_array_attributes *src)
1164bf215546Sopenharmony_ci{
1165bf215546Sopenharmony_ci   dst->Ptr            = src->Ptr;
1166bf215546Sopenharmony_ci   dst->RelativeOffset = src->RelativeOffset;
1167bf215546Sopenharmony_ci   dst->Format         = src->Format;
1168bf215546Sopenharmony_ci   dst->Stride         = src->Stride;
1169bf215546Sopenharmony_ci   dst->BufferBindingIndex = src->BufferBindingIndex;
1170bf215546Sopenharmony_ci   dst->_EffBufferBindingIndex = src->_EffBufferBindingIndex;
1171bf215546Sopenharmony_ci   dst->_EffRelativeOffset = src->_EffRelativeOffset;
1172bf215546Sopenharmony_ci}
1173bf215546Sopenharmony_ci
1174bf215546Sopenharmony_cistatic void
1175bf215546Sopenharmony_cicopy_vertex_buffer_binding(struct gl_context *ctx,
1176bf215546Sopenharmony_ci                           struct gl_vertex_buffer_binding *dst,
1177bf215546Sopenharmony_ci                           const struct gl_vertex_buffer_binding *src)
1178bf215546Sopenharmony_ci{
1179bf215546Sopenharmony_ci   dst->Offset          = src->Offset;
1180bf215546Sopenharmony_ci   dst->Stride          = src->Stride;
1181bf215546Sopenharmony_ci   dst->InstanceDivisor = src->InstanceDivisor;
1182bf215546Sopenharmony_ci   dst->_BoundArrays    = src->_BoundArrays;
1183bf215546Sopenharmony_ci   dst->_EffBoundArrays = src->_EffBoundArrays;
1184bf215546Sopenharmony_ci   dst->_EffOffset      = src->_EffOffset;
1185bf215546Sopenharmony_ci
1186bf215546Sopenharmony_ci   _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
1187bf215546Sopenharmony_ci}
1188bf215546Sopenharmony_ci
1189bf215546Sopenharmony_ci/**
1190bf215546Sopenharmony_ci * Copy gl_vertex_array_object from src to dest.
1191bf215546Sopenharmony_ci * 'dest' must be in an initialized state.
1192bf215546Sopenharmony_ci */
1193bf215546Sopenharmony_cistatic void
1194bf215546Sopenharmony_cicopy_array_object(struct gl_context *ctx,
1195bf215546Sopenharmony_ci                  struct gl_vertex_array_object *dest,
1196bf215546Sopenharmony_ci                  struct gl_vertex_array_object *src,
1197bf215546Sopenharmony_ci                  unsigned copy_attrib_mask)
1198bf215546Sopenharmony_ci{
1199bf215546Sopenharmony_ci   /* skip Name */
1200bf215546Sopenharmony_ci   /* skip RefCount */
1201bf215546Sopenharmony_ci
1202bf215546Sopenharmony_ci   while (copy_attrib_mask) {
1203bf215546Sopenharmony_ci      unsigned i = u_bit_scan(&copy_attrib_mask);
1204bf215546Sopenharmony_ci
1205bf215546Sopenharmony_ci      copy_vertex_attrib_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]);
1206bf215546Sopenharmony_ci      copy_vertex_buffer_binding(ctx, &dest->BufferBinding[i], &src->BufferBinding[i]);
1207bf215546Sopenharmony_ci   }
1208bf215546Sopenharmony_ci
1209bf215546Sopenharmony_ci   /* Enabled must be the same than on push */
1210bf215546Sopenharmony_ci   dest->Enabled = src->Enabled;
1211bf215546Sopenharmony_ci   dest->_EnabledWithMapMode = src->_EnabledWithMapMode;
1212bf215546Sopenharmony_ci   dest->_EffEnabledVBO = src->_EffEnabledVBO;
1213bf215546Sopenharmony_ci   dest->_EffEnabledNonZeroDivisor = src->_EffEnabledNonZeroDivisor;
1214bf215546Sopenharmony_ci   /* The bitmask of bound VBOs needs to match the VertexBinding array */
1215bf215546Sopenharmony_ci   dest->VertexAttribBufferMask = src->VertexAttribBufferMask;
1216bf215546Sopenharmony_ci   dest->NonZeroDivisorMask = src->NonZeroDivisorMask;
1217bf215546Sopenharmony_ci   dest->_AttributeMapMode = src->_AttributeMapMode;
1218bf215546Sopenharmony_ci   dest->NewVertexBuffers = src->NewVertexBuffers;
1219bf215546Sopenharmony_ci   dest->NewVertexElements = src->NewVertexElements;
1220bf215546Sopenharmony_ci   /* skip NumUpdates and IsDynamic because they can only increase, not decrease */
1221bf215546Sopenharmony_ci}
1222bf215546Sopenharmony_ci
1223bf215546Sopenharmony_ci/**
1224bf215546Sopenharmony_ci * Copy gl_array_attrib from src to dest.
1225bf215546Sopenharmony_ci * 'dest' must be in an initialized state.
1226bf215546Sopenharmony_ci */
1227bf215546Sopenharmony_cistatic void
1228bf215546Sopenharmony_cicopy_array_attrib(struct gl_context *ctx,
1229bf215546Sopenharmony_ci                  struct gl_array_attrib *dest,
1230bf215546Sopenharmony_ci                  struct gl_array_attrib *src,
1231bf215546Sopenharmony_ci                  bool vbo_deleted,
1232bf215546Sopenharmony_ci                  unsigned copy_attrib_mask)
1233bf215546Sopenharmony_ci{
1234bf215546Sopenharmony_ci   /* skip ArrayObj */
1235bf215546Sopenharmony_ci   /* skip DefaultArrayObj, Objects */
1236bf215546Sopenharmony_ci   dest->ActiveTexture = src->ActiveTexture;
1237bf215546Sopenharmony_ci   dest->LockFirst = src->LockFirst;
1238bf215546Sopenharmony_ci   dest->LockCount = src->LockCount;
1239bf215546Sopenharmony_ci   dest->PrimitiveRestart = src->PrimitiveRestart;
1240bf215546Sopenharmony_ci   dest->PrimitiveRestartFixedIndex = src->PrimitiveRestartFixedIndex;
1241bf215546Sopenharmony_ci   dest->RestartIndex = src->RestartIndex;
1242bf215546Sopenharmony_ci   memcpy(dest->_PrimitiveRestart, src->_PrimitiveRestart,
1243bf215546Sopenharmony_ci          sizeof(src->_PrimitiveRestart));
1244bf215546Sopenharmony_ci   memcpy(dest->_RestartIndex, src->_RestartIndex, sizeof(src->_RestartIndex));
1245bf215546Sopenharmony_ci   /* skip NewState */
1246bf215546Sopenharmony_ci   /* skip RebindArrays */
1247bf215546Sopenharmony_ci
1248bf215546Sopenharmony_ci   if (!vbo_deleted)
1249bf215546Sopenharmony_ci      copy_array_object(ctx, dest->VAO, src->VAO, copy_attrib_mask);
1250bf215546Sopenharmony_ci
1251bf215546Sopenharmony_ci   /* skip ArrayBufferObj */
1252bf215546Sopenharmony_ci   /* skip IndexBufferObj */
1253bf215546Sopenharmony_ci}
1254bf215546Sopenharmony_ci
1255bf215546Sopenharmony_ci/**
1256bf215546Sopenharmony_ci * Save the content of src to dest.
1257bf215546Sopenharmony_ci */
1258bf215546Sopenharmony_cistatic void
1259bf215546Sopenharmony_cisave_array_attrib(struct gl_context *ctx,
1260bf215546Sopenharmony_ci                  struct gl_array_attrib *dest,
1261bf215546Sopenharmony_ci                  struct gl_array_attrib *src)
1262bf215546Sopenharmony_ci{
1263bf215546Sopenharmony_ci   /* Set the Name, needed for restore, but do never overwrite.
1264bf215546Sopenharmony_ci    * Needs to match value in the object hash. */
1265bf215546Sopenharmony_ci   dest->VAO->Name = src->VAO->Name;
1266bf215546Sopenharmony_ci   dest->VAO->NonDefaultStateMask = src->VAO->NonDefaultStateMask;
1267bf215546Sopenharmony_ci   /* And copy all of the rest. */
1268bf215546Sopenharmony_ci   copy_array_attrib(ctx, dest, src, false, src->VAO->NonDefaultStateMask);
1269bf215546Sopenharmony_ci
1270bf215546Sopenharmony_ci   /* Just reference them here */
1271bf215546Sopenharmony_ci   _mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj,
1272bf215546Sopenharmony_ci                                 src->ArrayBufferObj);
1273bf215546Sopenharmony_ci   _mesa_reference_buffer_object(ctx, &dest->VAO->IndexBufferObj,
1274bf215546Sopenharmony_ci                                 src->VAO->IndexBufferObj);
1275bf215546Sopenharmony_ci}
1276bf215546Sopenharmony_ci
1277bf215546Sopenharmony_ci/**
1278bf215546Sopenharmony_ci * Restore the content of src to dest.
1279bf215546Sopenharmony_ci */
1280bf215546Sopenharmony_cistatic void
1281bf215546Sopenharmony_cirestore_array_attrib(struct gl_context *ctx,
1282bf215546Sopenharmony_ci                     struct gl_array_attrib *dest,
1283bf215546Sopenharmony_ci                     struct gl_array_attrib *src)
1284bf215546Sopenharmony_ci{
1285bf215546Sopenharmony_ci   bool is_vao_name_zero = src->VAO->Name == 0;
1286bf215546Sopenharmony_ci
1287bf215546Sopenharmony_ci   /* The ARB_vertex_array_object spec says:
1288bf215546Sopenharmony_ci    *
1289bf215546Sopenharmony_ci    *     "BindVertexArray fails and an INVALID_OPERATION error is generated
1290bf215546Sopenharmony_ci    *     if array is not a name returned from a previous call to
1291bf215546Sopenharmony_ci    *     GenVertexArrays, or if such a name has since been deleted with
1292bf215546Sopenharmony_ci    *     DeleteVertexArrays."
1293bf215546Sopenharmony_ci    *
1294bf215546Sopenharmony_ci    * Therefore popping a deleted VAO cannot magically recreate it.
1295bf215546Sopenharmony_ci    */
1296bf215546Sopenharmony_ci   if (!is_vao_name_zero && !_mesa_IsVertexArray(src->VAO->Name))
1297bf215546Sopenharmony_ci      return;
1298bf215546Sopenharmony_ci
1299bf215546Sopenharmony_ci   _mesa_BindVertexArray(src->VAO->Name);
1300bf215546Sopenharmony_ci
1301bf215546Sopenharmony_ci   /* Restore or recreate the buffer objects by the names ... */
1302bf215546Sopenharmony_ci   if (is_vao_name_zero || !src->ArrayBufferObj ||
1303bf215546Sopenharmony_ci       _mesa_IsBuffer(src->ArrayBufferObj->Name)) {
1304bf215546Sopenharmony_ci      /* ... and restore its content */
1305bf215546Sopenharmony_ci      dest->VAO->NonDefaultStateMask |= src->VAO->NonDefaultStateMask;
1306bf215546Sopenharmony_ci      copy_array_attrib(ctx, dest, src, false,
1307bf215546Sopenharmony_ci                        dest->VAO->NonDefaultStateMask);
1308bf215546Sopenharmony_ci
1309bf215546Sopenharmony_ci      _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB,
1310bf215546Sopenharmony_ci                       src->ArrayBufferObj ?
1311bf215546Sopenharmony_ci                          src->ArrayBufferObj->Name : 0);
1312bf215546Sopenharmony_ci   } else {
1313bf215546Sopenharmony_ci      copy_array_attrib(ctx, dest, src, true, 0);
1314bf215546Sopenharmony_ci   }
1315bf215546Sopenharmony_ci
1316bf215546Sopenharmony_ci   /* Invalidate array state. It will be updated during the next draw. */
1317bf215546Sopenharmony_ci   _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO, 0);
1318bf215546Sopenharmony_ci
1319bf215546Sopenharmony_ci   if (is_vao_name_zero || !src->VAO->IndexBufferObj ||
1320bf215546Sopenharmony_ci       _mesa_IsBuffer(src->VAO->IndexBufferObj->Name)) {
1321bf215546Sopenharmony_ci      _mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,
1322bf215546Sopenharmony_ci                       src->VAO->IndexBufferObj ?
1323bf215546Sopenharmony_ci                          src->VAO->IndexBufferObj->Name : 0);
1324bf215546Sopenharmony_ci   }
1325bf215546Sopenharmony_ci}
1326bf215546Sopenharmony_ci
1327bf215546Sopenharmony_ci
1328bf215546Sopenharmony_civoid GLAPIENTRY
1329bf215546Sopenharmony_ci_mesa_PushClientAttrib(GLbitfield mask)
1330bf215546Sopenharmony_ci{
1331bf215546Sopenharmony_ci   struct gl_client_attrib_node *head;
1332bf215546Sopenharmony_ci
1333bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
1334bf215546Sopenharmony_ci
1335bf215546Sopenharmony_ci   if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) {
1336bf215546Sopenharmony_ci      _mesa_error(ctx, GL_STACK_OVERFLOW, "glPushClientAttrib");
1337bf215546Sopenharmony_ci      return;
1338bf215546Sopenharmony_ci   }
1339bf215546Sopenharmony_ci
1340bf215546Sopenharmony_ci   head = &ctx->ClientAttribStack[ctx->ClientAttribStackDepth];
1341bf215546Sopenharmony_ci   head->Mask = mask;
1342bf215546Sopenharmony_ci
1343bf215546Sopenharmony_ci   if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
1344bf215546Sopenharmony_ci      copy_pixelstore(ctx, &head->Pack, &ctx->Pack);
1345bf215546Sopenharmony_ci      copy_pixelstore(ctx, &head->Unpack, &ctx->Unpack);
1346bf215546Sopenharmony_ci   }
1347bf215546Sopenharmony_ci
1348bf215546Sopenharmony_ci   if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
1349bf215546Sopenharmony_ci      _mesa_initialize_vao(ctx, &head->VAO, 0);
1350bf215546Sopenharmony_ci      /* Use the VAO declared within the node instead of allocating it. */
1351bf215546Sopenharmony_ci      head->Array.VAO = &head->VAO;
1352bf215546Sopenharmony_ci      save_array_attrib(ctx, &head->Array, &ctx->Array);
1353bf215546Sopenharmony_ci   }
1354bf215546Sopenharmony_ci
1355bf215546Sopenharmony_ci   ctx->ClientAttribStackDepth++;
1356bf215546Sopenharmony_ci}
1357bf215546Sopenharmony_ci
1358bf215546Sopenharmony_ci
1359bf215546Sopenharmony_civoid GLAPIENTRY
1360bf215546Sopenharmony_ci_mesa_PopClientAttrib(void)
1361bf215546Sopenharmony_ci{
1362bf215546Sopenharmony_ci   struct gl_client_attrib_node *head;
1363bf215546Sopenharmony_ci
1364bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
1365bf215546Sopenharmony_ci
1366bf215546Sopenharmony_ci   if (ctx->ClientAttribStackDepth == 0) {
1367bf215546Sopenharmony_ci      _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib");
1368bf215546Sopenharmony_ci      return;
1369bf215546Sopenharmony_ci   }
1370bf215546Sopenharmony_ci
1371bf215546Sopenharmony_ci   ctx->ClientAttribStackDepth--;
1372bf215546Sopenharmony_ci   head = &ctx->ClientAttribStack[ctx->ClientAttribStackDepth];
1373bf215546Sopenharmony_ci
1374bf215546Sopenharmony_ci   if (head->Mask & GL_CLIENT_PIXEL_STORE_BIT) {
1375bf215546Sopenharmony_ci      copy_pixelstore(ctx, &ctx->Pack, &head->Pack);
1376bf215546Sopenharmony_ci      _mesa_reference_buffer_object(ctx, &head->Pack.BufferObj, NULL);
1377bf215546Sopenharmony_ci
1378bf215546Sopenharmony_ci      copy_pixelstore(ctx, &ctx->Unpack, &head->Unpack);
1379bf215546Sopenharmony_ci      _mesa_reference_buffer_object(ctx, &head->Unpack.BufferObj, NULL);
1380bf215546Sopenharmony_ci   }
1381bf215546Sopenharmony_ci
1382bf215546Sopenharmony_ci   if (head->Mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
1383bf215546Sopenharmony_ci      restore_array_attrib(ctx, &ctx->Array, &head->Array);
1384bf215546Sopenharmony_ci
1385bf215546Sopenharmony_ci      /* _mesa_unbind_array_object_vbos can't use NonDefaultStateMask because
1386bf215546Sopenharmony_ci       * it's used by internal VAOs which don't always update the mask, so do
1387bf215546Sopenharmony_ci       * it manually here.
1388bf215546Sopenharmony_ci       */
1389bf215546Sopenharmony_ci      GLbitfield mask = head->VAO.NonDefaultStateMask;
1390bf215546Sopenharmony_ci      while (mask) {
1391bf215546Sopenharmony_ci         unsigned i = u_bit_scan(&mask);
1392bf215546Sopenharmony_ci         _mesa_reference_buffer_object(ctx, &head->VAO.BufferBinding[i].BufferObj, NULL);
1393bf215546Sopenharmony_ci      }
1394bf215546Sopenharmony_ci
1395bf215546Sopenharmony_ci      _mesa_reference_buffer_object(ctx, &head->VAO.IndexBufferObj, NULL);
1396bf215546Sopenharmony_ci      _mesa_reference_buffer_object(ctx, &head->Array.ArrayBufferObj, NULL);
1397bf215546Sopenharmony_ci   }
1398bf215546Sopenharmony_ci}
1399bf215546Sopenharmony_ci
1400bf215546Sopenharmony_civoid GLAPIENTRY
1401bf215546Sopenharmony_ci_mesa_ClientAttribDefaultEXT( GLbitfield mask )
1402bf215546Sopenharmony_ci{
1403bf215546Sopenharmony_ci   if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
1404bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
1405bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
1406bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
1407bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
1408bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1409bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1410bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1411bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_UNPACK_ALIGNMENT, 4);
1412bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
1413bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_PACK_LSB_FIRST, GL_FALSE);
1414bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
1415bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_PACK_SKIP_IMAGES, 0);
1416bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_PACK_ROW_LENGTH, 0);
1417bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_PACK_SKIP_ROWS, 0);
1418bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_PACK_SKIP_PIXELS, 0);
1419bf215546Sopenharmony_ci      _mesa_PixelStorei(GL_PACK_ALIGNMENT, 4);
1420bf215546Sopenharmony_ci
1421bf215546Sopenharmony_ci      _mesa_BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
1422bf215546Sopenharmony_ci      _mesa_BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
1423bf215546Sopenharmony_ci   }
1424bf215546Sopenharmony_ci   if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
1425bf215546Sopenharmony_ci      GET_CURRENT_CONTEXT(ctx);
1426bf215546Sopenharmony_ci      int i;
1427bf215546Sopenharmony_ci
1428bf215546Sopenharmony_ci      _mesa_BindBuffer(GL_ARRAY_BUFFER, 0);
1429bf215546Sopenharmony_ci      _mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1430bf215546Sopenharmony_ci
1431bf215546Sopenharmony_ci      _mesa_DisableClientState(GL_EDGE_FLAG_ARRAY);
1432bf215546Sopenharmony_ci      _mesa_EdgeFlagPointer(0, 0);
1433bf215546Sopenharmony_ci
1434bf215546Sopenharmony_ci      _mesa_DisableClientState(GL_INDEX_ARRAY);
1435bf215546Sopenharmony_ci      _mesa_IndexPointer(GL_FLOAT, 0, 0);
1436bf215546Sopenharmony_ci
1437bf215546Sopenharmony_ci      _mesa_DisableClientState(GL_SECONDARY_COLOR_ARRAY);
1438bf215546Sopenharmony_ci      _mesa_SecondaryColorPointer(4, GL_FLOAT, 0, 0);
1439bf215546Sopenharmony_ci
1440bf215546Sopenharmony_ci      _mesa_DisableClientState(GL_FOG_COORD_ARRAY);
1441bf215546Sopenharmony_ci      _mesa_FogCoordPointer(GL_FLOAT, 0, 0);
1442bf215546Sopenharmony_ci
1443bf215546Sopenharmony_ci      for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
1444bf215546Sopenharmony_ci         _mesa_ClientActiveTexture(GL_TEXTURE0 + i);
1445bf215546Sopenharmony_ci         _mesa_DisableClientState(GL_TEXTURE_COORD_ARRAY);
1446bf215546Sopenharmony_ci         _mesa_TexCoordPointer(4, GL_FLOAT, 0, 0);
1447bf215546Sopenharmony_ci      }
1448bf215546Sopenharmony_ci
1449bf215546Sopenharmony_ci      _mesa_DisableClientState(GL_COLOR_ARRAY);
1450bf215546Sopenharmony_ci      _mesa_ColorPointer(4, GL_FLOAT, 0, 0);
1451bf215546Sopenharmony_ci
1452bf215546Sopenharmony_ci      _mesa_DisableClientState(GL_NORMAL_ARRAY);
1453bf215546Sopenharmony_ci      _mesa_NormalPointer(GL_FLOAT, 0, 0);
1454bf215546Sopenharmony_ci
1455bf215546Sopenharmony_ci      _mesa_DisableClientState(GL_VERTEX_ARRAY);
1456bf215546Sopenharmony_ci      _mesa_VertexPointer(4, GL_FLOAT, 0, 0);
1457bf215546Sopenharmony_ci
1458bf215546Sopenharmony_ci      for (i = 0; i < ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs; i++) {
1459bf215546Sopenharmony_ci         _mesa_DisableVertexAttribArray(i);
1460bf215546Sopenharmony_ci         _mesa_VertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0);
1461bf215546Sopenharmony_ci      }
1462bf215546Sopenharmony_ci
1463bf215546Sopenharmony_ci      _mesa_ClientActiveTexture(GL_TEXTURE0);
1464bf215546Sopenharmony_ci
1465bf215546Sopenharmony_ci      _mesa_PrimitiveRestartIndex_no_error(0);
1466bf215546Sopenharmony_ci      if (ctx->Version >= 31)
1467bf215546Sopenharmony_ci         _mesa_Disable(GL_PRIMITIVE_RESTART);
1468bf215546Sopenharmony_ci      else if (_mesa_has_NV_primitive_restart(ctx))
1469bf215546Sopenharmony_ci         _mesa_DisableClientState(GL_PRIMITIVE_RESTART_NV);
1470bf215546Sopenharmony_ci
1471bf215546Sopenharmony_ci      if (_mesa_has_ARB_ES3_compatibility(ctx))
1472bf215546Sopenharmony_ci         _mesa_Disable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
1473bf215546Sopenharmony_ci   }
1474bf215546Sopenharmony_ci}
1475bf215546Sopenharmony_ci
1476bf215546Sopenharmony_civoid GLAPIENTRY
1477bf215546Sopenharmony_ci_mesa_PushClientAttribDefaultEXT( GLbitfield mask )
1478bf215546Sopenharmony_ci{
1479bf215546Sopenharmony_ci   _mesa_PushClientAttrib(mask);
1480bf215546Sopenharmony_ci   _mesa_ClientAttribDefaultEXT(mask);
1481bf215546Sopenharmony_ci}
1482bf215546Sopenharmony_ci
1483bf215546Sopenharmony_ci
1484bf215546Sopenharmony_ci/**
1485bf215546Sopenharmony_ci * Free any attribute state data that might be attached to the context.
1486bf215546Sopenharmony_ci */
1487bf215546Sopenharmony_civoid
1488bf215546Sopenharmony_ci_mesa_free_attrib_data(struct gl_context *ctx)
1489bf215546Sopenharmony_ci{
1490bf215546Sopenharmony_ci   for (unsigned i = 0; i < ARRAY_SIZE(ctx->AttribStack); i++)
1491bf215546Sopenharmony_ci      FREE(ctx->AttribStack[i]);
1492bf215546Sopenharmony_ci}
1493bf215546Sopenharmony_ci
1494bf215546Sopenharmony_ci
1495bf215546Sopenharmony_civoid
1496bf215546Sopenharmony_ci_mesa_init_attrib(struct gl_context *ctx)
1497bf215546Sopenharmony_ci{
1498bf215546Sopenharmony_ci   /* Renderer and client attribute stacks */
1499bf215546Sopenharmony_ci   ctx->AttribStackDepth = 0;
1500bf215546Sopenharmony_ci   ctx->ClientAttribStackDepth = 0;
1501bf215546Sopenharmony_ci}
1502