attrib.c revision b8e80941
1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5 * Copyright (C) 2009  VMware, Inc.   All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#include "glheader.h"
27#include "imports.h"
28#include "accum.h"
29#include "arrayobj.h"
30#include "attrib.h"
31#include "blend.h"
32#include "buffers.h"
33#include "bufferobj.h"
34#include "clear.h"
35#include "context.h"
36#include "depth.h"
37#include "enable.h"
38#include "enums.h"
39#include "fog.h"
40#include "hint.h"
41#include "light.h"
42#include "lines.h"
43#include "macros.h"
44#include "matrix.h"
45#include "multisample.h"
46#include "points.h"
47#include "polygon.h"
48#include "shared.h"
49#include "scissor.h"
50#include "stencil.h"
51#include "texenv.h"
52#include "texgen.h"
53#include "texobj.h"
54#include "texparam.h"
55#include "texstate.h"
56#include "varray.h"
57#include "viewport.h"
58#include "mtypes.h"
59#include "state.h"
60#include "hash.h"
61#include <stdbool.h>
62
63
64/**
65 * glEnable()/glDisable() attribute group (GL_ENABLE_BIT).
66 */
67struct gl_enable_attrib
68{
69   GLboolean AlphaTest;
70   GLboolean AutoNormal;
71   GLboolean Blend;
72   GLbitfield ClipPlanes;
73   GLboolean ColorMaterial;
74   GLboolean CullFace;
75   GLboolean DepthClampNear;
76   GLboolean DepthClampFar;
77   GLboolean DepthTest;
78   GLboolean Dither;
79   GLboolean Fog;
80   GLboolean Light[MAX_LIGHTS];
81   GLboolean Lighting;
82   GLboolean LineSmooth;
83   GLboolean LineStipple;
84   GLboolean IndexLogicOp;
85   GLboolean ColorLogicOp;
86
87   GLboolean Map1Color4;
88   GLboolean Map1Index;
89   GLboolean Map1Normal;
90   GLboolean Map1TextureCoord1;
91   GLboolean Map1TextureCoord2;
92   GLboolean Map1TextureCoord3;
93   GLboolean Map1TextureCoord4;
94   GLboolean Map1Vertex3;
95   GLboolean Map1Vertex4;
96   GLboolean Map2Color4;
97   GLboolean Map2Index;
98   GLboolean Map2Normal;
99   GLboolean Map2TextureCoord1;
100   GLboolean Map2TextureCoord2;
101   GLboolean Map2TextureCoord3;
102   GLboolean Map2TextureCoord4;
103   GLboolean Map2Vertex3;
104   GLboolean Map2Vertex4;
105
106   GLboolean Normalize;
107   GLboolean PixelTexture;
108   GLboolean PointSmooth;
109   GLboolean PolygonOffsetPoint;
110   GLboolean PolygonOffsetLine;
111   GLboolean PolygonOffsetFill;
112   GLboolean PolygonSmooth;
113   GLboolean PolygonStipple;
114   GLboolean RescaleNormals;
115   GLbitfield Scissor;
116   GLboolean Stencil;
117   GLboolean StencilTwoSide;          /* GL_EXT_stencil_two_side */
118   GLboolean MultisampleEnabled;      /* GL_ARB_multisample */
119   GLboolean SampleAlphaToCoverage;   /* GL_ARB_multisample */
120   GLboolean SampleAlphaToOne;        /* GL_ARB_multisample */
121   GLboolean SampleCoverage;          /* GL_ARB_multisample */
122   GLboolean RasterPositionUnclipped; /* GL_IBM_rasterpos_clip */
123
124   GLbitfield Texture[MAX_TEXTURE_UNITS];
125   GLbitfield TexGen[MAX_TEXTURE_UNITS];
126
127   /* GL_ARB_vertex_program */
128   GLboolean VertexProgram;
129   GLboolean VertexProgramPointSize;
130   GLboolean VertexProgramTwoSide;
131
132   /* GL_ARB_fragment_program */
133   GLboolean FragmentProgram;
134
135   /* GL_ARB_point_sprite / GL_NV_point_sprite */
136   GLboolean PointSprite;
137   GLboolean FragmentShaderATI;
138
139   /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
140   GLboolean sRGBEnabled;
141
142   /* GL_NV_conservative_raster */
143   GLboolean ConservativeRasterization;
144};
145
146
147/**
148 * Node for the attribute stack.
149 */
150struct gl_attrib_node
151{
152   GLbitfield kind;
153   void *data;
154   struct gl_attrib_node *next;
155};
156
157
158
159/**
160 * Special struct for saving/restoring texture state (GL_TEXTURE_BIT)
161 */
162struct texture_state
163{
164   struct gl_texture_attrib Texture;  /**< The usual context state */
165
166   /** to save per texture object state (wrap modes, filters, etc): */
167   struct gl_texture_object SavedObj[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS];
168
169   /**
170    * To save references to texture objects (so they don't get accidentally
171    * deleted while saved in the attribute stack).
172    */
173   struct gl_texture_object *SavedTexRef[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS];
174
175   /* We need to keep a reference to the shared state.  That's where the
176    * default texture objects are kept.  We don't want that state to be
177    * freed while the attribute stack contains pointers to any default
178    * texture objects.
179    */
180   struct gl_shared_state *SharedRef;
181};
182
183
184struct viewport_state
185{
186   struct gl_viewport_attrib ViewportArray[MAX_VIEWPORTS];
187   GLuint SubpixelPrecisionBias[2];
188};
189
190
191/** An unused GL_*_BIT value */
192#define DUMMY_BIT 0x10000000
193
194
195/**
196 * Allocate new attribute node of given type/kind.  Attach payload data.
197 * Insert it into the linked list named by 'head'.
198 */
199static bool
200save_attrib_data(struct gl_attrib_node **head,
201                 GLbitfield kind, void *payload)
202{
203   struct gl_attrib_node *n = MALLOC_STRUCT(gl_attrib_node);
204   if (n) {
205      n->kind = kind;
206      n->data = payload;
207      /* insert at head */
208      n->next = *head;
209      *head = n;
210   }
211   else {
212      /* out of memory! */
213      return false;
214   }
215   return true;
216}
217
218
219/**
220 * Helper function for_mesa_PushAttrib for simple attributes.
221 * Allocates memory for attribute data and copies the given attribute data.
222 * \param head  head of linked list to insert attribute data into
223 * \param attr_bit  one of the GL_<attrib>_BIT flags
224 * \param attr_size  number of bytes to allocate for attribute data
225 * \param attr_data  the attribute data to copy
226 * \return true for success, false for out of memory
227 */
228static bool
229push_attrib(struct gl_context *ctx, struct gl_attrib_node **head,
230            GLbitfield attr_bit, GLuint attr_size, const void *attr_data)
231{
232   void *attribute;
233
234   attribute = malloc(attr_size);
235   if (attribute == NULL) {
236      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
237      return false;
238   }
239
240   if (save_attrib_data(head, attr_bit, attribute)) {
241      memcpy(attribute, attr_data, attr_size);
242   }
243   else {
244      free(attribute);
245      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
246      return false;
247   }
248   return true;
249}
250
251
252void GLAPIENTRY
253_mesa_PushAttrib(GLbitfield mask)
254{
255   struct gl_attrib_node *head;
256
257   GET_CURRENT_CONTEXT(ctx);
258
259   if (MESA_VERBOSE & VERBOSE_API)
260      _mesa_debug(ctx, "glPushAttrib %x\n", (int) mask);
261
262   if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) {
263      _mesa_error(ctx, GL_STACK_OVERFLOW, "glPushAttrib");
264      return;
265   }
266
267   /* Build linked list of attribute nodes which save all attribute */
268   /* groups specified by the mask. */
269   head = NULL;
270
271   if (mask == 0) {
272      /* if mask is zero we still need to push something so that we
273       * don't get a GL_STACK_UNDERFLOW error in glPopAttrib().
274       */
275      GLuint dummy = 0;
276      if (!push_attrib(ctx, &head, DUMMY_BIT, sizeof(dummy), &dummy))
277         goto end;
278   }
279
280   if (mask & GL_ACCUM_BUFFER_BIT) {
281      if (!push_attrib(ctx, &head, GL_ACCUM_BUFFER_BIT,
282                       sizeof(struct gl_accum_attrib),
283                       (void*)&ctx->Accum))
284         goto end;
285   }
286
287   if (mask & GL_COLOR_BUFFER_BIT) {
288      GLuint i;
289      struct gl_colorbuffer_attrib *attr;
290      attr = MALLOC_STRUCT(gl_colorbuffer_attrib);
291      if (attr == NULL) {
292         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
293         goto end;
294      }
295
296    if (save_attrib_data(&head, GL_COLOR_BUFFER_BIT, attr)) {
297         memcpy(attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib));
298         /* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */
299         for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++)
300            attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i];
301      }
302      else {
303         free(attr);
304         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
305         goto end;
306      }
307   }
308
309   if (mask & GL_CURRENT_BIT) {
310      FLUSH_CURRENT(ctx, 0);
311      if (!push_attrib(ctx, &head, GL_CURRENT_BIT,
312                       sizeof(struct gl_current_attrib),
313                       (void*)&ctx->Current))
314         goto end;
315   }
316
317   if (mask & GL_DEPTH_BUFFER_BIT) {
318      if (!push_attrib(ctx, &head, GL_DEPTH_BUFFER_BIT,
319                       sizeof(struct gl_depthbuffer_attrib),
320                       (void*)&ctx->Depth))
321         goto end;
322   }
323
324   if (mask & GL_ENABLE_BIT) {
325      struct gl_enable_attrib *attr;
326      GLuint i;
327      attr = MALLOC_STRUCT(gl_enable_attrib);
328      if (attr == NULL) {
329         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
330         goto end;
331      }
332
333      /* Copy enable flags from all other attributes into the enable struct. */
334      attr->AlphaTest = ctx->Color.AlphaEnabled;
335      attr->AutoNormal = ctx->Eval.AutoNormal;
336      attr->Blend = ctx->Color.BlendEnabled;
337      attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled;
338      attr->ColorMaterial = ctx->Light.ColorMaterialEnabled;
339      attr->CullFace = ctx->Polygon.CullFlag;
340      attr->DepthClampNear = ctx->Transform.DepthClampNear;
341      attr->DepthClampFar = ctx->Transform.DepthClampFar;
342      attr->DepthTest = ctx->Depth.Test;
343      attr->Dither = ctx->Color.DitherFlag;
344      attr->Fog = ctx->Fog.Enabled;
345      for (i = 0; i < ctx->Const.MaxLights; i++) {
346         attr->Light[i] = ctx->Light.Light[i].Enabled;
347      }
348      attr->Lighting = ctx->Light.Enabled;
349      attr->LineSmooth = ctx->Line.SmoothFlag;
350      attr->LineStipple = ctx->Line.StippleFlag;
351      attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled;
352      attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled;
353      attr->Map1Color4 = ctx->Eval.Map1Color4;
354      attr->Map1Index = ctx->Eval.Map1Index;
355      attr->Map1Normal = ctx->Eval.Map1Normal;
356      attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1;
357      attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2;
358      attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3;
359      attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4;
360      attr->Map1Vertex3 = ctx->Eval.Map1Vertex3;
361      attr->Map1Vertex4 = ctx->Eval.Map1Vertex4;
362      attr->Map2Color4 = ctx->Eval.Map2Color4;
363      attr->Map2Index = ctx->Eval.Map2Index;
364      attr->Map2Normal = ctx->Eval.Map2Normal;
365      attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1;
366      attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2;
367      attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3;
368      attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4;
369      attr->Map2Vertex3 = ctx->Eval.Map2Vertex3;
370      attr->Map2Vertex4 = ctx->Eval.Map2Vertex4;
371      attr->Normalize = ctx->Transform.Normalize;
372      attr->RasterPositionUnclipped = ctx->Transform.RasterPositionUnclipped;
373      attr->PointSmooth = ctx->Point.SmoothFlag;
374      attr->PointSprite = ctx->Point.PointSprite;
375      attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint;
376      attr->PolygonOffsetLine = ctx->Polygon.OffsetLine;
377      attr->PolygonOffsetFill = ctx->Polygon.OffsetFill;
378      attr->PolygonSmooth = ctx->Polygon.SmoothFlag;
379      attr->PolygonStipple = ctx->Polygon.StippleFlag;
380      attr->RescaleNormals = ctx->Transform.RescaleNormals;
381      attr->Scissor = ctx->Scissor.EnableFlags;
382      attr->Stencil = ctx->Stencil.Enabled;
383      attr->StencilTwoSide = ctx->Stencil.TestTwoSide;
384      attr->MultisampleEnabled = ctx->Multisample.Enabled;
385      attr->SampleAlphaToCoverage = ctx->Multisample.SampleAlphaToCoverage;
386      attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne;
387      attr->SampleCoverage = ctx->Multisample.SampleCoverage;
388      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
389         attr->Texture[i] = ctx->Texture.FixedFuncUnit[i].Enabled;
390         attr->TexGen[i] = ctx->Texture.FixedFuncUnit[i].TexGenEnabled;
391      }
392      /* GL_ARB_vertex_program */
393      attr->VertexProgram = ctx->VertexProgram.Enabled;
394      attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled;
395      attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled;
396
397      /* GL_ARB_fragment_program */
398      attr->FragmentProgram = ctx->FragmentProgram.Enabled;
399
400      if (!save_attrib_data(&head, GL_ENABLE_BIT, attr)) {
401         free(attr);
402         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
403         goto end;
404      }
405
406      /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
407      attr->sRGBEnabled = ctx->Color.sRGBEnabled;
408
409      /* GL_NV_conservative_raster */
410      attr->ConservativeRasterization = ctx->ConservativeRasterization;
411   }
412
413   if (mask & GL_EVAL_BIT) {
414      if (!push_attrib(ctx, &head, GL_EVAL_BIT,
415                       sizeof(struct gl_eval_attrib),
416                       (void*)&ctx->Eval))
417         goto end;
418   }
419
420   if (mask & GL_FOG_BIT) {
421      if (!push_attrib(ctx, &head, GL_FOG_BIT,
422                       sizeof(struct gl_fog_attrib),
423                       (void*)&ctx->Fog))
424         goto end;
425   }
426
427   if (mask & GL_HINT_BIT) {
428      if (!push_attrib(ctx, &head, GL_HINT_BIT,
429                       sizeof(struct gl_hint_attrib),
430                       (void*)&ctx->Hint))
431         goto end;
432   }
433
434   if (mask & GL_LIGHTING_BIT) {
435      FLUSH_CURRENT(ctx, 0);   /* flush material changes */
436      if (!push_attrib(ctx, &head, GL_LIGHTING_BIT,
437                       sizeof(struct gl_light_attrib),
438                       (void*)&ctx->Light))
439         goto end;
440   }
441
442   if (mask & GL_LINE_BIT) {
443      if (!push_attrib(ctx, &head, GL_LINE_BIT,
444                       sizeof(struct gl_line_attrib),
445                       (void*)&ctx->Line))
446         goto end;
447   }
448
449   if (mask & GL_LIST_BIT) {
450      if (!push_attrib(ctx, &head, GL_LIST_BIT,
451                       sizeof(struct gl_list_attrib),
452                       (void*)&ctx->List))
453         goto end;
454   }
455
456   if (mask & GL_PIXEL_MODE_BIT) {
457      struct gl_pixel_attrib *attr;
458      attr = MALLOC_STRUCT(gl_pixel_attrib);
459      if (attr == NULL) {
460         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
461         goto end;
462      }
463
464      if (save_attrib_data(&head, GL_PIXEL_MODE_BIT, attr)) {
465         memcpy(attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib));
466         /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */
467         attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer;
468      }
469      else {
470         free(attr);
471         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
472         goto end;
473      }
474   }
475
476   if (mask & GL_POINT_BIT) {
477      if (!push_attrib(ctx, &head, GL_POINT_BIT,
478                       sizeof(struct gl_point_attrib),
479                       (void*)&ctx->Point))
480         goto end;
481   }
482
483   if (mask & GL_POLYGON_BIT) {
484      if (!push_attrib(ctx, &head, GL_POLYGON_BIT,
485                       sizeof(struct gl_polygon_attrib),
486                       (void*)&ctx->Polygon))
487         goto end;
488   }
489
490   if (mask & GL_POLYGON_STIPPLE_BIT) {
491      if (!push_attrib(ctx, &head, GL_POLYGON_STIPPLE_BIT,
492                       sizeof(ctx->PolygonStipple),
493                       (void*)&ctx->PolygonStipple))
494         goto end;
495   }
496
497   if (mask & GL_SCISSOR_BIT) {
498      if (!push_attrib(ctx, &head, GL_SCISSOR_BIT,
499                       sizeof(struct gl_scissor_attrib),
500                       (void*)&ctx->Scissor))
501         goto end;
502   }
503
504   if (mask & GL_STENCIL_BUFFER_BIT) {
505      if (!push_attrib(ctx, &head, GL_STENCIL_BUFFER_BIT,
506                       sizeof(struct gl_stencil_attrib),
507                       (void*)&ctx->Stencil))
508         goto end;
509   }
510
511   if (mask & GL_TEXTURE_BIT) {
512      struct texture_state *texstate = CALLOC_STRUCT(texture_state);
513      GLuint u, tex;
514
515      if (!texstate) {
516         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)");
517         goto end;
518      }
519
520      if (!save_attrib_data(&head, GL_TEXTURE_BIT, texstate)) {
521         free(texstate);
522         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)");
523         goto end;
524      }
525
526      _mesa_lock_context_textures(ctx);
527
528      /* copy/save the bulk of texture state here */
529      memcpy(&texstate->Texture, &ctx->Texture, sizeof(ctx->Texture));
530
531      /* Save references to the currently bound texture objects so they don't
532       * accidentally get deleted while referenced in the attribute stack.
533       */
534      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
535         for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
536            _mesa_reference_texobj(&texstate->SavedTexRef[u][tex],
537                                   ctx->Texture.Unit[u].CurrentTex[tex]);
538         }
539      }
540
541      /* copy state/contents of the currently bound texture objects */
542      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
543         for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
544            _mesa_copy_texture_object(&texstate->SavedObj[u][tex],
545                                      ctx->Texture.Unit[u].CurrentTex[tex]);
546         }
547      }
548
549      _mesa_reference_shared_state(ctx, &texstate->SharedRef, ctx->Shared);
550
551      _mesa_unlock_context_textures(ctx);
552   }
553
554   if (mask & GL_TRANSFORM_BIT) {
555      if (!push_attrib(ctx, &head, GL_TRANSFORM_BIT,
556                       sizeof(struct gl_transform_attrib),
557                       (void*)&ctx->Transform))
558         goto end;
559   }
560
561   if (mask & GL_VIEWPORT_BIT) {
562      struct viewport_state *viewstate = CALLOC_STRUCT(viewport_state);
563      if (!viewstate) {
564         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_VIEWPORT_BIT)");
565         goto end;
566      }
567
568      if (!save_attrib_data(&head, GL_VIEWPORT_BIT, viewstate)) {
569         free(viewstate);
570         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_VIEWPORT_BIT)");
571         goto end;
572      }
573
574      memcpy(&viewstate->ViewportArray, &ctx->ViewportArray,
575             sizeof(struct gl_viewport_attrib)*ctx->Const.MaxViewports);
576
577      viewstate->SubpixelPrecisionBias[0] = ctx->SubpixelPrecisionBias[0];
578      viewstate->SubpixelPrecisionBias[1] = ctx->SubpixelPrecisionBias[1];
579   }
580
581   /* GL_ARB_multisample */
582   if (mask & GL_MULTISAMPLE_BIT_ARB) {
583      if (!push_attrib(ctx, &head, GL_MULTISAMPLE_BIT_ARB,
584                       sizeof(struct gl_multisample_attrib),
585                       (void*)&ctx->Multisample))
586         goto end;
587   }
588
589end:
590   if (head != NULL) {
591       ctx->AttribStack[ctx->AttribStackDepth] = head;
592       ctx->AttribStackDepth++;
593   }
594}
595
596
597
598static void
599pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable)
600{
601   const GLuint curTexUnitSave = ctx->Texture.CurrentUnit;
602   GLuint i;
603
604#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM)                \
605        if ((VALUE) != (NEWVALUE)) {                        \
606           _mesa_set_enable(ctx, ENUM, (NEWVALUE));        \
607        }
608
609   TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST);
610   if (ctx->Color.BlendEnabled != enable->Blend) {
611      if (ctx->Extensions.EXT_draw_buffers2) {
612         GLuint i;
613         for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
614            _mesa_set_enablei(ctx, GL_BLEND, i, (enable->Blend >> i) & 1);
615         }
616      }
617      else {
618         _mesa_set_enable(ctx, GL_BLEND, (enable->Blend & 1));
619      }
620   }
621
622   for (i=0;i<ctx->Const.MaxClipPlanes;i++) {
623      const GLuint mask = 1 << i;
624      if ((ctx->Transform.ClipPlanesEnabled & mask) != (enable->ClipPlanes & mask))
625          _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i),
626                           !!(enable->ClipPlanes & mask));
627   }
628
629   TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial,
630                   GL_COLOR_MATERIAL);
631   TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
632
633   if (!ctx->Extensions.AMD_depth_clamp_separate) {
634      TEST_AND_UPDATE(ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar,
635                      enable->DepthClampNear && enable->DepthClampFar,
636                      GL_DEPTH_CLAMP);
637   } else {
638      TEST_AND_UPDATE(ctx->Transform.DepthClampNear, enable->DepthClampNear,
639                      GL_DEPTH_CLAMP_NEAR_AMD);
640      TEST_AND_UPDATE(ctx->Transform.DepthClampFar, enable->DepthClampFar,
641                      GL_DEPTH_CLAMP_FAR_AMD);
642   }
643
644   TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST);
645   TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER);
646   TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG);
647   TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING);
648   TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH);
649   TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple,
650                   GL_LINE_STIPPLE);
651   TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp,
652                   GL_INDEX_LOGIC_OP);
653   TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp,
654                   GL_COLOR_LOGIC_OP);
655
656   TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4);
657   TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX);
658   TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL);
659   TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1,
660                   GL_MAP1_TEXTURE_COORD_1);
661   TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2,
662                   GL_MAP1_TEXTURE_COORD_2);
663   TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3,
664                   GL_MAP1_TEXTURE_COORD_3);
665   TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4,
666                   GL_MAP1_TEXTURE_COORD_4);
667   TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3,
668                   GL_MAP1_VERTEX_3);
669   TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4,
670                   GL_MAP1_VERTEX_4);
671
672   TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4);
673   TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX);
674   TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL);
675   TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1,
676                   GL_MAP2_TEXTURE_COORD_1);
677   TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2,
678                   GL_MAP2_TEXTURE_COORD_2);
679   TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3,
680                   GL_MAP2_TEXTURE_COORD_3);
681   TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4,
682                   GL_MAP2_TEXTURE_COORD_4);
683   TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3,
684                   GL_MAP2_VERTEX_3);
685   TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4,
686                   GL_MAP2_VERTEX_4);
687
688   TEST_AND_UPDATE(ctx->Eval.AutoNormal, enable->AutoNormal, GL_AUTO_NORMAL);
689   TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE);
690   TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals,
691                   GL_RESCALE_NORMAL_EXT);
692   TEST_AND_UPDATE(ctx->Transform.RasterPositionUnclipped,
693                   enable->RasterPositionUnclipped,
694                   GL_RASTER_POSITION_UNCLIPPED_IBM);
695   TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth,
696                   GL_POINT_SMOOTH);
697   if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) {
698      TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite,
699                      GL_POINT_SPRITE_NV);
700   }
701   TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint,
702                   GL_POLYGON_OFFSET_POINT);
703   TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine,
704                   GL_POLYGON_OFFSET_LINE);
705   TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill,
706                   GL_POLYGON_OFFSET_FILL);
707   TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth,
708                   GL_POLYGON_SMOOTH);
709   TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple,
710                   GL_POLYGON_STIPPLE);
711   if (ctx->Scissor.EnableFlags != enable->Scissor) {
712      unsigned i;
713
714      for (i = 0; i < ctx->Const.MaxViewports; i++) {
715         _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i, (enable->Scissor >> i) & 1);
716      }
717   }
718   TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST);
719   if (ctx->Extensions.EXT_stencil_two_side) {
720      TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, enable->StencilTwoSide, GL_STENCIL_TEST_TWO_SIDE_EXT);
721   }
722   TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled,
723                   GL_MULTISAMPLE_ARB);
724   TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage,
725                   enable->SampleAlphaToCoverage,
726                   GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
727   TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne,
728                   enable->SampleAlphaToOne,
729                   GL_SAMPLE_ALPHA_TO_ONE_ARB);
730   TEST_AND_UPDATE(ctx->Multisample.SampleCoverage,
731                   enable->SampleCoverage,
732                   GL_SAMPLE_COVERAGE_ARB);
733   /* GL_ARB_vertex_program */
734   TEST_AND_UPDATE(ctx->VertexProgram.Enabled,
735                   enable->VertexProgram,
736                   GL_VERTEX_PROGRAM_ARB);
737   TEST_AND_UPDATE(ctx->VertexProgram.PointSizeEnabled,
738                   enable->VertexProgramPointSize,
739                   GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
740   TEST_AND_UPDATE(ctx->VertexProgram.TwoSideEnabled,
741                   enable->VertexProgramTwoSide,
742                   GL_VERTEX_PROGRAM_TWO_SIDE_ARB);
743
744   /* GL_ARB_fragment_program */
745   TEST_AND_UPDATE(ctx->FragmentProgram.Enabled,
746                   enable->FragmentProgram,
747                   GL_FRAGMENT_PROGRAM_ARB);
748
749   /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
750   TEST_AND_UPDATE(ctx->Color.sRGBEnabled, enable->sRGBEnabled,
751                   GL_FRAMEBUFFER_SRGB);
752
753   /* GL_NV_conservative_raster */
754   if (ctx->Extensions.NV_conservative_raster) {
755      TEST_AND_UPDATE(ctx->ConservativeRasterization,
756                      enable->ConservativeRasterization,
757                      GL_CONSERVATIVE_RASTERIZATION_NV);
758   }
759
760   /* texture unit enables */
761   for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
762      const GLbitfield enabled = enable->Texture[i];
763      const GLbitfield genEnabled = enable->TexGen[i];
764
765      if (ctx->Texture.FixedFuncUnit[i].Enabled != enabled) {
766         _mesa_ActiveTexture(GL_TEXTURE0 + i);
767
768         _mesa_set_enable(ctx, GL_TEXTURE_1D, !!(enabled & TEXTURE_1D_BIT));
769         _mesa_set_enable(ctx, GL_TEXTURE_2D, !!(enabled & TEXTURE_2D_BIT));
770         _mesa_set_enable(ctx, GL_TEXTURE_3D, !!(enabled & TEXTURE_3D_BIT));
771         if (ctx->Extensions.NV_texture_rectangle) {
772            _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_ARB,
773                             !!(enabled & TEXTURE_RECT_BIT));
774         }
775         if (ctx->Extensions.ARB_texture_cube_map) {
776            _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP,
777                             !!(enabled & TEXTURE_CUBE_BIT));
778         }
779      }
780
781      if (ctx->Texture.FixedFuncUnit[i].TexGenEnabled != genEnabled) {
782         _mesa_ActiveTexture(GL_TEXTURE0 + i);
783         _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, !!(genEnabled & S_BIT));
784         _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, !!(genEnabled & T_BIT));
785         _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, !!(genEnabled & R_BIT));
786         _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, !!(genEnabled & Q_BIT));
787      }
788   }
789
790   _mesa_ActiveTexture(GL_TEXTURE0 + curTexUnitSave);
791}
792
793
794/**
795 * Pop/restore texture attribute/group state.
796 */
797static void
798pop_texture_group(struct gl_context *ctx, struct texture_state *texstate)
799{
800   GLuint u;
801
802   _mesa_lock_context_textures(ctx);
803
804   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
805      const struct gl_fixedfunc_texture_unit *unit =
806         &texstate->Texture.FixedFuncUnit[u];
807      GLuint tgt;
808
809      _mesa_ActiveTexture(GL_TEXTURE0_ARB + u);
810      _mesa_set_enable(ctx, GL_TEXTURE_1D, !!(unit->Enabled & TEXTURE_1D_BIT));
811      _mesa_set_enable(ctx, GL_TEXTURE_2D, !!(unit->Enabled & TEXTURE_2D_BIT));
812      _mesa_set_enable(ctx, GL_TEXTURE_3D, !!(unit->Enabled & TEXTURE_3D_BIT));
813      if (ctx->Extensions.ARB_texture_cube_map) {
814         _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP,
815                          !!(unit->Enabled & TEXTURE_CUBE_BIT));
816      }
817      if (ctx->Extensions.NV_texture_rectangle) {
818         _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_NV,
819                          !!(unit->Enabled & TEXTURE_RECT_BIT));
820      }
821      _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode);
822      _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor);
823      _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenS.Mode);
824      _mesa_TexGeni(GL_T, GL_TEXTURE_GEN_MODE, unit->GenT.Mode);
825      _mesa_TexGeni(GL_R, GL_TEXTURE_GEN_MODE, unit->GenR.Mode);
826      _mesa_TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, unit->GenQ.Mode);
827      _mesa_TexGenfv(GL_S, GL_OBJECT_PLANE, unit->GenS.ObjectPlane);
828      _mesa_TexGenfv(GL_T, GL_OBJECT_PLANE, unit->GenT.ObjectPlane);
829      _mesa_TexGenfv(GL_R, GL_OBJECT_PLANE, unit->GenR.ObjectPlane);
830      _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->GenQ.ObjectPlane);
831      /* Eye plane done differently to avoid re-transformation */
832      {
833         struct gl_fixedfunc_texture_unit *destUnit =
834            &ctx->Texture.FixedFuncUnit[u];
835
836         COPY_4FV(destUnit->GenS.EyePlane, unit->GenS.EyePlane);
837         COPY_4FV(destUnit->GenT.EyePlane, unit->GenT.EyePlane);
838         COPY_4FV(destUnit->GenR.EyePlane, unit->GenR.EyePlane);
839         COPY_4FV(destUnit->GenQ.EyePlane, unit->GenQ.EyePlane);
840         if (ctx->Driver.TexGen) {
841            ctx->Driver.TexGen(ctx, GL_S, GL_EYE_PLANE, unit->GenS.EyePlane);
842            ctx->Driver.TexGen(ctx, GL_T, GL_EYE_PLANE, unit->GenT.EyePlane);
843            ctx->Driver.TexGen(ctx, GL_R, GL_EYE_PLANE, unit->GenR.EyePlane);
844            ctx->Driver.TexGen(ctx, GL_Q, GL_EYE_PLANE, unit->GenQ.EyePlane);
845         }
846      }
847      _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, !!(unit->TexGenEnabled & S_BIT));
848      _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, !!(unit->TexGenEnabled & T_BIT));
849      _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, !!(unit->TexGenEnabled & R_BIT));
850      _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, !!(unit->TexGenEnabled & Q_BIT));
851      _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS,
852		    texstate->Texture.Unit[u].LodBias);
853      _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,
854                    unit->Combine.ModeRGB);
855      _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
856                    unit->Combine.ModeA);
857      {
858         const GLuint n = ctx->Extensions.NV_texture_env_combine4 ? 4 : 3;
859         GLuint i;
860         for (i = 0; i < n; i++) {
861            _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB + i,
862                          unit->Combine.SourceRGB[i]);
863            _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA + i,
864                          unit->Combine.SourceA[i]);
865            _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB + i,
866                          unit->Combine.OperandRGB[i]);
867            _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA + i,
868                          unit->Combine.OperandA[i]);
869         }
870      }
871      _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE,
872                    1 << unit->Combine.ScaleShiftRGB);
873      _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE,
874                    1 << unit->Combine.ScaleShiftA);
875
876      /* Restore texture object state for each target */
877      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
878         const struct gl_texture_object *obj = NULL;
879         const struct gl_sampler_object *samp;
880         GLenum target;
881
882         obj = &texstate->SavedObj[u][tgt];
883
884         /* don't restore state for unsupported targets to prevent
885          * raising GL errors.
886          */
887         if (obj->Target == GL_TEXTURE_CUBE_MAP &&
888             !ctx->Extensions.ARB_texture_cube_map) {
889            continue;
890         }
891         else if (obj->Target == GL_TEXTURE_RECTANGLE_NV &&
892                  !ctx->Extensions.NV_texture_rectangle) {
893            continue;
894         }
895         else if ((obj->Target == GL_TEXTURE_1D_ARRAY_EXT ||
896                   obj->Target == GL_TEXTURE_2D_ARRAY_EXT) &&
897                  !ctx->Extensions.EXT_texture_array) {
898            continue;
899         }
900         else if (obj->Target == GL_TEXTURE_CUBE_MAP_ARRAY &&
901             !ctx->Extensions.ARB_texture_cube_map_array) {
902            continue;
903         } else if (obj->Target == GL_TEXTURE_BUFFER)
904            continue;
905         else if (obj->Target == GL_TEXTURE_EXTERNAL_OES)
906            continue;
907         else if (obj->Target == GL_TEXTURE_2D_MULTISAMPLE ||
908                  obj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
909            continue;
910
911         target = obj->Target;
912
913         _mesa_BindTexture(target, obj->Name);
914
915         samp = &obj->Sampler;
916
917         _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, samp->BorderColor.f);
918         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, samp->WrapS);
919         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, samp->WrapT);
920         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, samp->WrapR);
921         _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, samp->MinFilter);
922         _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, samp->MagFilter);
923         _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, samp->MinLod);
924         _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, samp->MaxLod);
925         _mesa_TexParameterf(target, GL_TEXTURE_LOD_BIAS, samp->LodBias);
926         _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority);
927         _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel);
928         if (target != GL_TEXTURE_RECTANGLE_ARB)
929            _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel);
930         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
931            _mesa_TexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
932                                samp->MaxAnisotropy);
933         }
934         if (ctx->Extensions.ARB_shadow) {
935            _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_MODE,
936                                samp->CompareMode);
937            _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_FUNC,
938                                samp->CompareFunc);
939         }
940         if (ctx->Extensions.ARB_depth_texture)
941            _mesa_TexParameteri(target, GL_DEPTH_TEXTURE_MODE, obj->DepthMode);
942      }
943
944      /* remove saved references to the texture objects */
945      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
946         _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL);
947      }
948   }
949
950   _mesa_ActiveTexture(GL_TEXTURE0_ARB + texstate->Texture.CurrentUnit);
951
952   _mesa_reference_shared_state(ctx, &texstate->SharedRef, NULL);
953
954   _mesa_unlock_context_textures(ctx);
955}
956
957
958/*
959 * This function is kind of long just because we have to call a lot
960 * of device driver functions to update device driver state.
961 *
962 * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions
963 * in order to restore GL state.  This isn't terribly efficient but it
964 * ensures that dirty flags and any derived state gets updated correctly.
965 * We could at least check if the value to restore equals the current value
966 * and then skip the Mesa call.
967 */
968void GLAPIENTRY
969_mesa_PopAttrib(void)
970{
971   struct gl_attrib_node *attr, *next;
972   GET_CURRENT_CONTEXT(ctx);
973   FLUSH_VERTICES(ctx, 0);
974
975   if (ctx->AttribStackDepth == 0) {
976      _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopAttrib");
977      return;
978   }
979
980   ctx->AttribStackDepth--;
981   attr = ctx->AttribStack[ctx->AttribStackDepth];
982
983   while (attr) {
984
985      if (MESA_VERBOSE & VERBOSE_API) {
986         _mesa_debug(ctx, "glPopAttrib %s\n",
987                     _mesa_enum_to_string(attr->kind));
988      }
989
990      switch (attr->kind) {
991         case DUMMY_BIT:
992            /* do nothing */
993            break;
994
995         case GL_ACCUM_BUFFER_BIT:
996            {
997               const struct gl_accum_attrib *accum;
998               accum = (const struct gl_accum_attrib *) attr->data;
999               _mesa_ClearAccum(accum->ClearColor[0],
1000                                accum->ClearColor[1],
1001                                accum->ClearColor[2],
1002                                accum->ClearColor[3]);
1003            }
1004            break;
1005         case GL_COLOR_BUFFER_BIT:
1006            {
1007               const struct gl_colorbuffer_attrib *color;
1008
1009               color = (const struct gl_colorbuffer_attrib *) attr->data;
1010               _mesa_ClearIndex((GLfloat) color->ClearIndex);
1011               _mesa_ClearColor(color->ClearColor.f[0],
1012                                color->ClearColor.f[1],
1013                                color->ClearColor.f[2],
1014                                color->ClearColor.f[3]);
1015               _mesa_IndexMask(color->IndexMask);
1016               if (!ctx->Extensions.EXT_draw_buffers2) {
1017                  _mesa_ColorMask(GET_COLORMASK_BIT(color->ColorMask, 0, 0),
1018                                  GET_COLORMASK_BIT(color->ColorMask, 0, 1),
1019                                  GET_COLORMASK_BIT(color->ColorMask, 0, 2),
1020                                  GET_COLORMASK_BIT(color->ColorMask, 0, 3));
1021               }
1022               else {
1023                  GLuint i;
1024                  for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
1025                     _mesa_ColorMaski(i,
1026                                      GET_COLORMASK_BIT(color->ColorMask, i, 0),
1027                                      GET_COLORMASK_BIT(color->ColorMask, i, 1),
1028                                      GET_COLORMASK_BIT(color->ColorMask, i, 2),
1029                                      GET_COLORMASK_BIT(color->ColorMask, i, 3));
1030                  }
1031               }
1032               {
1033                  /* Need to determine if more than one color output is
1034                   * specified.  If so, call glDrawBuffersARB, else call
1035                   * glDrawBuffer().  This is a subtle, but essential point
1036                   * since GL_FRONT (for example) is illegal for the former
1037                   * function, but legal for the later.
1038                   */
1039                  GLboolean multipleBuffers = GL_FALSE;
1040                  GLuint i;
1041
1042                  for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) {
1043                     if (color->DrawBuffer[i] != GL_NONE) {
1044                        multipleBuffers = GL_TRUE;
1045                        break;
1046                     }
1047                  }
1048                  /* Call the API_level functions, not _mesa_drawbuffers()
1049                   * since we need to do error checking on the pop'd
1050                   * GL_DRAW_BUFFER.
1051                   * Ex: if GL_FRONT were pushed, but we're popping with a
1052                   * user FBO bound, GL_FRONT will be illegal and we'll need
1053                   * to record that error.  Per OpenGL ARB decision.
1054                   */
1055                  if (multipleBuffers) {
1056                     GLenum buffers[MAX_DRAW_BUFFERS];
1057
1058                     for (unsigned i = 0; i < ctx->Const.MaxDrawBuffers; i++)
1059                        buffers[i] = color->DrawBuffer[i];
1060
1061                     _mesa_DrawBuffers(ctx->Const.MaxDrawBuffers, buffers);
1062                  } else {
1063                     _mesa_DrawBuffer(color->DrawBuffer[0]);
1064                  }
1065               }
1066               _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled);
1067               _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRefUnclamped);
1068               if (ctx->Color.BlendEnabled != color->BlendEnabled) {
1069                  if (ctx->Extensions.EXT_draw_buffers2) {
1070                     GLuint i;
1071                     for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
1072                        _mesa_set_enablei(ctx, GL_BLEND, i,
1073                                          (color->BlendEnabled >> i) & 1);
1074                     }
1075                  }
1076                  else {
1077                     _mesa_set_enable(ctx, GL_BLEND, (color->BlendEnabled & 1));
1078                  }
1079               }
1080               if (ctx->Color._BlendFuncPerBuffer ||
1081                   ctx->Color._BlendEquationPerBuffer) {
1082                  /* set blend per buffer */
1083                  GLuint buf;
1084                  for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) {
1085                     _mesa_BlendFuncSeparateiARB(buf, color->Blend[buf].SrcRGB,
1086                                              color->Blend[buf].DstRGB,
1087                                              color->Blend[buf].SrcA,
1088                                              color->Blend[buf].DstA);
1089                     _mesa_BlendEquationSeparateiARB(buf,
1090                                                  color->Blend[buf].EquationRGB,
1091                                                  color->Blend[buf].EquationA);
1092                  }
1093               }
1094               else {
1095                  /* set same blend modes for all buffers */
1096                  _mesa_BlendFuncSeparate(color->Blend[0].SrcRGB,
1097                                             color->Blend[0].DstRGB,
1098                                             color->Blend[0].SrcA,
1099                                             color->Blend[0].DstA);
1100                  /* This special case is because glBlendEquationSeparateEXT
1101                   * cannot take GL_LOGIC_OP as a parameter.
1102                   */
1103                  if (color->Blend[0].EquationRGB ==
1104                      color->Blend[0].EquationA) {
1105                     _mesa_BlendEquation(color->Blend[0].EquationRGB);
1106                  }
1107                  else {
1108                     _mesa_BlendEquationSeparate(
1109                                                 color->Blend[0].EquationRGB,
1110                                                 color->Blend[0].EquationA);
1111                  }
1112               }
1113               _mesa_BlendColor(color->BlendColorUnclamped[0],
1114                                color->BlendColorUnclamped[1],
1115                                color->BlendColorUnclamped[2],
1116                                color->BlendColorUnclamped[3]);
1117               _mesa_LogicOp(color->LogicOp);
1118               _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP,
1119                                color->ColorLogicOpEnabled);
1120               _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP,
1121                                color->IndexLogicOpEnabled);
1122               _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag);
1123               if (ctx->Extensions.ARB_color_buffer_float)
1124                  _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB,
1125                                   color->ClampFragmentColor);
1126               if (ctx->Extensions.ARB_color_buffer_float || ctx->Version >= 30)
1127                  _mesa_ClampColor(GL_CLAMP_READ_COLOR_ARB, color->ClampReadColor);
1128
1129               /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
1130               if (ctx->Extensions.EXT_framebuffer_sRGB)
1131                  _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB, color->sRGBEnabled);
1132            }
1133            break;
1134         case GL_CURRENT_BIT:
1135            FLUSH_CURRENT(ctx, 0);
1136            memcpy(&ctx->Current, attr->data,
1137                    sizeof(struct gl_current_attrib));
1138            break;
1139         case GL_DEPTH_BUFFER_BIT:
1140            {
1141               const struct gl_depthbuffer_attrib *depth;
1142               depth = (const struct gl_depthbuffer_attrib *) attr->data;
1143               _mesa_DepthFunc(depth->Func);
1144               _mesa_ClearDepth(depth->Clear);
1145               _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test);
1146               _mesa_DepthMask(depth->Mask);
1147               if (ctx->Extensions.EXT_depth_bounds_test) {
1148                  _mesa_set_enable(ctx, GL_DEPTH_BOUNDS_TEST_EXT,
1149                                   depth->BoundsTest);
1150                  _mesa_DepthBoundsEXT(depth->BoundsMin, depth->BoundsMax);
1151               }
1152            }
1153            break;
1154         case GL_ENABLE_BIT:
1155            {
1156               const struct gl_enable_attrib *enable;
1157               enable = (const struct gl_enable_attrib *) attr->data;
1158               pop_enable_group(ctx, enable);
1159               ctx->NewState |= _NEW_ALL;
1160               ctx->NewDriverState |= ctx->DriverFlags.NewAlphaTest |
1161                                      ctx->DriverFlags.NewBlend |
1162                                      ctx->DriverFlags.NewClipPlaneEnable |
1163                                      ctx->DriverFlags.NewDepth |
1164                                      ctx->DriverFlags.NewDepthClamp |
1165                                      ctx->DriverFlags.NewFramebufferSRGB |
1166                                      ctx->DriverFlags.NewLineState |
1167                                      ctx->DriverFlags.NewLogicOp |
1168                                      ctx->DriverFlags.NewMultisampleEnable |
1169                                      ctx->DriverFlags.NewPolygonState |
1170                                      ctx->DriverFlags.NewSampleAlphaToXEnable |
1171                                      ctx->DriverFlags.NewSampleMask |
1172                                      ctx->DriverFlags.NewScissorTest |
1173                                      ctx->DriverFlags.NewStencil |
1174                                      ctx->DriverFlags.NewNvConservativeRasterization;
1175            }
1176            break;
1177         case GL_EVAL_BIT:
1178            memcpy(&ctx->Eval, attr->data, sizeof(struct gl_eval_attrib));
1179            ctx->NewState |= _NEW_EVAL;
1180            break;
1181         case GL_FOG_BIT:
1182            {
1183               const struct gl_fog_attrib *fog;
1184               fog = (const struct gl_fog_attrib *) attr->data;
1185               _mesa_set_enable(ctx, GL_FOG, fog->Enabled);
1186               _mesa_Fogfv(GL_FOG_COLOR, fog->Color);
1187               _mesa_Fogf(GL_FOG_DENSITY, fog->Density);
1188               _mesa_Fogf(GL_FOG_START, fog->Start);
1189               _mesa_Fogf(GL_FOG_END, fog->End);
1190               _mesa_Fogf(GL_FOG_INDEX, fog->Index);
1191               _mesa_Fogi(GL_FOG_MODE, fog->Mode);
1192            }
1193            break;
1194         case GL_HINT_BIT:
1195            {
1196               const struct gl_hint_attrib *hint;
1197               hint = (const struct gl_hint_attrib *) attr->data;
1198               _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT,
1199                          hint->PerspectiveCorrection);
1200               _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth);
1201               _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth);
1202               _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth);
1203               _mesa_Hint(GL_FOG_HINT, hint->Fog);
1204               _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB,
1205                          hint->TextureCompression);
1206            }
1207            break;
1208         case GL_LIGHTING_BIT:
1209            {
1210               GLuint i;
1211               const struct gl_light_attrib *light;
1212               light = (const struct gl_light_attrib *) attr->data;
1213               /* lighting enable */
1214               _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled);
1215               /* per-light state */
1216               if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top))
1217                  _math_matrix_analyse(ctx->ModelviewMatrixStack.Top);
1218
1219               for (i = 0; i < ctx->Const.MaxLights; i++) {
1220                  const struct gl_light *l = &light->Light[i];
1221                  _mesa_set_enable(ctx, GL_LIGHT0 + i, l->Enabled);
1222                  _mesa_light(ctx, i, GL_AMBIENT, l->Ambient);
1223                  _mesa_light(ctx, i, GL_DIFFUSE, l->Diffuse);
1224                  _mesa_light(ctx, i, GL_SPECULAR, l->Specular);
1225                  _mesa_light(ctx, i, GL_POSITION, l->EyePosition);
1226                  _mesa_light(ctx, i, GL_SPOT_DIRECTION, l->SpotDirection);
1227                  {
1228                     GLfloat p[4] = { 0 };
1229                     p[0] = l->SpotExponent;
1230                     _mesa_light(ctx, i, GL_SPOT_EXPONENT, p);
1231                  }
1232                  {
1233                     GLfloat p[4] = { 0 };
1234                     p[0] = l->SpotCutoff;
1235                     _mesa_light(ctx, i, GL_SPOT_CUTOFF, p);
1236                  }
1237                  {
1238                     GLfloat p[4] = { 0 };
1239                     p[0] = l->ConstantAttenuation;
1240                     _mesa_light(ctx, i, GL_CONSTANT_ATTENUATION, p);
1241                  }
1242                  {
1243                     GLfloat p[4] = { 0 };
1244                     p[0] = l->LinearAttenuation;
1245                     _mesa_light(ctx, i, GL_LINEAR_ATTENUATION, p);
1246                  }
1247                  {
1248                     GLfloat p[4] = { 0 };
1249                     p[0] = l->QuadraticAttenuation;
1250                     _mesa_light(ctx, i, GL_QUADRATIC_ATTENUATION, p);
1251                  }
1252               }
1253               /* light model */
1254               _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT,
1255                                  light->Model.Ambient);
1256               _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER,
1257                                 (GLfloat) light->Model.LocalViewer);
1258               _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE,
1259                                 (GLfloat) light->Model.TwoSide);
1260               _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL,
1261                                 (GLfloat) light->Model.ColorControl);
1262               /* shade model */
1263               _mesa_ShadeModel(light->ShadeModel);
1264               /* color material */
1265               _mesa_ColorMaterial(light->ColorMaterialFace,
1266                                   light->ColorMaterialMode);
1267               _mesa_set_enable(ctx, GL_COLOR_MATERIAL,
1268                                light->ColorMaterialEnabled);
1269               /* materials */
1270               memcpy(&ctx->Light.Material, &light->Material,
1271                      sizeof(struct gl_material));
1272               if (ctx->Extensions.ARB_color_buffer_float) {
1273                  _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR_ARB,
1274                                   light->ClampVertexColor);
1275               }
1276            }
1277            break;
1278         case GL_LINE_BIT:
1279            {
1280               const struct gl_line_attrib *line;
1281               line = (const struct gl_line_attrib *) attr->data;
1282               _mesa_set_enable(ctx, GL_LINE_SMOOTH, line->SmoothFlag);
1283               _mesa_set_enable(ctx, GL_LINE_STIPPLE, line->StippleFlag);
1284               _mesa_LineStipple(line->StippleFactor, line->StipplePattern);
1285               _mesa_LineWidth(line->Width);
1286            }
1287            break;
1288         case GL_LIST_BIT:
1289            memcpy(&ctx->List, attr->data, sizeof(struct gl_list_attrib));
1290            break;
1291         case GL_PIXEL_MODE_BIT:
1292            memcpy(&ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib));
1293            /* XXX what other pixel state needs to be set by function calls? */
1294            _mesa_ReadBuffer(ctx->Pixel.ReadBuffer);
1295            ctx->NewState |= _NEW_PIXEL;
1296            break;
1297         case GL_POINT_BIT:
1298            {
1299               const struct gl_point_attrib *point;
1300               point = (const struct gl_point_attrib *) attr->data;
1301               _mesa_PointSize(point->Size);
1302               _mesa_set_enable(ctx, GL_POINT_SMOOTH, point->SmoothFlag);
1303               if (ctx->Extensions.EXT_point_parameters) {
1304                  _mesa_PointParameterfv(GL_DISTANCE_ATTENUATION_EXT,
1305                                         point->Params);
1306                  _mesa_PointParameterf(GL_POINT_SIZE_MIN_EXT,
1307                                        point->MinSize);
1308                  _mesa_PointParameterf(GL_POINT_SIZE_MAX_EXT,
1309                                        point->MaxSize);
1310                  _mesa_PointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_EXT,
1311                                        point->Threshold);
1312               }
1313               if (ctx->Extensions.NV_point_sprite
1314                   || ctx->Extensions.ARB_point_sprite) {
1315                  GLuint u;
1316                  for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
1317                     _mesa_TexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV,
1318                                   !!(point->CoordReplace & (1u << u)));
1319                  }
1320                  _mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite);
1321                  if (ctx->Extensions.NV_point_sprite)
1322                     _mesa_PointParameteri(GL_POINT_SPRITE_R_MODE_NV,
1323                                           ctx->Point.SpriteRMode);
1324
1325                  if ((ctx->API == API_OPENGL_COMPAT && ctx->Version >= 20)
1326                      || ctx->API == API_OPENGL_CORE)
1327                     _mesa_PointParameterf(GL_POINT_SPRITE_COORD_ORIGIN,
1328                                           (GLfloat)ctx->Point.SpriteOrigin);
1329               }
1330            }
1331            break;
1332         case GL_POLYGON_BIT:
1333            {
1334               const struct gl_polygon_attrib *polygon;
1335               polygon = (const struct gl_polygon_attrib *) attr->data;
1336               _mesa_CullFace(polygon->CullFaceMode);
1337               _mesa_FrontFace(polygon->FrontFace);
1338               _mesa_PolygonMode(GL_FRONT, polygon->FrontMode);
1339               _mesa_PolygonMode(GL_BACK, polygon->BackMode);
1340               _mesa_polygon_offset_clamp(ctx,
1341                                          polygon->OffsetFactor,
1342                                          polygon->OffsetUnits,
1343                                          polygon->OffsetClamp);
1344               _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag);
1345               _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag);
1346               _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag);
1347               _mesa_set_enable(ctx, GL_POLYGON_OFFSET_POINT,
1348                                polygon->OffsetPoint);
1349               _mesa_set_enable(ctx, GL_POLYGON_OFFSET_LINE,
1350                                polygon->OffsetLine);
1351               _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL,
1352                                polygon->OffsetFill);
1353            }
1354            break;
1355         case GL_POLYGON_STIPPLE_BIT:
1356            memcpy(ctx->PolygonStipple, attr->data, 32*sizeof(GLuint));
1357
1358            if (ctx->DriverFlags.NewPolygonStipple)
1359               ctx->NewDriverState |= ctx->DriverFlags.NewPolygonStipple;
1360            else
1361               ctx->NewState |= _NEW_POLYGONSTIPPLE;
1362
1363            if (ctx->Driver.PolygonStipple)
1364               ctx->Driver.PolygonStipple(ctx, (const GLubyte *) attr->data);
1365            break;
1366         case GL_SCISSOR_BIT:
1367            {
1368               unsigned i;
1369               const struct gl_scissor_attrib *scissor;
1370               scissor = (const struct gl_scissor_attrib *) attr->data;
1371
1372               for (i = 0; i < ctx->Const.MaxViewports; i++) {
1373                  _mesa_set_scissor(ctx, i,
1374                                    scissor->ScissorArray[i].X,
1375                                    scissor->ScissorArray[i].Y,
1376                                    scissor->ScissorArray[i].Width,
1377                                    scissor->ScissorArray[i].Height);
1378                  _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i,
1379                                    (scissor->EnableFlags >> i) & 1);
1380               }
1381               if (ctx->Extensions.EXT_window_rectangles) {
1382                  STATIC_ASSERT(sizeof(struct gl_scissor_rect) ==
1383                                4 * sizeof(GLint));
1384                  _mesa_WindowRectanglesEXT(
1385                        scissor->WindowRectMode, scissor->NumWindowRects,
1386                        (const GLint *)scissor->WindowRects);
1387               }
1388            }
1389            break;
1390         case GL_STENCIL_BUFFER_BIT:
1391            {
1392               const struct gl_stencil_attrib *stencil;
1393               stencil = (const struct gl_stencil_attrib *) attr->data;
1394               _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
1395               _mesa_ClearStencil(stencil->Clear);
1396               if (ctx->Extensions.EXT_stencil_two_side) {
1397                  _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
1398                                   stencil->TestTwoSide);
1399                  _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
1400                                             ? GL_BACK : GL_FRONT);
1401               }
1402               /* front state */
1403               _mesa_StencilFuncSeparate(GL_FRONT,
1404                                         stencil->Function[0],
1405                                         stencil->Ref[0],
1406                                         stencil->ValueMask[0]);
1407               _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
1408               _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
1409                                       stencil->ZFailFunc[0],
1410                                       stencil->ZPassFunc[0]);
1411               /* back state */
1412               _mesa_StencilFuncSeparate(GL_BACK,
1413                                         stencil->Function[1],
1414                                         stencil->Ref[1],
1415                                         stencil->ValueMask[1]);
1416               _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
1417               _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
1418                                       stencil->ZFailFunc[1],
1419                                       stencil->ZPassFunc[1]);
1420            }
1421            break;
1422         case GL_TRANSFORM_BIT:
1423            {
1424               GLuint i;
1425               const struct gl_transform_attrib *xform;
1426               xform = (const struct gl_transform_attrib *) attr->data;
1427               _mesa_MatrixMode(xform->MatrixMode);
1428               if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top))
1429                  _math_matrix_analyse(ctx->ProjectionMatrixStack.Top);
1430
1431               /* restore clip planes */
1432               for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
1433                  const GLuint mask = 1 << i;
1434                  const GLfloat *eyePlane = xform->EyeUserPlane[i];
1435                  COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane);
1436                  _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i,
1437                                   !!(xform->ClipPlanesEnabled & mask));
1438                  if (ctx->Driver.ClipPlane)
1439                     ctx->Driver.ClipPlane(ctx, GL_CLIP_PLANE0 + i, eyePlane);
1440               }
1441
1442               /* normalize/rescale */
1443               if (xform->Normalize != ctx->Transform.Normalize)
1444                  _mesa_set_enable(ctx, GL_NORMALIZE,ctx->Transform.Normalize);
1445               if (xform->RescaleNormals != ctx->Transform.RescaleNormals)
1446                  _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT,
1447                                   ctx->Transform.RescaleNormals);
1448
1449               if (!ctx->Extensions.AMD_depth_clamp_separate) {
1450                  if (xform->DepthClampNear != ctx->Transform.DepthClampNear &&
1451                      xform->DepthClampFar != ctx->Transform.DepthClampFar) {
1452                     _mesa_set_enable(ctx, GL_DEPTH_CLAMP,
1453                                      ctx->Transform.DepthClampNear &&
1454                                      ctx->Transform.DepthClampFar);
1455                  }
1456               } else {
1457                  if (xform->DepthClampNear != ctx->Transform.DepthClampNear)
1458                     _mesa_set_enable(ctx, GL_DEPTH_CLAMP_NEAR_AMD,
1459                                      ctx->Transform.DepthClampNear);
1460                  if (xform->DepthClampFar != ctx->Transform.DepthClampFar)
1461                     _mesa_set_enable(ctx, GL_DEPTH_CLAMP_FAR_AMD,
1462                                      ctx->Transform.DepthClampFar);
1463               }
1464
1465               if (ctx->Extensions.ARB_clip_control)
1466                  _mesa_ClipControl(xform->ClipOrigin, xform->ClipDepthMode);
1467            }
1468            break;
1469         case GL_TEXTURE_BIT:
1470            {
1471               struct texture_state *texstate
1472                  = (struct texture_state *) attr->data;
1473               pop_texture_group(ctx, texstate);
1474               ctx->NewState |= _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE;
1475            }
1476            break;
1477         case GL_VIEWPORT_BIT:
1478            {
1479               unsigned i;
1480               const struct viewport_state *viewstate;
1481               viewstate = (const struct viewport_state *) attr->data;
1482
1483               for (i = 0; i < ctx->Const.MaxViewports; i++) {
1484                  const struct gl_viewport_attrib *vp = &viewstate->ViewportArray[i];
1485                  _mesa_set_viewport(ctx, i, vp->X, vp->Y, vp->Width,
1486                                     vp->Height);
1487                  _mesa_set_depth_range(ctx, i, vp->Near, vp->Far);
1488               }
1489
1490               if (ctx->Extensions.NV_conservative_raster) {
1491                  GLuint biasx = viewstate->SubpixelPrecisionBias[0];
1492                  GLuint biasy = viewstate->SubpixelPrecisionBias[1];
1493                  _mesa_SubpixelPrecisionBiasNV(biasx, biasy);
1494               }
1495            }
1496            break;
1497         case GL_MULTISAMPLE_BIT_ARB:
1498            {
1499               const struct gl_multisample_attrib *ms;
1500               ms = (const struct gl_multisample_attrib *) attr->data;
1501
1502               TEST_AND_UPDATE(ctx->Multisample.Enabled,
1503                               ms->Enabled,
1504                               GL_MULTISAMPLE);
1505
1506               TEST_AND_UPDATE(ctx->Multisample.SampleCoverage,
1507                               ms->SampleCoverage,
1508                               GL_SAMPLE_COVERAGE);
1509
1510               TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage,
1511                               ms->SampleAlphaToCoverage,
1512                               GL_SAMPLE_ALPHA_TO_COVERAGE);
1513
1514               TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne,
1515                               ms->SampleAlphaToOne,
1516                               GL_SAMPLE_ALPHA_TO_ONE);
1517
1518               _mesa_SampleCoverage(ms->SampleCoverageValue,
1519                                       ms->SampleCoverageInvert);
1520            }
1521            break;
1522
1523         default:
1524            unreachable("Bad attrib flag in PopAttrib");
1525      }
1526
1527      next = attr->next;
1528      free(attr->data);
1529      free(attr);
1530      attr = next;
1531   }
1532}
1533
1534
1535/**
1536 * Copy gl_pixelstore_attrib from src to dst, updating buffer
1537 * object refcounts.
1538 */
1539static void
1540copy_pixelstore(struct gl_context *ctx,
1541                struct gl_pixelstore_attrib *dst,
1542                const struct gl_pixelstore_attrib *src)
1543{
1544   dst->Alignment = src->Alignment;
1545   dst->RowLength = src->RowLength;
1546   dst->SkipPixels = src->SkipPixels;
1547   dst->SkipRows = src->SkipRows;
1548   dst->ImageHeight = src->ImageHeight;
1549   dst->SkipImages = src->SkipImages;
1550   dst->SwapBytes = src->SwapBytes;
1551   dst->LsbFirst = src->LsbFirst;
1552   dst->Invert = src->Invert;
1553   _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
1554}
1555
1556
1557#define GL_CLIENT_PACK_BIT (1<<20)
1558#define GL_CLIENT_UNPACK_BIT (1<<21)
1559
1560/**
1561 * Copy gl_vertex_array_object from src to dest.
1562 * 'dest' must be in an initialized state.
1563 */
1564static void
1565copy_array_object(struct gl_context *ctx,
1566                  struct gl_vertex_array_object *dest,
1567                  struct gl_vertex_array_object *src)
1568{
1569   GLuint i;
1570
1571   /* skip Name */
1572   /* skip RefCount */
1573
1574   for (i = 0; i < ARRAY_SIZE(src->VertexAttrib); i++) {
1575      _mesa_copy_vertex_attrib_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]);
1576      _mesa_copy_vertex_buffer_binding(ctx, &dest->BufferBinding[i], &src->BufferBinding[i]);
1577   }
1578
1579   /* Enabled must be the same than on push */
1580   dest->Enabled = src->Enabled;
1581   dest->_EffEnabledVBO = src->_EffEnabledVBO;
1582   /* The bitmask of bound VBOs needs to match the VertexBinding array */
1583   dest->VertexAttribBufferMask = src->VertexAttribBufferMask;
1584   dest->_AttributeMapMode = src->_AttributeMapMode;
1585   dest->NewArrays = src->NewArrays;
1586}
1587
1588/**
1589 * Copy gl_array_attrib from src to dest.
1590 * 'dest' must be in an initialized state.
1591 */
1592static void
1593copy_array_attrib(struct gl_context *ctx,
1594                  struct gl_array_attrib *dest,
1595                  struct gl_array_attrib *src,
1596                  bool vbo_deleted)
1597{
1598   /* skip ArrayObj */
1599   /* skip DefaultArrayObj, Objects */
1600   dest->ActiveTexture = src->ActiveTexture;
1601   dest->LockFirst = src->LockFirst;
1602   dest->LockCount = src->LockCount;
1603   dest->PrimitiveRestart = src->PrimitiveRestart;
1604   dest->PrimitiveRestartFixedIndex = src->PrimitiveRestartFixedIndex;
1605   dest->_PrimitiveRestart = src->_PrimitiveRestart;
1606   dest->RestartIndex = src->RestartIndex;
1607   /* skip NewState */
1608   /* skip RebindArrays */
1609
1610   if (!vbo_deleted)
1611      copy_array_object(ctx, dest->VAO, src->VAO);
1612
1613   /* skip ArrayBufferObj */
1614   /* skip IndexBufferObj */
1615
1616   /* Invalidate array state. It will be updated during the next draw. */
1617   _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO, 0);
1618}
1619
1620/**
1621 * Save the content of src to dest.
1622 */
1623static void
1624save_array_attrib(struct gl_context *ctx,
1625                  struct gl_array_attrib *dest,
1626                  struct gl_array_attrib *src)
1627{
1628   /* Set the Name, needed for restore, but do never overwrite.
1629    * Needs to match value in the object hash. */
1630   dest->VAO->Name = src->VAO->Name;
1631   /* And copy all of the rest. */
1632   copy_array_attrib(ctx, dest, src, false);
1633
1634   /* Just reference them here */
1635   _mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj,
1636                                 src->ArrayBufferObj);
1637   _mesa_reference_buffer_object(ctx, &dest->VAO->IndexBufferObj,
1638                                 src->VAO->IndexBufferObj);
1639}
1640
1641/**
1642 * Restore the content of src to dest.
1643 */
1644static void
1645restore_array_attrib(struct gl_context *ctx,
1646                     struct gl_array_attrib *dest,
1647                     struct gl_array_attrib *src)
1648{
1649   bool is_vao_name_zero = src->VAO->Name == 0;
1650
1651   /* The ARB_vertex_array_object spec says:
1652    *
1653    *     "BindVertexArray fails and an INVALID_OPERATION error is generated
1654    *     if array is not a name returned from a previous call to
1655    *     GenVertexArrays, or if such a name has since been deleted with
1656    *     DeleteVertexArrays."
1657    *
1658    * Therefore popping a deleted VAO cannot magically recreate it.
1659    */
1660   if (!is_vao_name_zero && !_mesa_IsVertexArray(src->VAO->Name))
1661      return;
1662
1663   _mesa_BindVertexArray(src->VAO->Name);
1664
1665   /* Restore or recreate the buffer objects by the names ... */
1666   if (is_vao_name_zero || src->ArrayBufferObj->Name == 0 ||
1667       _mesa_IsBuffer(src->ArrayBufferObj->Name)) {
1668      /* ... and restore its content */
1669      copy_array_attrib(ctx, dest, src, false);
1670
1671      _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB,
1672                       src->ArrayBufferObj->Name);
1673   } else {
1674      copy_array_attrib(ctx, dest, src, true);
1675   }
1676
1677   if (is_vao_name_zero || src->VAO->IndexBufferObj->Name == 0 ||
1678       _mesa_IsBuffer(src->VAO->IndexBufferObj->Name))
1679      _mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,
1680                       src->VAO->IndexBufferObj->Name);
1681}
1682
1683/**
1684 * init/alloc the fields of 'attrib'.
1685 * Needs to the init part matching free_array_attrib_data below.
1686 */
1687static bool
1688init_array_attrib_data(struct gl_context *ctx,
1689                       struct gl_array_attrib *attrib)
1690{
1691   /* Get a non driver gl_vertex_array_object. */
1692   attrib->VAO = CALLOC_STRUCT(gl_vertex_array_object);
1693
1694   if (attrib->VAO == NULL) {
1695      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
1696      return false;
1697   }
1698
1699   _mesa_initialize_vao(ctx, attrib->VAO, 0);
1700   return true;
1701}
1702
1703/**
1704 * Free/unreference the fields of 'attrib' but don't delete it (that's
1705 * done later in the calling code).
1706 * Needs to the cleanup part matching init_array_attrib_data above.
1707 */
1708static void
1709free_array_attrib_data(struct gl_context *ctx,
1710                       struct gl_array_attrib *attrib)
1711{
1712   /* We use a non driver array object, so don't just unref since we would
1713    * end up using the drivers DeleteArrayObject function for deletion. */
1714   _mesa_delete_vao(ctx, attrib->VAO);
1715   attrib->VAO = 0;
1716   _mesa_reference_buffer_object(ctx, &attrib->ArrayBufferObj, NULL);
1717}
1718
1719
1720void GLAPIENTRY
1721_mesa_PushClientAttrib(GLbitfield mask)
1722{
1723   struct gl_attrib_node *head;
1724
1725   GET_CURRENT_CONTEXT(ctx);
1726
1727   if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) {
1728      _mesa_error(ctx, GL_STACK_OVERFLOW, "glPushClientAttrib");
1729      return;
1730   }
1731
1732   /* Build linked list of attribute nodes which save all attribute
1733    * groups specified by the mask.
1734    */
1735   head = NULL;
1736
1737   if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
1738      struct gl_pixelstore_attrib *attr;
1739      /* packing attribs */
1740      attr = CALLOC_STRUCT(gl_pixelstore_attrib);
1741      if (attr == NULL) {
1742         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
1743         goto end;
1744      }
1745      if (save_attrib_data(&head, GL_CLIENT_PACK_BIT, attr)) {
1746         copy_pixelstore(ctx, attr, &ctx->Pack);
1747      }
1748      else {
1749         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
1750         free(attr);
1751         goto end;
1752      }
1753
1754      /* unpacking attribs */
1755      attr = CALLOC_STRUCT(gl_pixelstore_attrib);
1756      if (attr == NULL) {
1757         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
1758         goto end;
1759      }
1760
1761      if (save_attrib_data(&head, GL_CLIENT_UNPACK_BIT, attr)) {
1762         copy_pixelstore(ctx, attr, &ctx->Unpack);
1763      }
1764      else {
1765         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
1766         free(attr);
1767         goto end;
1768       }
1769   }
1770
1771   if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
1772      struct gl_array_attrib *attr;
1773      attr = CALLOC_STRUCT(gl_array_attrib);
1774      if (attr == NULL) {
1775         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
1776         goto end;
1777      }
1778
1779      if (!init_array_attrib_data(ctx, attr)) {
1780         free(attr);
1781         goto end;
1782      }
1783
1784      if (save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr)) {
1785         save_array_attrib(ctx, attr, &ctx->Array);
1786      }
1787      else {
1788         free_array_attrib_data(ctx, attr);
1789         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
1790         free(attr);
1791         /* goto to keep safe from possible later changes */
1792         goto end;
1793      }
1794   }
1795end:
1796   if (head != NULL) {
1797       ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
1798       ctx->ClientAttribStackDepth++;
1799   }
1800}
1801
1802
1803void GLAPIENTRY
1804_mesa_PopClientAttrib(void)
1805{
1806   struct gl_attrib_node *node, *next;
1807
1808   GET_CURRENT_CONTEXT(ctx);
1809   FLUSH_VERTICES(ctx, 0);
1810
1811   if (ctx->ClientAttribStackDepth == 0) {
1812      _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib");
1813      return;
1814   }
1815
1816   ctx->ClientAttribStackDepth--;
1817   node = ctx->ClientAttribStack[ctx->ClientAttribStackDepth];
1818
1819   while (node) {
1820      switch (node->kind) {
1821         case GL_CLIENT_PACK_BIT:
1822            {
1823               struct gl_pixelstore_attrib *store =
1824                  (struct gl_pixelstore_attrib *) node->data;
1825               copy_pixelstore(ctx, &ctx->Pack, store);
1826               _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL);
1827            }
1828            break;
1829         case GL_CLIENT_UNPACK_BIT:
1830            {
1831               struct gl_pixelstore_attrib *store =
1832                  (struct gl_pixelstore_attrib *) node->data;
1833               copy_pixelstore(ctx, &ctx->Unpack, store);
1834               _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL);
1835            }
1836            break;
1837         case GL_CLIENT_VERTEX_ARRAY_BIT: {
1838            struct gl_array_attrib * attr =
1839               (struct gl_array_attrib *) node->data;
1840            restore_array_attrib(ctx, &ctx->Array, attr);
1841            free_array_attrib_data(ctx, attr);
1842            break;
1843         }
1844         default:
1845            unreachable("Bad attrib flag in PopClientAttrib");
1846      }
1847
1848      next = node->next;
1849      free(node->data);
1850      free(node);
1851      node = next;
1852   }
1853}
1854
1855
1856/**
1857 * Free any attribute state data that might be attached to the context.
1858 */
1859void
1860_mesa_free_attrib_data(struct gl_context *ctx)
1861{
1862   while (ctx->AttribStackDepth > 0) {
1863      struct gl_attrib_node *attr, *next;
1864
1865      ctx->AttribStackDepth--;
1866      attr = ctx->AttribStack[ctx->AttribStackDepth];
1867
1868      while (attr) {
1869         if (attr->kind == GL_TEXTURE_BIT) {
1870            struct texture_state *texstate = (struct texture_state*)attr->data;
1871            GLuint u, tgt;
1872            /* clear references to the saved texture objects */
1873            for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
1874               for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
1875                  _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL);
1876               }
1877            }
1878            _mesa_reference_shared_state(ctx, &texstate->SharedRef, NULL);
1879         }
1880         else {
1881            /* any other chunks of state that requires special handling? */
1882         }
1883
1884         next = attr->next;
1885         free(attr->data);
1886         free(attr);
1887         attr = next;
1888      }
1889   }
1890}
1891
1892
1893void
1894_mesa_init_attrib(struct gl_context *ctx)
1895{
1896   /* Renderer and client attribute stacks */
1897   ctx->AttribStackDepth = 0;
1898   ctx->ClientAttribStackDepth = 0;
1899}
1900