attrib.c revision b96ae1b2c463d6d99ee0418083ef68f4027b7cd7
1/*
2 * Mesa 3-D graphics library
3 * Version:  7.6
4 *
5 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6 * Copyright (C) 2009  VMware, Inc.   All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR 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 "colormac.h"
36#include "colortab.h"
37#include "context.h"
38#include "depth.h"
39#include "enable.h"
40#include "enums.h"
41#include "fog.h"
42#include "hint.h"
43#include "light.h"
44#include "lines.h"
45#include "matrix.h"
46#include "multisample.h"
47#include "points.h"
48#include "polygon.h"
49#include "scissor.h"
50#include "simple_list.h"
51#include "stencil.h"
52#include "texenv.h"
53#include "texgen.h"
54#include "texobj.h"
55#include "texparam.h"
56#include "texstate.h"
57#include "varray.h"
58#include "viewport.h"
59#include "mtypes.h"
60
61
62/**
63 * glEnable()/glDisable() attribute group (GL_ENABLE_BIT).
64 */
65struct gl_enable_attrib
66{
67   GLboolean AlphaTest;
68   GLboolean AutoNormal;
69   GLboolean Blend;
70   GLbitfield ClipPlanes;
71   GLboolean ColorMaterial;
72   GLboolean ColorTable[COLORTABLE_MAX];
73   GLboolean Convolution1D;
74   GLboolean Convolution2D;
75   GLboolean Separable2D;
76   GLboolean CullFace;
77   GLboolean DepthTest;
78   GLboolean Dither;
79   GLboolean Fog;
80   GLboolean Histogram;
81   GLboolean Light[MAX_LIGHTS];
82   GLboolean Lighting;
83   GLboolean LineSmooth;
84   GLboolean LineStipple;
85   GLboolean IndexLogicOp;
86   GLboolean ColorLogicOp;
87
88   GLboolean Map1Color4;
89   GLboolean Map1Index;
90   GLboolean Map1Normal;
91   GLboolean Map1TextureCoord1;
92   GLboolean Map1TextureCoord2;
93   GLboolean Map1TextureCoord3;
94   GLboolean Map1TextureCoord4;
95   GLboolean Map1Vertex3;
96   GLboolean Map1Vertex4;
97   GLboolean Map1Attrib[16];  /* GL_NV_vertex_program */
98   GLboolean Map2Color4;
99   GLboolean Map2Index;
100   GLboolean Map2Normal;
101   GLboolean Map2TextureCoord1;
102   GLboolean Map2TextureCoord2;
103   GLboolean Map2TextureCoord3;
104   GLboolean Map2TextureCoord4;
105   GLboolean Map2Vertex3;
106   GLboolean Map2Vertex4;
107   GLboolean Map2Attrib[16];  /* GL_NV_vertex_program */
108
109   GLboolean MinMax;
110   GLboolean Normalize;
111   GLboolean PixelTexture;
112   GLboolean PointSmooth;
113   GLboolean PolygonOffsetPoint;
114   GLboolean PolygonOffsetLine;
115   GLboolean PolygonOffsetFill;
116   GLboolean PolygonSmooth;
117   GLboolean PolygonStipple;
118   GLboolean RescaleNormals;
119   GLboolean Scissor;
120   GLboolean Stencil;
121   GLboolean StencilTwoSide;          /* GL_EXT_stencil_two_side */
122   GLboolean MultisampleEnabled;      /* GL_ARB_multisample */
123   GLboolean SampleAlphaToCoverage;   /* GL_ARB_multisample */
124   GLboolean SampleAlphaToOne;        /* GL_ARB_multisample */
125   GLboolean SampleCoverage;          /* GL_ARB_multisample */
126   GLboolean SampleCoverageInvert;    /* GL_ARB_multisample */
127   GLboolean RasterPositionUnclipped; /* GL_IBM_rasterpos_clip */
128
129   GLbitfield Texture[MAX_TEXTURE_UNITS];
130   GLbitfield TexGen[MAX_TEXTURE_UNITS];
131
132   /* SGI_texture_color_table */
133   GLboolean TextureColorTable[MAX_TEXTURE_UNITS];
134
135   /* GL_ARB_vertex_program / GL_NV_vertex_program */
136   GLboolean VertexProgram;
137   GLboolean VertexProgramPointSize;
138   GLboolean VertexProgramTwoSide;
139
140   /* GL_ARB_point_sprite / GL_NV_point_sprite */
141   GLboolean PointSprite;
142   GLboolean FragmentShaderATI;
143};
144
145
146/**
147 * Node for the attribute stack.
148 */
149struct gl_attrib_node
150{
151   GLbitfield kind;
152   void *data;
153   struct gl_attrib_node *next;
154};
155
156
157
158/**
159 * Special struct for saving/restoring texture state (GL_TEXTURE_BIT)
160 */
161struct texture_state
162{
163   struct gl_texture_attrib Texture;  /**< The usual context state */
164
165   /** to save per texture object state (wrap modes, filters, etc): */
166   struct gl_texture_object SavedObj[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS];
167
168   /**
169    * To save references to texture objects (so they don't get accidentally
170    * deleted while saved in the attribute stack).
171    */
172   struct gl_texture_object *SavedTexRef[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS];
173};
174
175
176/**
177 * Allocate a new attribute state node.  These nodes have a
178 * "kind" value and a pointer to a struct of state data.
179 */
180static struct gl_attrib_node *
181new_attrib_node( GLbitfield kind )
182{
183   struct gl_attrib_node *an = MALLOC_STRUCT(gl_attrib_node);
184   if (an) {
185      an->kind = kind;
186   }
187   return an;
188}
189
190
191void GLAPIENTRY
192_mesa_PushAttrib(GLbitfield mask)
193{
194   struct gl_attrib_node *newnode;
195   struct gl_attrib_node *head;
196
197   GET_CURRENT_CONTEXT(ctx);
198   ASSERT_OUTSIDE_BEGIN_END(ctx);
199
200   if (MESA_VERBOSE & VERBOSE_API)
201      _mesa_debug(ctx, "glPushAttrib %x\n", (int) mask);
202
203   if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) {
204      _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" );
205      return;
206   }
207
208   /* Build linked list of attribute nodes which save all attribute */
209   /* groups specified by the mask. */
210   head = NULL;
211
212   if (mask & GL_ACCUM_BUFFER_BIT) {
213      struct gl_accum_attrib *attr;
214      attr = MALLOC_STRUCT( gl_accum_attrib );
215      MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) );
216      newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT );
217      newnode->data = attr;
218      newnode->next = head;
219      head = newnode;
220   }
221
222   if (mask & GL_COLOR_BUFFER_BIT) {
223      GLuint i;
224      struct gl_colorbuffer_attrib *attr;
225      attr = MALLOC_STRUCT( gl_colorbuffer_attrib );
226      MEMCPY( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) );
227      /* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */
228      for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++)
229         attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i];
230      newnode = new_attrib_node( GL_COLOR_BUFFER_BIT );
231      newnode->data = attr;
232      newnode->next = head;
233      head = newnode;
234   }
235
236   if (mask & GL_CURRENT_BIT) {
237      struct gl_current_attrib *attr;
238      FLUSH_CURRENT( ctx, 0 );
239      attr = MALLOC_STRUCT( gl_current_attrib );
240      MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) );
241      newnode = new_attrib_node( GL_CURRENT_BIT );
242      newnode->data = attr;
243      newnode->next = head;
244      head = newnode;
245   }
246
247   if (mask & GL_DEPTH_BUFFER_BIT) {
248      struct gl_depthbuffer_attrib *attr;
249      attr = MALLOC_STRUCT( gl_depthbuffer_attrib );
250      MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) );
251      newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT );
252      newnode->data = attr;
253      newnode->next = head;
254      head = newnode;
255   }
256
257   if (mask & GL_ENABLE_BIT) {
258      struct gl_enable_attrib *attr;
259      GLuint i;
260      attr = MALLOC_STRUCT( gl_enable_attrib );
261      /* Copy enable flags from all other attributes into the enable struct. */
262      attr->AlphaTest = ctx->Color.AlphaEnabled;
263      attr->AutoNormal = ctx->Eval.AutoNormal;
264      attr->Blend = ctx->Color.BlendEnabled;
265      attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled;
266      attr->ColorMaterial = ctx->Light.ColorMaterialEnabled;
267      for (i = 0; i < COLORTABLE_MAX; i++) {
268         attr->ColorTable[i] = ctx->Pixel.ColorTableEnabled[i];
269      }
270      attr->Convolution1D = ctx->Pixel.Convolution1DEnabled;
271      attr->Convolution2D = ctx->Pixel.Convolution2DEnabled;
272      attr->Separable2D = ctx->Pixel.Separable2DEnabled;
273      attr->CullFace = ctx->Polygon.CullFlag;
274      attr->DepthTest = ctx->Depth.Test;
275      attr->Dither = ctx->Color.DitherFlag;
276      attr->Fog = ctx->Fog.Enabled;
277      for (i = 0; i < ctx->Const.MaxLights; i++) {
278         attr->Light[i] = ctx->Light.Light[i].Enabled;
279      }
280      attr->Lighting = ctx->Light.Enabled;
281      attr->LineSmooth = ctx->Line.SmoothFlag;
282      attr->LineStipple = ctx->Line.StippleFlag;
283      attr->Histogram = ctx->Pixel.HistogramEnabled;
284      attr->MinMax = ctx->Pixel.MinMaxEnabled;
285      attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled;
286      attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled;
287      attr->Map1Color4 = ctx->Eval.Map1Color4;
288      attr->Map1Index = ctx->Eval.Map1Index;
289      attr->Map1Normal = ctx->Eval.Map1Normal;
290      attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1;
291      attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2;
292      attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3;
293      attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4;
294      attr->Map1Vertex3 = ctx->Eval.Map1Vertex3;
295      attr->Map1Vertex4 = ctx->Eval.Map1Vertex4;
296      MEMCPY(attr->Map1Attrib, ctx->Eval.Map1Attrib, sizeof(ctx->Eval.Map1Attrib));
297      attr->Map2Color4 = ctx->Eval.Map2Color4;
298      attr->Map2Index = ctx->Eval.Map2Index;
299      attr->Map2Normal = ctx->Eval.Map2Normal;
300      attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1;
301      attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2;
302      attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3;
303      attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4;
304      attr->Map2Vertex3 = ctx->Eval.Map2Vertex3;
305      attr->Map2Vertex4 = ctx->Eval.Map2Vertex4;
306      MEMCPY(attr->Map2Attrib, ctx->Eval.Map2Attrib, sizeof(ctx->Eval.Map2Attrib));
307      attr->Normalize = ctx->Transform.Normalize;
308      attr->RasterPositionUnclipped = ctx->Transform.RasterPositionUnclipped;
309      attr->PointSmooth = ctx->Point.SmoothFlag;
310      attr->PointSprite = ctx->Point.PointSprite;
311      attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint;
312      attr->PolygonOffsetLine = ctx->Polygon.OffsetLine;
313      attr->PolygonOffsetFill = ctx->Polygon.OffsetFill;
314      attr->PolygonSmooth = ctx->Polygon.SmoothFlag;
315      attr->PolygonStipple = ctx->Polygon.StippleFlag;
316      attr->RescaleNormals = ctx->Transform.RescaleNormals;
317      attr->Scissor = ctx->Scissor.Enabled;
318      attr->Stencil = ctx->Stencil.Enabled;
319      attr->StencilTwoSide = ctx->Stencil.TestTwoSide;
320      attr->MultisampleEnabled = ctx->Multisample.Enabled;
321      attr->SampleAlphaToCoverage = ctx->Multisample.SampleAlphaToCoverage;
322      attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne;
323      attr->SampleCoverage = ctx->Multisample.SampleCoverage;
324      attr->SampleCoverageInvert = ctx->Multisample.SampleCoverageInvert;
325      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
326         attr->Texture[i] = ctx->Texture.Unit[i].Enabled;
327         attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled;
328         attr->TextureColorTable[i] = ctx->Texture.Unit[i].ColorTableEnabled;
329      }
330      /* GL_NV_vertex_program */
331      attr->VertexProgram = ctx->VertexProgram.Enabled;
332      attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled;
333      attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled;
334      newnode = new_attrib_node( GL_ENABLE_BIT );
335      newnode->data = attr;
336      newnode->next = head;
337      head = newnode;
338   }
339
340   if (mask & GL_EVAL_BIT) {
341      struct gl_eval_attrib *attr;
342      attr = MALLOC_STRUCT( gl_eval_attrib );
343      MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) );
344      newnode = new_attrib_node( GL_EVAL_BIT );
345      newnode->data = attr;
346      newnode->next = head;
347      head = newnode;
348   }
349
350   if (mask & GL_FOG_BIT) {
351      struct gl_fog_attrib *attr;
352      attr = MALLOC_STRUCT( gl_fog_attrib );
353      MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) );
354      newnode = new_attrib_node( GL_FOG_BIT );
355      newnode->data = attr;
356      newnode->next = head;
357      head = newnode;
358   }
359
360   if (mask & GL_HINT_BIT) {
361      struct gl_hint_attrib *attr;
362      attr = MALLOC_STRUCT( gl_hint_attrib );
363      MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) );
364      newnode = new_attrib_node( GL_HINT_BIT );
365      newnode->data = attr;
366      newnode->next = head;
367      head = newnode;
368   }
369
370   if (mask & GL_LIGHTING_BIT) {
371      struct gl_light_attrib *attr;
372      FLUSH_CURRENT(ctx, 0);	/* flush material changes */
373      attr = MALLOC_STRUCT( gl_light_attrib );
374      MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) );
375      newnode = new_attrib_node( GL_LIGHTING_BIT );
376      newnode->data = attr;
377      newnode->next = head;
378      head = newnode;
379   }
380
381   if (mask & GL_LINE_BIT) {
382      struct gl_line_attrib *attr;
383      attr = MALLOC_STRUCT( gl_line_attrib );
384      MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) );
385      newnode = new_attrib_node( GL_LINE_BIT );
386      newnode->data = attr;
387      newnode->next = head;
388      head = newnode;
389   }
390
391   if (mask & GL_LIST_BIT) {
392      struct gl_list_attrib *attr;
393      attr = MALLOC_STRUCT( gl_list_attrib );
394      MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) );
395      newnode = new_attrib_node( GL_LIST_BIT );
396      newnode->data = attr;
397      newnode->next = head;
398      head = newnode;
399   }
400
401   if (mask & GL_PIXEL_MODE_BIT) {
402      struct gl_pixel_attrib *attr;
403      attr = MALLOC_STRUCT( gl_pixel_attrib );
404      MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) );
405      /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */
406      attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer;
407      newnode = new_attrib_node( GL_PIXEL_MODE_BIT );
408      newnode->data = attr;
409      newnode->next = head;
410      head = newnode;
411   }
412
413   if (mask & GL_POINT_BIT) {
414      struct gl_point_attrib *attr;
415      attr = MALLOC_STRUCT( gl_point_attrib );
416      MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) );
417      newnode = new_attrib_node( GL_POINT_BIT );
418      newnode->data = attr;
419      newnode->next = head;
420      head = newnode;
421   }
422
423   if (mask & GL_POLYGON_BIT) {
424      struct gl_polygon_attrib *attr;
425      attr = MALLOC_STRUCT( gl_polygon_attrib );
426      MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) );
427      newnode = new_attrib_node( GL_POLYGON_BIT );
428      newnode->data = attr;
429      newnode->next = head;
430      head = newnode;
431   }
432
433   if (mask & GL_POLYGON_STIPPLE_BIT) {
434      GLuint *stipple;
435      stipple = (GLuint *) MALLOC( 32*sizeof(GLuint) );
436      MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) );
437      newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT );
438      newnode->data = stipple;
439      newnode->next = head;
440      head = newnode;
441   }
442
443   if (mask & GL_SCISSOR_BIT) {
444      struct gl_scissor_attrib *attr;
445      attr = MALLOC_STRUCT( gl_scissor_attrib );
446      MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) );
447      newnode = new_attrib_node( GL_SCISSOR_BIT );
448      newnode->data = attr;
449      newnode->next = head;
450      head = newnode;
451   }
452
453   if (mask & GL_STENCIL_BUFFER_BIT) {
454      struct gl_stencil_attrib *attr;
455      attr = MALLOC_STRUCT( gl_stencil_attrib );
456      MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) );
457      newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT );
458      newnode->data = attr;
459      newnode->next = head;
460      head = newnode;
461   }
462
463   if (mask & GL_TEXTURE_BIT) {
464      struct texture_state *texstate = CALLOC_STRUCT(texture_state);
465      GLuint u, tex;
466
467      if (!texstate) {
468         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)");
469         goto end;
470      }
471
472      _mesa_lock_context_textures(ctx);
473
474      /* copy/save the bulk of texture state here */
475      _mesa_memcpy(&texstate->Texture, &ctx->Texture, sizeof(ctx->Texture));
476
477      /* Save references to the currently bound texture objects so they don't
478       * accidentally get deleted while referenced in the attribute stack.
479       */
480      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
481         for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
482            _mesa_reference_texobj(&texstate->SavedTexRef[u][tex],
483                                   ctx->Texture.Unit[u].CurrentTex[tex]);
484         }
485      }
486
487      /* copy state/contents of the currently bound texture objects */
488      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
489         for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
490            _mesa_copy_texture_object(&texstate->SavedObj[u][tex],
491                                      ctx->Texture.Unit[u].CurrentTex[tex]);
492         }
493      }
494
495      _mesa_unlock_context_textures(ctx);
496
497      newnode = new_attrib_node( GL_TEXTURE_BIT );
498      newnode->data = texstate;
499      newnode->next = head;
500      head = newnode;
501   }
502
503   if (mask & GL_TRANSFORM_BIT) {
504      struct gl_transform_attrib *attr;
505      attr = MALLOC_STRUCT( gl_transform_attrib );
506      MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) );
507      newnode = new_attrib_node( GL_TRANSFORM_BIT );
508      newnode->data = attr;
509      newnode->next = head;
510      head = newnode;
511   }
512
513   if (mask & GL_VIEWPORT_BIT) {
514      struct gl_viewport_attrib *attr;
515      attr = MALLOC_STRUCT( gl_viewport_attrib );
516      MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) );
517      newnode = new_attrib_node( GL_VIEWPORT_BIT );
518      newnode->data = attr;
519      newnode->next = head;
520      head = newnode;
521   }
522
523   /* GL_ARB_multisample */
524   if (mask & GL_MULTISAMPLE_BIT_ARB) {
525      struct gl_multisample_attrib *attr;
526      attr = MALLOC_STRUCT( gl_multisample_attrib );
527      MEMCPY( attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib) );
528      newnode = new_attrib_node( GL_MULTISAMPLE_BIT_ARB );
529      newnode->data = attr;
530      newnode->next = head;
531      head = newnode;
532   }
533
534end:
535   ctx->AttribStack[ctx->AttribStackDepth] = head;
536   ctx->AttribStackDepth++;
537}
538
539
540
541static void
542pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable)
543{
544   const GLuint curTexUnitSave = ctx->Texture.CurrentUnit;
545   GLuint i;
546
547#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM)		\
548	if ((VALUE) != (NEWVALUE)) {			\
549	   _mesa_set_enable( ctx, ENUM, (NEWVALUE) );	\
550	}
551
552   TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST);
553   TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND);
554
555   for (i=0;i<MAX_CLIP_PLANES;i++) {
556      const GLuint mask = 1 << i;
557      if ((ctx->Transform.ClipPlanesEnabled & mask) != (enable->ClipPlanes & mask))
558	  _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i),
559			   (GLboolean) ((enable->ClipPlanes & mask) ? GL_TRUE : GL_FALSE));
560   }
561
562   TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial,
563                   GL_COLOR_MATERIAL);
564   TEST_AND_UPDATE(ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION],
565                   enable->ColorTable[COLORTABLE_PRECONVOLUTION],
566                   GL_COLOR_TABLE);
567   TEST_AND_UPDATE(ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION],
568                   enable->ColorTable[COLORTABLE_POSTCONVOLUTION],
569                   GL_POST_CONVOLUTION_COLOR_TABLE);
570   TEST_AND_UPDATE(ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX],
571                   enable->ColorTable[COLORTABLE_POSTCOLORMATRIX],
572                   GL_POST_COLOR_MATRIX_COLOR_TABLE);
573   TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
574   TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST);
575   TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER);
576   TEST_AND_UPDATE(ctx->Pixel.Convolution1DEnabled, enable->Convolution1D,
577                   GL_CONVOLUTION_1D);
578   TEST_AND_UPDATE(ctx->Pixel.Convolution2DEnabled, enable->Convolution2D,
579                   GL_CONVOLUTION_2D);
580   TEST_AND_UPDATE(ctx->Pixel.Separable2DEnabled, enable->Separable2D,
581                   GL_SEPARABLE_2D);
582   TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG);
583   TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING);
584   TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH);
585   TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple,
586                   GL_LINE_STIPPLE);
587   TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp,
588                   GL_INDEX_LOGIC_OP);
589   TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp,
590                   GL_COLOR_LOGIC_OP);
591
592   TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4);
593   TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX);
594   TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL);
595   TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1,
596                   GL_MAP1_TEXTURE_COORD_1);
597   TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2,
598                   GL_MAP1_TEXTURE_COORD_2);
599   TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3,
600                   GL_MAP1_TEXTURE_COORD_3);
601   TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4,
602                   GL_MAP1_TEXTURE_COORD_4);
603   TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3,
604                   GL_MAP1_VERTEX_3);
605   TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4,
606                   GL_MAP1_VERTEX_4);
607   for (i = 0; i < 16; i++) {
608      TEST_AND_UPDATE(ctx->Eval.Map1Attrib[i], enable->Map1Attrib[i],
609                      GL_MAP1_VERTEX_ATTRIB0_4_NV + i);
610   }
611
612   TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4);
613   TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX);
614   TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL);
615   TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1,
616                   GL_MAP2_TEXTURE_COORD_1);
617   TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2,
618                   GL_MAP2_TEXTURE_COORD_2);
619   TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3,
620                   GL_MAP2_TEXTURE_COORD_3);
621   TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4,
622                   GL_MAP2_TEXTURE_COORD_4);
623   TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3,
624                   GL_MAP2_VERTEX_3);
625   TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4,
626                   GL_MAP2_VERTEX_4);
627   for (i = 0; i < 16; i++) {
628      TEST_AND_UPDATE(ctx->Eval.Map2Attrib[i], enable->Map2Attrib[i],
629                      GL_MAP2_VERTEX_ATTRIB0_4_NV + i);
630   }
631
632   TEST_AND_UPDATE(ctx->Eval.AutoNormal, enable->AutoNormal, GL_AUTO_NORMAL);
633   TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE);
634   TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals,
635                   GL_RESCALE_NORMAL_EXT);
636   TEST_AND_UPDATE(ctx->Transform.RasterPositionUnclipped,
637                   enable->RasterPositionUnclipped,
638                   GL_RASTER_POSITION_UNCLIPPED_IBM);
639   TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth,
640                   GL_POINT_SMOOTH);
641   if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) {
642      TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite,
643                      GL_POINT_SPRITE_NV);
644   }
645   TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint,
646                   GL_POLYGON_OFFSET_POINT);
647   TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine,
648                   GL_POLYGON_OFFSET_LINE);
649   TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill,
650                   GL_POLYGON_OFFSET_FILL);
651   TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth,
652                   GL_POLYGON_SMOOTH);
653   TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple,
654                   GL_POLYGON_STIPPLE);
655   TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST);
656   TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST);
657   if (ctx->Extensions.EXT_stencil_two_side) {
658      TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, enable->StencilTwoSide, GL_STENCIL_TEST_TWO_SIDE_EXT);
659   }
660   TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled,
661                   GL_MULTISAMPLE_ARB);
662   TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage,
663                   enable->SampleAlphaToCoverage,
664                   GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
665   TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne,
666                   enable->SampleAlphaToOne,
667                   GL_SAMPLE_ALPHA_TO_ONE_ARB);
668   TEST_AND_UPDATE(ctx->Multisample.SampleCoverage,
669                   enable->SampleCoverage,
670                   GL_SAMPLE_COVERAGE_ARB);
671   TEST_AND_UPDATE(ctx->Multisample.SampleCoverageInvert,
672                   enable->SampleCoverageInvert,
673                   GL_SAMPLE_COVERAGE_INVERT_ARB);
674   /* GL_ARB_vertex_program, GL_NV_vertex_program */
675   TEST_AND_UPDATE(ctx->VertexProgram.Enabled,
676                   enable->VertexProgram,
677                   GL_VERTEX_PROGRAM_ARB);
678   TEST_AND_UPDATE(ctx->VertexProgram.PointSizeEnabled,
679                   enable->VertexProgramPointSize,
680                   GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
681   TEST_AND_UPDATE(ctx->VertexProgram.TwoSideEnabled,
682                   enable->VertexProgramTwoSide,
683                   GL_VERTEX_PROGRAM_TWO_SIDE_ARB);
684
685#undef TEST_AND_UPDATE
686
687   /* texture unit enables */
688   for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
689      const GLbitfield enabled = enable->Texture[i];
690      const GLbitfield genEnabled = enable->TexGen[i];
691
692      if (ctx->Texture.Unit[i].Enabled != enabled) {
693         _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
694
695         _mesa_set_enable(ctx, GL_TEXTURE_1D,
696                          (enabled & TEXTURE_1D_BIT) ? GL_TRUE : GL_FALSE);
697         _mesa_set_enable(ctx, GL_TEXTURE_2D,
698                          (enabled & TEXTURE_2D_BIT) ? GL_TRUE : GL_FALSE);
699         _mesa_set_enable(ctx, GL_TEXTURE_3D,
700                          (enabled & TEXTURE_3D_BIT) ? GL_TRUE : GL_FALSE);
701         if (ctx->Extensions.NV_texture_rectangle) {
702            _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_ARB,
703                             (enabled & TEXTURE_RECT_BIT) ? GL_TRUE : GL_FALSE);
704         }
705         if (ctx->Extensions.ARB_texture_cube_map) {
706            _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP,
707                             (enabled & TEXTURE_CUBE_BIT) ? GL_TRUE : GL_FALSE);
708         }
709         if (ctx->Extensions.MESA_texture_array) {
710            _mesa_set_enable(ctx, GL_TEXTURE_1D_ARRAY_EXT,
711                           (enabled & TEXTURE_1D_ARRAY_BIT) ? GL_TRUE : GL_FALSE);
712            _mesa_set_enable(ctx, GL_TEXTURE_2D_ARRAY_EXT,
713                           (enabled & TEXTURE_2D_ARRAY_BIT) ? GL_TRUE : GL_FALSE);
714         }
715      }
716
717      if (ctx->Texture.Unit[i].TexGenEnabled != genEnabled) {
718         _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
719         _mesa_set_enable(ctx, GL_TEXTURE_GEN_S,
720                          (genEnabled & S_BIT) ? GL_TRUE : GL_FALSE);
721         _mesa_set_enable(ctx, GL_TEXTURE_GEN_T,
722                          (genEnabled & T_BIT) ? GL_TRUE : GL_FALSE);
723         _mesa_set_enable(ctx, GL_TEXTURE_GEN_R,
724                          (genEnabled & R_BIT) ? GL_TRUE : GL_FALSE);
725         _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q,
726                          (genEnabled & Q_BIT) ? GL_TRUE : GL_FALSE);
727      }
728
729      /* GL_SGI_texture_color_table */
730      ctx->Texture.Unit[i].ColorTableEnabled = enable->TextureColorTable[i];
731   }
732
733   _mesa_ActiveTextureARB(GL_TEXTURE0 + curTexUnitSave);
734}
735
736
737/**
738 * Pop/restore texture attribute/group state.
739 */
740static void
741pop_texture_group(GLcontext *ctx, struct texture_state *texstate)
742{
743   GLuint u;
744
745   _mesa_lock_context_textures(ctx);
746
747   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
748      const struct gl_texture_unit *unit = &texstate->Texture.Unit[u];
749      GLuint tgt;
750
751      _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + u);
752      _mesa_set_enable(ctx, GL_TEXTURE_1D,
753                       (unit->Enabled & TEXTURE_1D_BIT) ? GL_TRUE : GL_FALSE);
754      _mesa_set_enable(ctx, GL_TEXTURE_2D,
755                       (unit->Enabled & TEXTURE_2D_BIT) ? GL_TRUE : GL_FALSE);
756      _mesa_set_enable(ctx, GL_TEXTURE_3D,
757                       (unit->Enabled & TEXTURE_3D_BIT) ? GL_TRUE : GL_FALSE);
758      if (ctx->Extensions.ARB_texture_cube_map) {
759         _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP_ARB,
760                     (unit->Enabled & TEXTURE_CUBE_BIT) ? GL_TRUE : GL_FALSE);
761      }
762      if (ctx->Extensions.NV_texture_rectangle) {
763         _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_NV,
764                     (unit->Enabled & TEXTURE_RECT_BIT) ? GL_TRUE : GL_FALSE);
765      }
766      if (ctx->Extensions.MESA_texture_array) {
767         _mesa_set_enable(ctx, GL_TEXTURE_1D_ARRAY_EXT,
768                 (unit->Enabled & TEXTURE_1D_ARRAY_BIT) ? GL_TRUE : GL_FALSE);
769         _mesa_set_enable(ctx, GL_TEXTURE_2D_ARRAY_EXT,
770                 (unit->Enabled & TEXTURE_2D_ARRAY_BIT) ? GL_TRUE : GL_FALSE);
771      }
772
773      if (ctx->Extensions.SGI_texture_color_table) {
774         _mesa_set_enable(ctx, GL_TEXTURE_COLOR_TABLE_SGI,
775                          unit->ColorTableEnabled);
776      }
777      _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode);
778      _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor);
779      _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenS.Mode);
780      _mesa_TexGeni(GL_T, GL_TEXTURE_GEN_MODE, unit->GenT.Mode);
781      _mesa_TexGeni(GL_R, GL_TEXTURE_GEN_MODE, unit->GenR.Mode);
782      _mesa_TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, unit->GenQ.Mode);
783      _mesa_TexGenfv(GL_S, GL_OBJECT_PLANE, unit->GenS.ObjectPlane);
784      _mesa_TexGenfv(GL_T, GL_OBJECT_PLANE, unit->GenT.ObjectPlane);
785      _mesa_TexGenfv(GL_R, GL_OBJECT_PLANE, unit->GenR.ObjectPlane);
786      _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->GenQ.ObjectPlane);
787      /* Eye plane done differently to avoid re-transformation */
788      {
789         struct gl_texture_unit *destUnit = &ctx->Texture.Unit[u];
790         COPY_4FV(destUnit->GenS.EyePlane, unit->GenS.EyePlane);
791         COPY_4FV(destUnit->GenT.EyePlane, unit->GenT.EyePlane);
792         COPY_4FV(destUnit->GenR.EyePlane, unit->GenR.EyePlane);
793         COPY_4FV(destUnit->GenQ.EyePlane, unit->GenQ.EyePlane);
794         if (ctx->Driver.TexGen) {
795            ctx->Driver.TexGen(ctx, GL_S, GL_EYE_PLANE, unit->GenS.EyePlane);
796            ctx->Driver.TexGen(ctx, GL_T, GL_EYE_PLANE, unit->GenT.EyePlane);
797            ctx->Driver.TexGen(ctx, GL_R, GL_EYE_PLANE, unit->GenR.EyePlane);
798            ctx->Driver.TexGen(ctx, GL_Q, GL_EYE_PLANE, unit->GenQ.EyePlane);
799         }
800      }
801      _mesa_set_enable(ctx, GL_TEXTURE_GEN_S,
802                       ((unit->TexGenEnabled & S_BIT) ? GL_TRUE : GL_FALSE));
803      _mesa_set_enable(ctx, GL_TEXTURE_GEN_T,
804                       ((unit->TexGenEnabled & T_BIT) ? GL_TRUE : GL_FALSE));
805      _mesa_set_enable(ctx, GL_TEXTURE_GEN_R,
806                       ((unit->TexGenEnabled & R_BIT) ? GL_TRUE : GL_FALSE));
807      _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q,
808                       ((unit->TexGenEnabled & Q_BIT) ? GL_TRUE : GL_FALSE));
809      if (ctx->Extensions.EXT_texture_lod_bias) {
810         _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
811                       GL_TEXTURE_LOD_BIAS_EXT, unit->LodBias);
812      }
813      if (ctx->Extensions.EXT_texture_env_combine ||
814          ctx->Extensions.ARB_texture_env_combine) {
815         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,
816                       unit->Combine.ModeRGB);
817         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
818                       unit->Combine.ModeA);
819         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB,
820                       unit->Combine.SourceRGB[0]);
821         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB,
822                       unit->Combine.SourceRGB[1]);
823         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB,
824                       unit->Combine.SourceRGB[2]);
825         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA,
826                       unit->Combine.SourceA[0]);
827         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA,
828                       unit->Combine.SourceA[1]);
829         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA,
830                       unit->Combine.SourceA[2]);
831         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,
832                       unit->Combine.OperandRGB[0]);
833         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,
834                       unit->Combine.OperandRGB[1]);
835         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,
836                       unit->Combine.OperandRGB[2]);
837         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
838                       unit->Combine.OperandA[0]);
839         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
840                       unit->Combine.OperandA[1]);
841         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
842                       unit->Combine.OperandA[2]);
843         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE,
844                       1 << unit->Combine.ScaleShiftRGB);
845         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE,
846                       1 << unit->Combine.ScaleShiftA);
847      }
848
849      /* Restore texture object state for each target */
850      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
851         const struct gl_texture_object *obj = NULL;
852         GLenum target;
853
854         obj = &texstate->SavedObj[u][tgt];
855
856         /* don't restore state for unsupported targets to prevent
857          * raising GL errors.
858          */
859         if (obj->Target == GL_TEXTURE_CUBE_MAP_ARB &&
860             !ctx->Extensions.ARB_texture_cube_map) {
861            continue;
862         }
863         else if (obj->Target == GL_TEXTURE_RECTANGLE_NV &&
864                  !ctx->Extensions.NV_texture_rectangle) {
865            continue;
866         }
867         else if ((obj->Target == GL_TEXTURE_1D_ARRAY_EXT ||
868                   obj->Target == GL_TEXTURE_2D_ARRAY_EXT) &&
869                  !ctx->Extensions.MESA_texture_array) {
870            continue;
871         }
872
873         target = obj->Target;
874
875         _mesa_BindTexture(target, obj->Name);
876
877         _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, obj->BorderColor);
878         _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority);
879         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, obj->WrapS);
880         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, obj->WrapT);
881         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, obj->WrapR);
882         _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, obj->MinFilter);
883         _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, obj->MagFilter);
884         _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, obj->MinLod);
885         _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, obj->MaxLod);
886         _mesa_TexParameterf(target, GL_TEXTURE_LOD_BIAS, obj->LodBias);
887         _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel);
888         if (target != GL_TEXTURE_RECTANGLE_ARB)
889            _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel);
890         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
891            _mesa_TexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
892                                obj->MaxAnisotropy);
893         }
894         if (ctx->Extensions.ARB_shadow_ambient) {
895            _mesa_TexParameterf(target, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB,
896                                obj->CompareFailValue);
897         }
898      }
899
900      /* remove saved references to the texture objects */
901      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
902         _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL);
903      }
904   }
905
906   _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + texstate->Texture.CurrentUnit);
907
908   _mesa_unlock_context_textures(ctx);
909}
910
911
912/*
913 * This function is kind of long just because we have to call a lot
914 * of device driver functions to update device driver state.
915 *
916 * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions
917 * in order to restore GL state.  This isn't terribly efficient but it
918 * ensures that dirty flags and any derived state gets updated correctly.
919 * We could at least check if the value to restore equals the current value
920 * and then skip the Mesa call.
921 */
922void GLAPIENTRY
923_mesa_PopAttrib(void)
924{
925   struct gl_attrib_node *attr, *next;
926   GET_CURRENT_CONTEXT(ctx);
927   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
928
929   if (ctx->AttribStackDepth == 0) {
930      _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" );
931      return;
932   }
933
934   ctx->AttribStackDepth--;
935   attr = ctx->AttribStack[ctx->AttribStackDepth];
936
937   while (attr) {
938
939      if (MESA_VERBOSE & VERBOSE_API) {
940         _mesa_debug(ctx, "glPopAttrib %s\n",
941                     _mesa_lookup_enum_by_nr(attr->kind));
942      }
943
944      switch (attr->kind) {
945         case GL_ACCUM_BUFFER_BIT:
946            {
947               const struct gl_accum_attrib *accum;
948               accum = (const struct gl_accum_attrib *) attr->data;
949               _mesa_ClearAccum(accum->ClearColor[0],
950                                accum->ClearColor[1],
951                                accum->ClearColor[2],
952                                accum->ClearColor[3]);
953            }
954            break;
955         case GL_COLOR_BUFFER_BIT:
956            {
957               const struct gl_colorbuffer_attrib *color;
958               color = (const struct gl_colorbuffer_attrib *) attr->data;
959               _mesa_ClearIndex((GLfloat) color->ClearIndex);
960               _mesa_ClearColor(color->ClearColor[0],
961                                color->ClearColor[1],
962                                color->ClearColor[2],
963                                color->ClearColor[3]);
964               _mesa_IndexMask(color->IndexMask);
965               _mesa_ColorMask((GLboolean) (color->ColorMask[0] != 0),
966                               (GLboolean) (color->ColorMask[1] != 0),
967                               (GLboolean) (color->ColorMask[2] != 0),
968                               (GLboolean) (color->ColorMask[3] != 0));
969               {
970                  /* Need to determine if more than one color output is
971                   * specified.  If so, call glDrawBuffersARB, else call
972                   * glDrawBuffer().  This is a subtle, but essential point
973                   * since GL_FRONT (for example) is illegal for the former
974                   * function, but legal for the later.
975                   */
976                  GLboolean multipleBuffers = GL_FALSE;
977		  GLuint i;
978
979		  for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) {
980		     if (color->DrawBuffer[i] != GL_NONE) {
981			multipleBuffers = GL_TRUE;
982			break;
983		     }
984                  }
985                  /* Call the API_level functions, not _mesa_drawbuffers()
986                   * since we need to do error checking on the pop'd
987                   * GL_DRAW_BUFFER.
988                   * Ex: if GL_FRONT were pushed, but we're popping with a
989                   * user FBO bound, GL_FRONT will be illegal and we'll need
990                   * to record that error.  Per OpenGL ARB decision.
991                   */
992                  if (multipleBuffers)
993                     _mesa_DrawBuffersARB(ctx->Const.MaxDrawBuffers,
994                                          color->DrawBuffer);
995                  else
996                     _mesa_DrawBuffer(color->DrawBuffer[0]);
997               }
998               _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled);
999               _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRef);
1000               _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled);
1001               _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB,
1002                                          color->BlendDstRGB,
1003                                          color->BlendSrcA,
1004                                          color->BlendDstA);
1005	       /* This special case is because glBlendEquationSeparateEXT
1006		* cannot take GL_LOGIC_OP as a parameter.
1007		*/
1008	       if ( color->BlendEquationRGB == color->BlendEquationA ) {
1009		  _mesa_BlendEquation(color->BlendEquationRGB);
1010	       }
1011	       else {
1012		  _mesa_BlendEquationSeparateEXT(color->BlendEquationRGB,
1013						 color->BlendEquationA);
1014	       }
1015               _mesa_BlendColor(color->BlendColor[0],
1016                                color->BlendColor[1],
1017                                color->BlendColor[2],
1018                                color->BlendColor[3]);
1019               _mesa_LogicOp(color->LogicOp);
1020               _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP,
1021                                color->ColorLogicOpEnabled);
1022               _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP,
1023                                color->IndexLogicOpEnabled);
1024               _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag);
1025            }
1026            break;
1027         case GL_CURRENT_BIT:
1028	    FLUSH_CURRENT( ctx, 0 );
1029            MEMCPY( &ctx->Current, attr->data,
1030		    sizeof(struct gl_current_attrib) );
1031            break;
1032         case GL_DEPTH_BUFFER_BIT:
1033            {
1034               const struct gl_depthbuffer_attrib *depth;
1035               depth = (const struct gl_depthbuffer_attrib *) attr->data;
1036               _mesa_DepthFunc(depth->Func);
1037               _mesa_ClearDepth(depth->Clear);
1038               _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test);
1039               _mesa_DepthMask(depth->Mask);
1040            }
1041            break;
1042         case GL_ENABLE_BIT:
1043            {
1044               const struct gl_enable_attrib *enable;
1045               enable = (const struct gl_enable_attrib *) attr->data;
1046               pop_enable_group(ctx, enable);
1047	       ctx->NewState |= _NEW_ALL;
1048            }
1049            break;
1050         case GL_EVAL_BIT:
1051            MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) );
1052	    ctx->NewState |= _NEW_EVAL;
1053            break;
1054         case GL_FOG_BIT:
1055            {
1056               const struct gl_fog_attrib *fog;
1057               fog = (const struct gl_fog_attrib *) attr->data;
1058               _mesa_set_enable(ctx, GL_FOG, fog->Enabled);
1059               _mesa_Fogfv(GL_FOG_COLOR, fog->Color);
1060               _mesa_Fogf(GL_FOG_DENSITY, fog->Density);
1061               _mesa_Fogf(GL_FOG_START, fog->Start);
1062               _mesa_Fogf(GL_FOG_END, fog->End);
1063               _mesa_Fogf(GL_FOG_INDEX, fog->Index);
1064               _mesa_Fogi(GL_FOG_MODE, fog->Mode);
1065            }
1066            break;
1067         case GL_HINT_BIT:
1068            {
1069               const struct gl_hint_attrib *hint;
1070               hint = (const struct gl_hint_attrib *) attr->data;
1071               _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT,
1072                          hint->PerspectiveCorrection );
1073               _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth);
1074               _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth);
1075               _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth);
1076               _mesa_Hint(GL_FOG_HINT, hint->Fog);
1077               _mesa_Hint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT,
1078                          hint->ClipVolumeClipping);
1079	       _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB,
1080			  hint->TextureCompression);
1081            }
1082            break;
1083         case GL_LIGHTING_BIT:
1084            {
1085               GLuint i;
1086               const struct gl_light_attrib *light;
1087               light = (const struct gl_light_attrib *) attr->data;
1088               /* lighting enable */
1089               _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled);
1090               /* per-light state */
1091               if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top))
1092                  _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
1093
1094               for (i = 0; i < ctx->Const.MaxLights; i++) {
1095		  const struct gl_light *l = &light->Light[i];
1096                  _mesa_set_enable(ctx, GL_LIGHT0 + i, l->Enabled);
1097		  _mesa_light(ctx, i, GL_AMBIENT, l->Ambient);
1098		  _mesa_light(ctx, i, GL_DIFFUSE, l->Diffuse);
1099		  _mesa_light(ctx, i, GL_SPECULAR, l->Specular );
1100		  _mesa_light(ctx, i, GL_POSITION, l->EyePosition);
1101		  _mesa_light(ctx, i, GL_SPOT_DIRECTION, l->SpotDirection);
1102		  _mesa_light(ctx, i, GL_SPOT_EXPONENT, &l->SpotExponent);
1103		  _mesa_light(ctx, i, GL_SPOT_CUTOFF, &l->SpotCutoff);
1104		  _mesa_light(ctx, i, GL_CONSTANT_ATTENUATION,
1105                              &l->ConstantAttenuation);
1106		  _mesa_light(ctx, i, GL_LINEAR_ATTENUATION,
1107                              &l->LinearAttenuation);
1108		  _mesa_light(ctx, i, GL_QUADRATIC_ATTENUATION,
1109                              &l->QuadraticAttenuation);
1110               }
1111               /* light model */
1112               _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT,
1113                                  light->Model.Ambient);
1114               _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER,
1115                                 (GLfloat) light->Model.LocalViewer);
1116               _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE,
1117                                 (GLfloat) light->Model.TwoSide);
1118               _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL,
1119                                 (GLfloat) light->Model.ColorControl);
1120               /* shade model */
1121               _mesa_ShadeModel(light->ShadeModel);
1122               /* color material */
1123               _mesa_ColorMaterial(light->ColorMaterialFace,
1124                                   light->ColorMaterialMode);
1125               _mesa_set_enable(ctx, GL_COLOR_MATERIAL,
1126                                light->ColorMaterialEnabled);
1127               /* materials */
1128               MEMCPY(&ctx->Light.Material, &light->Material,
1129                      sizeof(struct gl_material));
1130            }
1131            break;
1132         case GL_LINE_BIT:
1133            {
1134               const struct gl_line_attrib *line;
1135               line = (const struct gl_line_attrib *) attr->data;
1136               _mesa_set_enable(ctx, GL_LINE_SMOOTH, line->SmoothFlag);
1137               _mesa_set_enable(ctx, GL_LINE_STIPPLE, line->StippleFlag);
1138               _mesa_LineStipple(line->StippleFactor, line->StipplePattern);
1139               _mesa_LineWidth(line->Width);
1140            }
1141            break;
1142         case GL_LIST_BIT:
1143            MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) );
1144            break;
1145         case GL_PIXEL_MODE_BIT:
1146            MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) );
1147            /* XXX what other pixel state needs to be set by function calls? */
1148            _mesa_ReadBuffer(ctx->Pixel.ReadBuffer);
1149	    ctx->NewState |= _NEW_PIXEL;
1150            break;
1151         case GL_POINT_BIT:
1152            {
1153               const struct gl_point_attrib *point;
1154               point = (const struct gl_point_attrib *) attr->data;
1155               _mesa_PointSize(point->Size);
1156               _mesa_set_enable(ctx, GL_POINT_SMOOTH, point->SmoothFlag);
1157               if (ctx->Extensions.EXT_point_parameters) {
1158                  _mesa_PointParameterfv(GL_DISTANCE_ATTENUATION_EXT,
1159                                         point->Params);
1160                  _mesa_PointParameterf(GL_POINT_SIZE_MIN_EXT,
1161                                        point->MinSize);
1162                  _mesa_PointParameterf(GL_POINT_SIZE_MAX_EXT,
1163                                        point->MaxSize);
1164                  _mesa_PointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_EXT,
1165                                        point->Threshold);
1166               }
1167               if (ctx->Extensions.NV_point_sprite
1168		   || ctx->Extensions.ARB_point_sprite) {
1169                  GLuint u;
1170                  for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
1171                     _mesa_TexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV,
1172                                   (GLint) point->CoordReplace[u]);
1173                  }
1174                  _mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite);
1175                  if (ctx->Extensions.NV_point_sprite)
1176                     _mesa_PointParameteri(GL_POINT_SPRITE_R_MODE_NV,
1177                                           ctx->Point.SpriteRMode);
1178                  _mesa_PointParameterf(GL_POINT_SPRITE_COORD_ORIGIN,
1179                                        (GLfloat)ctx->Point.SpriteOrigin);
1180               }
1181            }
1182            break;
1183         case GL_POLYGON_BIT:
1184            {
1185               const struct gl_polygon_attrib *polygon;
1186               polygon = (const struct gl_polygon_attrib *) attr->data;
1187               _mesa_CullFace(polygon->CullFaceMode);
1188               _mesa_FrontFace(polygon->FrontFace);
1189               _mesa_PolygonMode(GL_FRONT, polygon->FrontMode);
1190               _mesa_PolygonMode(GL_BACK, polygon->BackMode);
1191               _mesa_PolygonOffset(polygon->OffsetFactor,
1192                                   polygon->OffsetUnits);
1193               _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag);
1194               _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag);
1195               _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag);
1196               _mesa_set_enable(ctx, GL_POLYGON_OFFSET_POINT,
1197                                polygon->OffsetPoint);
1198               _mesa_set_enable(ctx, GL_POLYGON_OFFSET_LINE,
1199                                polygon->OffsetLine);
1200               _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL,
1201                                polygon->OffsetFill);
1202            }
1203            break;
1204	 case GL_POLYGON_STIPPLE_BIT:
1205	    MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) );
1206	    ctx->NewState |= _NEW_POLYGONSTIPPLE;
1207	    if (ctx->Driver.PolygonStipple)
1208	       ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data );
1209	    break;
1210         case GL_SCISSOR_BIT:
1211            {
1212               const struct gl_scissor_attrib *scissor;
1213               scissor = (const struct gl_scissor_attrib *) attr->data;
1214               _mesa_Scissor(scissor->X, scissor->Y,
1215                             scissor->Width, scissor->Height);
1216               _mesa_set_enable(ctx, GL_SCISSOR_TEST, scissor->Enabled);
1217            }
1218            break;
1219         case GL_STENCIL_BUFFER_BIT:
1220            {
1221               const struct gl_stencil_attrib *stencil;
1222               stencil = (const struct gl_stencil_attrib *) attr->data;
1223               _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
1224               _mesa_ClearStencil(stencil->Clear);
1225               if (ctx->Extensions.EXT_stencil_two_side) {
1226                  _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
1227                                   stencil->TestTwoSide);
1228                  _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
1229                                             ? GL_BACK : GL_FRONT);
1230               }
1231               /* front state */
1232               _mesa_StencilFuncSeparate(GL_FRONT,
1233                                         stencil->Function[0],
1234                                         stencil->Ref[0],
1235                                         stencil->ValueMask[0]);
1236               _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
1237               _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
1238                                       stencil->ZFailFunc[0],
1239                                       stencil->ZPassFunc[0]);
1240               /* back state */
1241               _mesa_StencilFuncSeparate(GL_BACK,
1242                                         stencil->Function[1],
1243                                         stencil->Ref[1],
1244                                         stencil->ValueMask[1]);
1245               _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
1246               _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
1247                                       stencil->ZFailFunc[1],
1248                                       stencil->ZPassFunc[1]);
1249            }
1250            break;
1251         case GL_TRANSFORM_BIT:
1252            {
1253               GLuint i;
1254               const struct gl_transform_attrib *xform;
1255               xform = (const struct gl_transform_attrib *) attr->data;
1256               _mesa_MatrixMode(xform->MatrixMode);
1257               if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top))
1258                  _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
1259
1260               /* restore clip planes */
1261               for (i = 0; i < MAX_CLIP_PLANES; i++) {
1262                  const GLuint mask = 1 << i;
1263                  const GLfloat *eyePlane = xform->EyeUserPlane[i];
1264                  COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane);
1265                  if (xform->ClipPlanesEnabled & mask) {
1266                     _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
1267                  }
1268                  else {
1269                     _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
1270                  }
1271                  if (ctx->Driver.ClipPlane)
1272                     ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, eyePlane );
1273               }
1274
1275               /* normalize/rescale */
1276               if (xform->Normalize != ctx->Transform.Normalize)
1277                  _mesa_set_enable(ctx, GL_NORMALIZE,ctx->Transform.Normalize);
1278               if (xform->RescaleNormals != ctx->Transform.RescaleNormals)
1279                  _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT,
1280                                   ctx->Transform.RescaleNormals);
1281            }
1282            break;
1283         case GL_TEXTURE_BIT:
1284            /* Take care of texture object reference counters */
1285            {
1286               struct texture_state *texstate
1287                  = (struct texture_state *) attr->data;
1288               pop_texture_group(ctx, texstate);
1289	       ctx->NewState |= _NEW_TEXTURE;
1290            }
1291            break;
1292         case GL_VIEWPORT_BIT:
1293            {
1294               const struct gl_viewport_attrib *vp;
1295               vp = (const struct gl_viewport_attrib *) attr->data;
1296               _mesa_Viewport(vp->X, vp->Y, vp->Width, vp->Height);
1297               _mesa_DepthRange(vp->Near, vp->Far);
1298            }
1299            break;
1300         case GL_MULTISAMPLE_BIT_ARB:
1301            {
1302               const struct gl_multisample_attrib *ms;
1303               ms = (const struct gl_multisample_attrib *) attr->data;
1304               _mesa_SampleCoverageARB(ms->SampleCoverageValue,
1305                                       ms->SampleCoverageInvert);
1306            }
1307            break;
1308
1309         default:
1310            _mesa_problem( ctx, "Bad attrib flag in PopAttrib");
1311            break;
1312      }
1313
1314      next = attr->next;
1315      FREE( attr->data );
1316      FREE( attr );
1317      attr = next;
1318   }
1319}
1320
1321
1322/**
1323 * Helper for incrementing/decrementing vertex buffer object reference
1324 * counts when pushing/popping the GL_CLIENT_VERTEX_ARRAY_BIT attribute group.
1325 */
1326static void
1327adjust_buffer_object_ref_counts(struct gl_array_object *arrayObj, GLint step)
1328{
1329   GLuint i;
1330
1331   arrayObj->Vertex.BufferObj->RefCount += step;
1332   arrayObj->Weight.BufferObj->RefCount += step;
1333   arrayObj->Normal.BufferObj->RefCount += step;
1334   arrayObj->Color.BufferObj->RefCount += step;
1335   arrayObj->SecondaryColor.BufferObj->RefCount += step;
1336   arrayObj->FogCoord.BufferObj->RefCount += step;
1337   arrayObj->Index.BufferObj->RefCount += step;
1338   arrayObj->EdgeFlag.BufferObj->RefCount += step;
1339   for (i = 0; i < Elements(arrayObj->TexCoord); i++)
1340      arrayObj->TexCoord[i].BufferObj->RefCount += step;
1341   for (i = 0; i < Elements(arrayObj->VertexAttrib); i++)
1342      arrayObj->VertexAttrib[i].BufferObj->RefCount += step;
1343}
1344
1345
1346/**
1347 * Copy gl_pixelstore_attrib from src to dst, updating buffer
1348 * object refcounts.
1349 */
1350static void
1351copy_pixelstore(GLcontext *ctx,
1352                struct gl_pixelstore_attrib *dst,
1353                const struct gl_pixelstore_attrib *src)
1354{
1355   dst->Alignment = src->Alignment;
1356   dst->RowLength = src->RowLength;
1357   dst->SkipPixels = src->SkipPixels;
1358   dst->SkipRows = src->SkipRows;
1359   dst->ImageHeight = src->ImageHeight;
1360   dst->SkipImages = src->SkipImages;
1361   dst->SwapBytes = src->SwapBytes;
1362   dst->LsbFirst = src->LsbFirst;
1363   dst->ClientStorage = src->ClientStorage;
1364   dst->Invert = src->Invert;
1365   _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
1366}
1367
1368
1369#define GL_CLIENT_PACK_BIT (1<<20)
1370#define GL_CLIENT_UNPACK_BIT (1<<21)
1371
1372
1373void GLAPIENTRY
1374_mesa_PushClientAttrib(GLbitfield mask)
1375{
1376   struct gl_attrib_node *newnode;
1377   struct gl_attrib_node *head;
1378
1379   GET_CURRENT_CONTEXT(ctx);
1380   ASSERT_OUTSIDE_BEGIN_END(ctx);
1381
1382   if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) {
1383      _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" );
1384      return;
1385   }
1386
1387   /* Build linked list of attribute nodes which save all attribute
1388    * groups specified by the mask.
1389    */
1390   head = NULL;
1391
1392   if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
1393      struct gl_pixelstore_attrib *attr;
1394      /* packing attribs */
1395      attr = CALLOC_STRUCT( gl_pixelstore_attrib );
1396      copy_pixelstore(ctx, attr, &ctx->Pack);
1397      newnode = new_attrib_node( GL_CLIENT_PACK_BIT );
1398      newnode->data = attr;
1399      newnode->next = head;
1400      head = newnode;
1401      /* unpacking attribs */
1402      attr = CALLOC_STRUCT( gl_pixelstore_attrib );
1403      copy_pixelstore(ctx, attr, &ctx->Unpack);
1404      newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT );
1405      newnode->data = attr;
1406      newnode->next = head;
1407      head = newnode;
1408   }
1409
1410   if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
1411      struct gl_array_attrib *attr;
1412      struct gl_array_object *obj;
1413
1414      attr = MALLOC_STRUCT( gl_array_attrib );
1415      obj = MALLOC_STRUCT( gl_array_object );
1416
1417#if FEATURE_ARB_vertex_buffer_object
1418      /* increment ref counts since we're copying pointers to these objects */
1419      ctx->Array.ArrayBufferObj->RefCount++;
1420      ctx->Array.ElementArrayBufferObj->RefCount++;
1421#endif
1422
1423      MEMCPY( attr, &ctx->Array, sizeof(struct gl_array_attrib) );
1424      MEMCPY( obj, ctx->Array.ArrayObj, sizeof(struct gl_array_object) );
1425
1426      attr->ArrayObj = obj;
1427
1428      newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT );
1429      newnode->data = attr;
1430      newnode->next = head;
1431      head = newnode;
1432      /* bump reference counts on buffer objects */
1433      adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, 1);
1434   }
1435
1436   ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
1437   ctx->ClientAttribStackDepth++;
1438}
1439
1440
1441
1442
1443void GLAPIENTRY
1444_mesa_PopClientAttrib(void)
1445{
1446   struct gl_attrib_node *node, *next;
1447
1448   GET_CURRENT_CONTEXT(ctx);
1449   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1450
1451   if (ctx->ClientAttribStackDepth == 0) {
1452      _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" );
1453      return;
1454   }
1455
1456   ctx->ClientAttribStackDepth--;
1457   node = ctx->ClientAttribStack[ctx->ClientAttribStackDepth];
1458
1459   while (node) {
1460      switch (node->kind) {
1461         case GL_CLIENT_PACK_BIT:
1462            {
1463               struct gl_pixelstore_attrib *store =
1464                  (struct gl_pixelstore_attrib *) node->data;
1465               copy_pixelstore(ctx, &ctx->Pack, store);
1466               _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL);
1467            }
1468	    ctx->NewState |= _NEW_PACKUNPACK;
1469            break;
1470         case GL_CLIENT_UNPACK_BIT:
1471            {
1472               struct gl_pixelstore_attrib *store =
1473                  (struct gl_pixelstore_attrib *) node->data;
1474               copy_pixelstore(ctx, &ctx->Unpack, store);
1475               _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL);
1476            }
1477	    ctx->NewState |= _NEW_PACKUNPACK;
1478            break;
1479         case GL_CLIENT_VERTEX_ARRAY_BIT: {
1480	    struct gl_array_attrib * data =
1481	      (struct gl_array_attrib *) node->data;
1482
1483            adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, -1);
1484
1485            ctx->Array.ActiveTexture = data->ActiveTexture;
1486	    if (data->LockCount != 0)
1487	       _mesa_LockArraysEXT(data->LockFirst, data->LockCount);
1488	    else if (ctx->Array.LockCount)
1489	       _mesa_UnlockArraysEXT();
1490
1491	    _mesa_BindVertexArrayAPPLE( data->ArrayObj->Name );
1492
1493#if FEATURE_ARB_vertex_buffer_object
1494            _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
1495                                data->ArrayBufferObj->Name);
1496            _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
1497                                data->ElementArrayBufferObj->Name);
1498#endif
1499
1500	    MEMCPY( ctx->Array.ArrayObj, data->ArrayObj,
1501		    sizeof( struct gl_array_object ) );
1502
1503	    FREE( data->ArrayObj );
1504
1505	    /* FIXME: Should some bits in ctx->Array->NewState also be set
1506	     * FIXME: here?  It seems like it should be set to inclusive-or
1507	     * FIXME: of the old ArrayObj->_Enabled and the new _Enabled.
1508	     */
1509
1510	    ctx->NewState |= _NEW_ARRAY;
1511            break;
1512	 }
1513         default:
1514            _mesa_problem( ctx, "Bad attrib flag in PopClientAttrib");
1515            break;
1516      }
1517
1518      next = node->next;
1519      FREE( node->data );
1520      FREE( node );
1521      node = next;
1522   }
1523}
1524
1525
1526/**
1527 * Free any attribute state data that might be attached to the context.
1528 */
1529void
1530_mesa_free_attrib_data(GLcontext *ctx)
1531{
1532   while (ctx->AttribStackDepth > 0) {
1533      struct gl_attrib_node *attr, *next;
1534
1535      ctx->AttribStackDepth--;
1536      attr = ctx->AttribStack[ctx->AttribStackDepth];
1537
1538      while (attr) {
1539         if (attr->kind == GL_TEXTURE_BIT) {
1540            struct texture_state *texstate = (struct texture_state*)attr->data;
1541            GLuint u, tgt;
1542            /* clear references to the saved texture objects */
1543            for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
1544               for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
1545                  _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL);
1546               }
1547            }
1548         }
1549         else {
1550            /* any other chunks of state that requires special handling? */
1551         }
1552
1553         next = attr->next;
1554         _mesa_free(attr->data);
1555         _mesa_free(attr);
1556         attr = next;
1557      }
1558   }
1559}
1560
1561
1562void _mesa_init_attrib( GLcontext *ctx )
1563{
1564   /* Renderer and client attribute stacks */
1565   ctx->AttribStackDepth = 0;
1566   ctx->ClientAttribStackDepth = 0;
1567}
1568