blob: ada2203ec0b4decec7ace23a070ff49f8409f784 [file] [log] [blame]
jtgafb833d1999-08-19 00:55:39 +00001/*
2 * Mesa 3-D graphics library
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00003 *
Brian Paul37c74af2008-09-04 14:58:02 -06004 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
Brian Paule9b34882008-12-31 11:54:02 -07005 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00006 *
jtgafb833d1999-08-19 00:55:39 +00007 * 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:
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000013 *
jtgafb833d1999-08-19 00:55:39 +000014 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000016 *
jtgafb833d1999-08-19 00:55:39 +000017 * 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
Kenneth Graunke3d8d5b22013-04-21 13:46:48 -070020 * 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.
jtgafb833d1999-08-19 00:55:39 +000024 */
25
Brian Paulfbd8f211999-11-11 01:22:25 +000026#include "glheader.h"
Brian Paul3c634522002-10-24 23:57:19 +000027#include "imports.h"
Brian Paulf3da3892001-01-24 15:27:10 +000028#include "accum.h"
Brian Paul0e0e3b02006-06-12 19:46:14 +000029#include "arrayobj.h"
jtgafb833d1999-08-19 00:55:39 +000030#include "attrib.h"
Brian Paulf3da3892001-01-24 15:27:10 +000031#include "blend.h"
Brian Paulea39f042000-02-02 19:17:57 +000032#include "buffers.h"
Brian Paul7a6b71e2004-03-13 18:21:40 +000033#include "bufferobj.h"
Brian Paule48defc2008-06-09 15:04:31 -060034#include "clear.h"
jtgafb833d1999-08-19 00:55:39 +000035#include "context.h"
Brian Paulf3da3892001-01-24 15:27:10 +000036#include "depth.h"
jtgafb833d1999-08-19 00:55:39 +000037#include "enable.h"
38#include "enums.h"
Brian Paulf3da3892001-01-24 15:27:10 +000039#include "fog.h"
40#include "hint.h"
41#include "light.h"
42#include "lines.h"
Vinson Leebddbdd62010-07-30 00:18:09 -070043#include "macros.h"
Brian Paul699bc7b2000-10-29 18:12:14 +000044#include "matrix.h"
Brian Paulc132e2b2008-06-09 15:09:21 -060045#include "multisample.h"
Brian Paulf3da3892001-01-24 15:27:10 +000046#include "points.h"
47#include "polygon.h"
Brian Paula1471e42012-01-31 18:24:07 -070048#include "shared.h"
Brian Paul55e341c2008-06-09 14:55:24 -060049#include "scissor.h"
Brian Paulf3da3892001-01-24 15:27:10 +000050#include "stencil.h"
Brian Paul11ebfd22008-06-11 19:58:30 -060051#include "texenv.h"
Brian Paul10db6c22008-06-11 19:48:01 -060052#include "texgen.h"
Brian Paul58cfa0f2001-08-07 23:10:55 +000053#include "texobj.h"
Brian Paulae1fdc12008-06-11 20:05:53 -060054#include "texparam.h"
jtgafb833d1999-08-19 00:55:39 +000055#include "texstate.h"
Brian3c9862d2008-03-21 13:42:36 -060056#include "varray.h"
Brian Paul2c378512009-03-07 12:33:11 -070057#include "viewport.h"
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000058#include "mtypes.h"
Chia-I Wu2cf44392010-02-24 12:01:14 +080059#include "main/dispatch.h"
Ian Romanick34c353c2012-01-20 17:23:02 -080060#include "hash.h"
61#include <stdbool.h>
Brian Paul19dff5e2009-02-12 09:21:50 -070062
jtgafb833d1999-08-19 00:55:39 +000063
Brian Paul418a7db2005-11-10 16:22:56 +000064/**
Brian Paul55399c22009-02-27 21:41:26 -070065 * 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;
Brian Paul55399c22009-02-27 21:41:26 -070074 GLboolean CullFace;
Eric Anholtb4922b52009-08-26 09:51:15 -070075 GLboolean DepthClamp;
Brian Paul55399c22009-02-27 21:41:26 -070076 GLboolean DepthTest;
77 GLboolean Dither;
78 GLboolean Fog;
Brian Paul55399c22009-02-27 21:41:26 -070079 GLboolean Light[MAX_LIGHTS];
80 GLboolean Lighting;
81 GLboolean LineSmooth;
82 GLboolean LineStipple;
83 GLboolean IndexLogicOp;
84 GLboolean ColorLogicOp;
85
86 GLboolean Map1Color4;
87 GLboolean Map1Index;
88 GLboolean Map1Normal;
89 GLboolean Map1TextureCoord1;
90 GLboolean Map1TextureCoord2;
91 GLboolean Map1TextureCoord3;
92 GLboolean Map1TextureCoord4;
93 GLboolean Map1Vertex3;
94 GLboolean Map1Vertex4;
Brian Paul55399c22009-02-27 21:41:26 -070095 GLboolean Map2Color4;
96 GLboolean Map2Index;
97 GLboolean Map2Normal;
98 GLboolean Map2TextureCoord1;
99 GLboolean Map2TextureCoord2;
100 GLboolean Map2TextureCoord3;
101 GLboolean Map2TextureCoord4;
102 GLboolean Map2Vertex3;
103 GLboolean Map2Vertex4;
Brian Paul55399c22009-02-27 21:41:26 -0700104
Brian Paul55399c22009-02-27 21:41:26 -0700105 GLboolean Normalize;
106 GLboolean PixelTexture;
107 GLboolean PointSmooth;
108 GLboolean PolygonOffsetPoint;
109 GLboolean PolygonOffsetLine;
110 GLboolean PolygonOffsetFill;
111 GLboolean PolygonSmooth;
112 GLboolean PolygonStipple;
113 GLboolean RescaleNormals;
Courtney Goeltzenleuchtera9c73fb2013-11-13 14:02:12 -0700114 GLbitfield Scissor;
Brian Paul55399c22009-02-27 21:41:26 -0700115 GLboolean Stencil;
116 GLboolean StencilTwoSide; /* GL_EXT_stencil_two_side */
117 GLboolean MultisampleEnabled; /* GL_ARB_multisample */
118 GLboolean SampleAlphaToCoverage; /* GL_ARB_multisample */
119 GLboolean SampleAlphaToOne; /* GL_ARB_multisample */
120 GLboolean SampleCoverage; /* GL_ARB_multisample */
Brian Paul55399c22009-02-27 21:41:26 -0700121 GLboolean RasterPositionUnclipped; /* GL_IBM_rasterpos_clip */
122
123 GLbitfield Texture[MAX_TEXTURE_UNITS];
124 GLbitfield TexGen[MAX_TEXTURE_UNITS];
125
Eric Anholt09c006d2012-10-09 17:08:17 -0700126 /* GL_ARB_vertex_program */
Brian Paul55399c22009-02-27 21:41:26 -0700127 GLboolean VertexProgram;
128 GLboolean VertexProgramPointSize;
129 GLboolean VertexProgramTwoSide;
130
Jordan Justen6f1538f2013-02-27 23:19:55 -0800131 /* GL_ARB_fragment_program */
132 GLboolean FragmentProgram;
133
Brian Paul55399c22009-02-27 21:41:26 -0700134 /* GL_ARB_point_sprite / GL_NV_point_sprite */
135 GLboolean PointSprite;
136 GLboolean FragmentShaderATI;
Eric Anholt4bbd1202012-08-01 12:38:56 -0700137
138 /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
139 GLboolean sRGBEnabled;
Brian Paul55399c22009-02-27 21:41:26 -0700140};
141
142
143/**
Brian Paul7f25d9e2009-02-27 22:01:40 -0700144 * Node for the attribute stack.
145 */
146struct gl_attrib_node
147{
148 GLbitfield kind;
149 void *data;
150 struct gl_attrib_node *next;
151};
152
153
154
155/**
Brian145d7622007-08-16 10:05:00 +0100156 * Special struct for saving/restoring texture state (GL_TEXTURE_BIT)
157 */
158struct texture_state
159{
160 struct gl_texture_attrib Texture; /**< The usual context state */
161
162 /** to save per texture object state (wrap modes, filters, etc): */
Brian0135ff52007-08-16 10:28:23 +0100163 struct gl_texture_object SavedObj[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS];
Brian145d7622007-08-16 10:05:00 +0100164
165 /**
166 * To save references to texture objects (so they don't get accidentally
167 * deleted while saved in the attribute stack).
168 */
Brian0135ff52007-08-16 10:28:23 +0100169 struct gl_texture_object *SavedTexRef[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS];
Brian Paula1471e42012-01-31 18:24:07 -0700170
171 /* We need to keep a reference to the shared state. That's where the
172 * default texture objects are kept. We don't want that state to be
173 * freed while the attribute stack contains pointers to any default
174 * texture objects.
175 */
176 struct gl_shared_state *SharedRef;
Brian145d7622007-08-16 10:05:00 +0100177};
178
179
Brian Paul61391952015-05-15 11:22:25 -0600180/** An unused GL_*_BIT value */
181#define DUMMY_BIT 0x10000000
182
183
Brian145d7622007-08-16 10:05:00 +0100184/**
Brian Paul101c2f92009-08-07 13:39:03 -0600185 * Allocate new attribute node of given type/kind. Attach payload data.
186 * Insert it into the linked list named by 'head'.
jtgafb833d1999-08-19 00:55:39 +0000187 */
Juha-Pekka Heikkilad08ac822013-12-16 07:04:00 -0700188static bool
Brian Paul101c2f92009-08-07 13:39:03 -0600189save_attrib_data(struct gl_attrib_node **head,
190 GLbitfield kind, void *payload)
jtgafb833d1999-08-19 00:55:39 +0000191{
Brian Paul101c2f92009-08-07 13:39:03 -0600192 struct gl_attrib_node *n = MALLOC_STRUCT(gl_attrib_node);
193 if (n) {
194 n->kind = kind;
195 n->data = payload;
196 /* insert at head */
197 n->next = *head;
198 *head = n;
jtgafb833d1999-08-19 00:55:39 +0000199 }
Brian Paul101c2f92009-08-07 13:39:03 -0600200 else {
201 /* out of memory! */
Juha-Pekka Heikkilad08ac822013-12-16 07:04:00 -0700202 return false;
Brian Paul101c2f92009-08-07 13:39:03 -0600203 }
Juha-Pekka Heikkilad08ac822013-12-16 07:04:00 -0700204 return true;
jtgafb833d1999-08-19 00:55:39 +0000205}
206
207
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700208/**
209 * Helper function for_mesa_PushAttrib for simple attributes.
210 * Allocates memory for attribute data and copies the given attribute data.
211 * \param head head of linked list to insert attribute data into
212 * \param attr_bit one of the GL_<attrib>_BIT flags
213 * \param attr_size number of bytes to allocate for attribute data
214 * \param attr_data the attribute data to copy
215 * \return true for success, false for out of memory
216 */
217static bool
218push_attrib(struct gl_context *ctx, struct gl_attrib_node **head,
219 GLbitfield attr_bit, GLuint attr_size, const void *attr_data)
220{
221 void *attribute;
222
Brian Paul7fbb8ba2014-04-09 19:27:06 -0600223 attribute = malloc(attr_size);
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700224 if (attribute == NULL) {
225 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
226 return false;
227 }
228
229 if (save_attrib_data(head, attr_bit, attribute)) {
230 memcpy(attribute, attr_data, attr_size);
231 }
232 else {
Brian Paul7fbb8ba2014-04-09 19:27:06 -0600233 free(attribute);
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700234 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
235 return false;
236 }
237 return true;
238}
239
240
Kendall Bennettc40d1dd2003-10-21 22:22:17 +0000241void GLAPIENTRY
Brian Paul42fcf032000-02-02 22:03:31 +0000242_mesa_PushAttrib(GLbitfield mask)
jtgafb833d1999-08-19 00:55:39 +0000243{
jtgafb833d1999-08-19 00:55:39 +0000244 struct gl_attrib_node *head;
245
Brian Paul42fcf032000-02-02 22:03:31 +0000246 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000247
Brian Paul9a33a112002-06-13 04:28:29 +0000248 if (MESA_VERBOSE & VERBOSE_API)
Brian Paul4753d602002-06-15 02:38:15 +0000249 _mesa_debug(ctx, "glPushAttrib %x\n", (int) mask);
jtgafb833d1999-08-19 00:55:39 +0000250
Brian Paulf3da3892001-01-24 15:27:10 +0000251 if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) {
Brian Paul08836342001-03-03 20:33:27 +0000252 _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" );
jtgafb833d1999-08-19 00:55:39 +0000253 return;
254 }
255
256 /* Build linked list of attribute nodes which save all attribute */
257 /* groups specified by the mask. */
258 head = NULL;
259
Brian Paul61391952015-05-15 11:22:25 -0600260 if (mask == 0) {
261 /* if mask is zero we still need to push something so that we
262 * don't get a GL_STACK_UNDERFLOW error in glPopAttrib().
263 */
264 GLuint dummy = 0;
265 if (!push_attrib(ctx, &head, DUMMY_BIT, sizeof(dummy), &dummy))
266 goto end;
267 }
268
jtgafb833d1999-08-19 00:55:39 +0000269 if (mask & GL_ACCUM_BUFFER_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700270 if (!push_attrib(ctx, &head, GL_ACCUM_BUFFER_BIT,
271 sizeof(struct gl_accum_attrib),
272 (void*)&ctx->Accum))
273 goto end;
jtgafb833d1999-08-19 00:55:39 +0000274 }
275
276 if (mask & GL_COLOR_BUFFER_BIT) {
Roland Scheideggera1bc0d02007-07-18 20:17:14 +0200277 GLuint i;
jtgafb833d1999-08-19 00:55:39 +0000278 struct gl_colorbuffer_attrib *attr;
Brian Paulbd5cdaf1999-10-13 18:42:49 +0000279 attr = MALLOC_STRUCT( gl_colorbuffer_attrib );
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700280 if (attr == NULL) {
281 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
282 goto end;
283 }
284
285 if (save_attrib_data(&head, GL_COLOR_BUFFER_BIT, attr)) {
286 memcpy(attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib));
287 /* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */
288 for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++)
289 attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i];
290 }
291 else {
Brian Paul7fbb8ba2014-04-09 19:27:06 -0600292 free(attr);
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700293 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
294 goto end;
295 }
jtgafb833d1999-08-19 00:55:39 +0000296 }
297
298 if (mask & GL_CURRENT_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700299 FLUSH_CURRENT(ctx, 0);
300 if (!push_attrib(ctx, &head, GL_CURRENT_BIT,
301 sizeof(struct gl_current_attrib),
302 (void*)&ctx->Current))
303 goto end;
jtgafb833d1999-08-19 00:55:39 +0000304 }
305
306 if (mask & GL_DEPTH_BUFFER_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700307 if (!push_attrib(ctx, &head, GL_DEPTH_BUFFER_BIT,
308 sizeof(struct gl_depthbuffer_attrib),
309 (void*)&ctx->Depth))
310 goto end;
jtgafb833d1999-08-19 00:55:39 +0000311 }
312
313 if (mask & GL_ENABLE_BIT) {
314 struct gl_enable_attrib *attr;
315 GLuint i;
Brian Paulbd5cdaf1999-10-13 18:42:49 +0000316 attr = MALLOC_STRUCT( gl_enable_attrib );
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700317 if (attr == NULL) {
318 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
319 goto end;
320 }
321
jtgafb833d1999-08-19 00:55:39 +0000322 /* Copy enable flags from all other attributes into the enable struct. */
323 attr->AlphaTest = ctx->Color.AlphaEnabled;
324 attr->AutoNormal = ctx->Eval.AutoNormal;
325 attr->Blend = ctx->Color.BlendEnabled;
Brian Paul103bc0f2002-03-29 17:27:59 +0000326 attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled;
jtgafb833d1999-08-19 00:55:39 +0000327 attr->ColorMaterial = ctx->Light.ColorMaterialEnabled;
328 attr->CullFace = ctx->Polygon.CullFlag;
Eric Anholtb4922b52009-08-26 09:51:15 -0700329 attr->DepthClamp = ctx->Transform.DepthClamp;
jtgafb833d1999-08-19 00:55:39 +0000330 attr->DepthTest = ctx->Depth.Test;
331 attr->Dither = ctx->Color.DitherFlag;
332 attr->Fog = ctx->Fog.Enabled;
Brian Paul418a7db2005-11-10 16:22:56 +0000333 for (i = 0; i < ctx->Const.MaxLights; i++) {
jtgafb833d1999-08-19 00:55:39 +0000334 attr->Light[i] = ctx->Light.Light[i].Enabled;
335 }
336 attr->Lighting = ctx->Light.Enabled;
337 attr->LineSmooth = ctx->Line.SmoothFlag;
338 attr->LineStipple = ctx->Line.StippleFlag;
339 attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled;
340 attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled;
341 attr->Map1Color4 = ctx->Eval.Map1Color4;
342 attr->Map1Index = ctx->Eval.Map1Index;
343 attr->Map1Normal = ctx->Eval.Map1Normal;
344 attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1;
345 attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2;
346 attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3;
347 attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4;
348 attr->Map1Vertex3 = ctx->Eval.Map1Vertex3;
349 attr->Map1Vertex4 = ctx->Eval.Map1Vertex4;
350 attr->Map2Color4 = ctx->Eval.Map2Color4;
351 attr->Map2Index = ctx->Eval.Map2Index;
352 attr->Map2Normal = ctx->Eval.Map2Normal;
353 attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1;
354 attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2;
355 attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3;
356 attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4;
357 attr->Map2Vertex3 = ctx->Eval.Map2Vertex3;
358 attr->Map2Vertex4 = ctx->Eval.Map2Vertex4;
359 attr->Normalize = ctx->Transform.Normalize;
Brian Paul8c2f6c52001-06-26 01:32:48 +0000360 attr->RasterPositionUnclipped = ctx->Transform.RasterPositionUnclipped;
jtgafb833d1999-08-19 00:55:39 +0000361 attr->PointSmooth = ctx->Point.SmoothFlag;
Brian Paul112f7cd2002-06-07 16:01:03 +0000362 attr->PointSprite = ctx->Point.PointSprite;
jtgafb833d1999-08-19 00:55:39 +0000363 attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint;
364 attr->PolygonOffsetLine = ctx->Polygon.OffsetLine;
365 attr->PolygonOffsetFill = ctx->Polygon.OffsetFill;
366 attr->PolygonSmooth = ctx->Polygon.SmoothFlag;
367 attr->PolygonStipple = ctx->Polygon.StippleFlag;
368 attr->RescaleNormals = ctx->Transform.RescaleNormals;
Courtney Goeltzenleuchtera9c73fb2013-11-13 14:02:12 -0700369 attr->Scissor = ctx->Scissor.EnableFlags;
jtgafb833d1999-08-19 00:55:39 +0000370 attr->Stencil = ctx->Stencil.Enabled;
Daniel Borcaf76be3d2004-11-22 08:46:53 +0000371 attr->StencilTwoSide = ctx->Stencil.TestTwoSide;
Brian Paul736fcbe2001-05-29 15:23:48 +0000372 attr->MultisampleEnabled = ctx->Multisample.Enabled;
373 attr->SampleAlphaToCoverage = ctx->Multisample.SampleAlphaToCoverage;
374 attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne;
375 attr->SampleCoverage = ctx->Multisample.SampleCoverage;
Brian Paule9b34882008-12-31 11:54:02 -0700376 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
Brian Pauleb6c6432000-09-28 22:44:30 +0000377 attr->Texture[i] = ctx->Texture.Unit[i].Enabled;
jtgafb833d1999-08-19 00:55:39 +0000378 attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled;
379 }
Eric Anholt09c006d2012-10-09 17:08:17 -0700380 /* GL_ARB_vertex_program */
Brian Paul86b84272001-12-14 02:50:01 +0000381 attr->VertexProgram = ctx->VertexProgram.Enabled;
382 attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled;
383 attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled;
Jordan Justen6f1538f2013-02-27 23:19:55 -0800384
385 /* GL_ARB_fragment_program */
386 attr->FragmentProgram = ctx->FragmentProgram.Enabled;
387
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700388 if (!save_attrib_data(&head, GL_ENABLE_BIT, attr)) {
Brian Paul7fbb8ba2014-04-09 19:27:06 -0600389 free(attr);
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700390 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
391 goto end;
392 }
Eric Anholt4bbd1202012-08-01 12:38:56 -0700393
394 /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
395 attr->sRGBEnabled = ctx->Color.sRGBEnabled;
jtgafb833d1999-08-19 00:55:39 +0000396 }
397
398 if (mask & GL_EVAL_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700399 if (!push_attrib(ctx, &head, GL_EVAL_BIT,
400 sizeof(struct gl_eval_attrib),
401 (void*)&ctx->Eval))
402 goto end;
jtgafb833d1999-08-19 00:55:39 +0000403 }
404
405 if (mask & GL_FOG_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700406 if (!push_attrib(ctx, &head, GL_FOG_BIT,
407 sizeof(struct gl_fog_attrib),
408 (void*)&ctx->Fog))
409 goto end;
jtgafb833d1999-08-19 00:55:39 +0000410 }
411
412 if (mask & GL_HINT_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700413 if (!push_attrib(ctx, &head, GL_HINT_BIT,
414 sizeof(struct gl_hint_attrib),
415 (void*)&ctx->Hint))
416 goto end;
jtgafb833d1999-08-19 00:55:39 +0000417 }
418
419 if (mask & GL_LIGHTING_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700420 FLUSH_CURRENT(ctx, 0); /* flush material changes */
421 if (!push_attrib(ctx, &head, GL_LIGHTING_BIT,
422 sizeof(struct gl_light_attrib),
423 (void*)&ctx->Light))
424 goto end;
jtgafb833d1999-08-19 00:55:39 +0000425 }
426
427 if (mask & GL_LINE_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700428 if (!push_attrib(ctx, &head, GL_LINE_BIT,
429 sizeof(struct gl_line_attrib),
430 (void*)&ctx->Line))
431 goto end;
jtgafb833d1999-08-19 00:55:39 +0000432 }
433
434 if (mask & GL_LIST_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700435 if (!push_attrib(ctx, &head, GL_LIST_BIT,
436 sizeof(struct gl_list_attrib),
437 (void*)&ctx->List))
438 goto end;
jtgafb833d1999-08-19 00:55:39 +0000439 }
440
441 if (mask & GL_PIXEL_MODE_BIT) {
442 struct gl_pixel_attrib *attr;
Brian Paulbd5cdaf1999-10-13 18:42:49 +0000443 attr = MALLOC_STRUCT( gl_pixel_attrib );
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700444 if (attr == NULL) {
445 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
446 goto end;
447 }
448
449 if (save_attrib_data(&head, GL_PIXEL_MODE_BIT, attr)) {
450 memcpy(attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib));
451 /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */
452 attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer;
453 }
454 else {
Brian Paul7fbb8ba2014-04-09 19:27:06 -0600455 free(attr);
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700456 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
457 goto end;
458 }
jtgafb833d1999-08-19 00:55:39 +0000459 }
460
461 if (mask & GL_POINT_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700462 if (!push_attrib(ctx, &head, GL_POINT_BIT,
463 sizeof(struct gl_point_attrib),
464 (void*)&ctx->Point))
465 goto end;
jtgafb833d1999-08-19 00:55:39 +0000466 }
467
468 if (mask & GL_POLYGON_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700469 if (!push_attrib(ctx, &head, GL_POLYGON_BIT,
470 sizeof(struct gl_polygon_attrib),
471 (void*)&ctx->Polygon))
472 goto end;
jtgafb833d1999-08-19 00:55:39 +0000473 }
474
475 if (mask & GL_POLYGON_STIPPLE_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700476 if (!push_attrib(ctx, &head, GL_POLYGON_STIPPLE_BIT,
477 sizeof(ctx->PolygonStipple),
478 (void*)&ctx->PolygonStipple))
479 goto end;
jtgafb833d1999-08-19 00:55:39 +0000480 }
481
482 if (mask & GL_SCISSOR_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700483 if (!push_attrib(ctx, &head, GL_SCISSOR_BIT,
484 sizeof(struct gl_scissor_attrib),
485 (void*)&ctx->Scissor))
486 goto end;
jtgafb833d1999-08-19 00:55:39 +0000487 }
488
489 if (mask & GL_STENCIL_BUFFER_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700490 if (!push_attrib(ctx, &head, GL_STENCIL_BUFFER_BIT,
491 sizeof(struct gl_stencil_attrib),
492 (void*)&ctx->Stencil))
493 goto end;
jtgafb833d1999-08-19 00:55:39 +0000494 }
495
496 if (mask & GL_TEXTURE_BIT) {
Brian145d7622007-08-16 10:05:00 +0100497 struct texture_state *texstate = CALLOC_STRUCT(texture_state);
Brian Paul98187342009-02-21 14:53:25 -0700498 GLuint u, tex;
Keith Whitwell5ac93f82006-11-01 14:21:57 +0000499
Brian145d7622007-08-16 10:05:00 +0100500 if (!texstate) {
501 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)");
502 goto end;
jtgafb833d1999-08-19 00:55:39 +0000503 }
Brian9e01b912007-08-13 11:29:46 +0100504
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700505 if (!save_attrib_data(&head, GL_TEXTURE_BIT, texstate)) {
Brian Paul7fbb8ba2014-04-09 19:27:06 -0600506 free(texstate);
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700507 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)");
508 goto end;
509 }
510
Brian145d7622007-08-16 10:05:00 +0100511 _mesa_lock_context_textures(ctx);
512
513 /* copy/save the bulk of texture state here */
Kenneth Graunkec7ac48622010-02-18 23:50:59 -0800514 memcpy(&texstate->Texture, &ctx->Texture, sizeof(ctx->Texture));
Brian145d7622007-08-16 10:05:00 +0100515
516 /* Save references to the currently bound texture objects so they don't
517 * accidentally get deleted while referenced in the attribute stack.
518 */
jtgafb833d1999-08-19 00:55:39 +0000519 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
Brian Paul98187342009-02-21 14:53:25 -0700520 for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
521 _mesa_reference_texobj(&texstate->SavedTexRef[u][tex],
522 ctx->Texture.Unit[u].CurrentTex[tex]);
523 }
Brian145d7622007-08-16 10:05:00 +0100524 }
525
526 /* copy state/contents of the currently bound texture objects */
527 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
Brian Paul98187342009-02-21 14:53:25 -0700528 for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
529 _mesa_copy_texture_object(&texstate->SavedObj[u][tex],
530 ctx->Texture.Unit[u].CurrentTex[tex]);
531 }
jtgafb833d1999-08-19 00:55:39 +0000532 }
Keith Whitwell5ac93f82006-11-01 14:21:57 +0000533
Brian Paula1471e42012-01-31 18:24:07 -0700534 _mesa_reference_shared_state(ctx, &texstate->SharedRef, ctx->Shared);
535
Keith Whitwell5ac93f82006-11-01 14:21:57 +0000536 _mesa_unlock_context_textures(ctx);
jtgafb833d1999-08-19 00:55:39 +0000537 }
538
539 if (mask & GL_TRANSFORM_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700540 if (!push_attrib(ctx, &head, GL_TRANSFORM_BIT,
541 sizeof(struct gl_transform_attrib),
542 (void*)&ctx->Transform))
543 goto end;
jtgafb833d1999-08-19 00:55:39 +0000544 }
545
546 if (mask & GL_VIEWPORT_BIT) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700547 if (!push_attrib(ctx, &head, GL_VIEWPORT_BIT,
Courtney Goeltzenleuchtercbb271a2013-11-13 16:24:56 -0700548 sizeof(struct gl_viewport_attrib)
549 * ctx->Const.MaxViewports,
550 (void*)&ctx->ViewportArray))
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700551 goto end;
jtgafb833d1999-08-19 00:55:39 +0000552 }
553
Brian Paul736fcbe2001-05-29 15:23:48 +0000554 /* GL_ARB_multisample */
555 if (mask & GL_MULTISAMPLE_BIT_ARB) {
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700556 if (!push_attrib(ctx, &head, GL_MULTISAMPLE_BIT_ARB,
557 sizeof(struct gl_multisample_attrib),
558 (void*)&ctx->Multisample))
559 goto end;
Brian Paul736fcbe2001-05-29 15:23:48 +0000560 }
561
Brian145d7622007-08-16 10:05:00 +0100562end:
Juha-Pekka Heikkila56c5ba82013-12-16 07:04:00 -0700563 if (head != NULL) {
564 ctx->AttribStack[ctx->AttribStackDepth] = head;
565 ctx->AttribStackDepth++;
566 }
jtgafb833d1999-08-19 00:55:39 +0000567}
568
569
570
Brian Pauleb6c6432000-09-28 22:44:30 +0000571static void
Kristian Høgsbergf9995b32010-10-12 12:26:10 -0400572pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable)
Brian Pauleb6c6432000-09-28 22:44:30 +0000573{
Brian Paulaac19602009-05-21 10:05:04 -0600574 const GLuint curTexUnitSave = ctx->Texture.CurrentUnit;
Brian Pauleb6c6432000-09-28 22:44:30 +0000575 GLuint i;
576
577#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) \
578 if ((VALUE) != (NEWVALUE)) { \
579 _mesa_set_enable( ctx, ENUM, (NEWVALUE) ); \
580 }
581
582 TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST);
Brian Paul37286732009-12-29 15:04:03 -0700583 if (ctx->Color.BlendEnabled != enable->Blend) {
Brian Paul1677d5c2009-12-29 23:04:27 -0700584 if (ctx->Extensions.EXT_draw_buffers2) {
585 GLuint i;
586 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
587 _mesa_set_enablei(ctx, GL_BLEND, i, (enable->Blend >> i) & 1);
588 }
589 }
590 else {
591 _mesa_set_enable(ctx, GL_BLEND, (enable->Blend & 1));
Brian Paul37286732009-12-29 15:04:03 -0700592 }
593 }
Brian Pauleb6c6432000-09-28 22:44:30 +0000594
Paul Berry27bdc762011-09-07 17:44:28 -0700595 for (i=0;i<ctx->Const.MaxClipPlanes;i++) {
Brian Paul103bc0f2002-03-29 17:27:59 +0000596 const GLuint mask = 1 << i;
597 if ((ctx->Transform.ClipPlanesEnabled & mask) != (enable->ClipPlanes & mask))
Karl Schultz798d83c2002-10-17 22:26:06 +0000598 _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i),
Brian Paulb15ab1d2011-09-30 21:03:42 -0600599 !!(enable->ClipPlanes & mask));
Brian Pauleb6c6432000-09-28 22:44:30 +0000600 }
601
602 TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial,
603 GL_COLOR_MATERIAL);
604 TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
Eric Anholtb4922b52009-08-26 09:51:15 -0700605 TEST_AND_UPDATE(ctx->Transform.DepthClamp, enable->DepthClamp,
606 GL_DEPTH_CLAMP);
Brian Pauleb6c6432000-09-28 22:44:30 +0000607 TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST);
608 TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER);
Brian Pauleb6c6432000-09-28 22:44:30 +0000609 TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG);
610 TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING);
611 TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH);
612 TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple,
613 GL_LINE_STIPPLE);
614 TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp,
615 GL_INDEX_LOGIC_OP);
616 TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp,
617 GL_COLOR_LOGIC_OP);
Brian Paulbc42c192002-01-05 21:53:20 +0000618
Brian Pauleb6c6432000-09-28 22:44:30 +0000619 TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4);
620 TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX);
621 TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL);
622 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1,
623 GL_MAP1_TEXTURE_COORD_1);
624 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2,
625 GL_MAP1_TEXTURE_COORD_2);
626 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3,
627 GL_MAP1_TEXTURE_COORD_3);
628 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4,
629 GL_MAP1_TEXTURE_COORD_4);
630 TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3,
631 GL_MAP1_VERTEX_3);
632 TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4,
633 GL_MAP1_VERTEX_4);
Brian Paulbc42c192002-01-05 21:53:20 +0000634
Brian Pauleb6c6432000-09-28 22:44:30 +0000635 TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4);
636 TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX);
637 TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL);
638 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1,
639 GL_MAP2_TEXTURE_COORD_1);
640 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2,
641 GL_MAP2_TEXTURE_COORD_2);
642 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3,
643 GL_MAP2_TEXTURE_COORD_3);
644 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4,
645 GL_MAP2_TEXTURE_COORD_4);
646 TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3,
647 GL_MAP2_VERTEX_3);
648 TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4,
649 GL_MAP2_VERTEX_4);
Brian Paulbc42c192002-01-05 21:53:20 +0000650
Brian Paul8c2f6c52001-06-26 01:32:48 +0000651 TEST_AND_UPDATE(ctx->Eval.AutoNormal, enable->AutoNormal, GL_AUTO_NORMAL);
Brian Pauleb6c6432000-09-28 22:44:30 +0000652 TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE);
653 TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals,
654 GL_RESCALE_NORMAL_EXT);
Brian Paul8c2f6c52001-06-26 01:32:48 +0000655 TEST_AND_UPDATE(ctx->Transform.RasterPositionUnclipped,
656 enable->RasterPositionUnclipped,
657 GL_RASTER_POSITION_UNCLIPPED_IBM);
Brian Pauleb6c6432000-09-28 22:44:30 +0000658 TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth,
659 GL_POINT_SMOOTH);
Ian Romanick63736722003-08-23 00:12:46 +0000660 if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) {
Brian Paul6c408b42002-05-27 17:04:52 +0000661 TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite,
662 GL_POINT_SPRITE_NV);
663 }
Brian Pauleb6c6432000-09-28 22:44:30 +0000664 TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint,
665 GL_POLYGON_OFFSET_POINT);
666 TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine,
667 GL_POLYGON_OFFSET_LINE);
668 TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill,
669 GL_POLYGON_OFFSET_FILL);
670 TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth,
671 GL_POLYGON_SMOOTH);
672 TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple,
673 GL_POLYGON_STIPPLE);
Courtney Goeltzenleuchtera9c73fb2013-11-13 14:02:12 -0700674 if (ctx->Scissor.EnableFlags != enable->Scissor) {
675 unsigned i;
676
677 for (i = 0; i < ctx->Const.MaxViewports; i++) {
678 _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i, (enable->Scissor >> i) & 1);
679 }
680 }
Brian Pauleb6c6432000-09-28 22:44:30 +0000681 TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST);
Daniel Borcaf76be3d2004-11-22 08:46:53 +0000682 if (ctx->Extensions.EXT_stencil_two_side) {
683 TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, enable->StencilTwoSide, GL_STENCIL_TEST_TWO_SIDE_EXT);
684 }
Brian Paul736fcbe2001-05-29 15:23:48 +0000685 TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled,
686 GL_MULTISAMPLE_ARB);
687 TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage,
688 enable->SampleAlphaToCoverage,
689 GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
690 TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne,
691 enable->SampleAlphaToOne,
692 GL_SAMPLE_ALPHA_TO_ONE_ARB);
693 TEST_AND_UPDATE(ctx->Multisample.SampleCoverage,
694 enable->SampleCoverage,
695 GL_SAMPLE_COVERAGE_ARB);
Eric Anholt09c006d2012-10-09 17:08:17 -0700696 /* GL_ARB_vertex_program */
Brian Paul86b84272001-12-14 02:50:01 +0000697 TEST_AND_UPDATE(ctx->VertexProgram.Enabled,
698 enable->VertexProgram,
Roland Scheideggere1e03b32006-03-03 15:03:04 +0000699 GL_VERTEX_PROGRAM_ARB);
Brian Paul86b84272001-12-14 02:50:01 +0000700 TEST_AND_UPDATE(ctx->VertexProgram.PointSizeEnabled,
701 enable->VertexProgramPointSize,
Roland Scheideggere1e03b32006-03-03 15:03:04 +0000702 GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
Brian Paul86b84272001-12-14 02:50:01 +0000703 TEST_AND_UPDATE(ctx->VertexProgram.TwoSideEnabled,
704 enable->VertexProgramTwoSide,
Roland Scheideggere1e03b32006-03-03 15:03:04 +0000705 GL_VERTEX_PROGRAM_TWO_SIDE_ARB);
Brian Paul86b84272001-12-14 02:50:01 +0000706
Jordan Justen6f1538f2013-02-27 23:19:55 -0800707 /* GL_ARB_fragment_program */
708 TEST_AND_UPDATE(ctx->FragmentProgram.Enabled,
709 enable->FragmentProgram,
710 GL_FRAGMENT_PROGRAM_ARB);
711
Eric Anholt4bbd1202012-08-01 12:38:56 -0700712 /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
713 TEST_AND_UPDATE(ctx->Color.sRGBEnabled, enable->sRGBEnabled,
714 GL_FRAMEBUFFER_SRGB);
715
Brian Pauleb6c6432000-09-28 22:44:30 +0000716 /* texture unit enables */
717 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
Brian Paulaac19602009-05-21 10:05:04 -0600718 const GLbitfield enabled = enable->Texture[i];
719 const GLbitfield genEnabled = enable->TexGen[i];
720
721 if (ctx->Texture.Unit[i].Enabled != enabled) {
Paul Berry1a1db172012-11-06 08:57:59 -0800722 _mesa_ActiveTexture(GL_TEXTURE0 + i);
Brian Paulaac19602009-05-21 10:05:04 -0600723
Brian Paulb15ab1d2011-09-30 21:03:42 -0600724 _mesa_set_enable(ctx, GL_TEXTURE_1D, !!(enabled & TEXTURE_1D_BIT));
725 _mesa_set_enable(ctx, GL_TEXTURE_2D, !!(enabled & TEXTURE_2D_BIT));
726 _mesa_set_enable(ctx, GL_TEXTURE_3D, !!(enabled & TEXTURE_3D_BIT));
Brian Paulaac19602009-05-21 10:05:04 -0600727 if (ctx->Extensions.NV_texture_rectangle) {
728 _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_ARB,
Brian Paulb15ab1d2011-09-30 21:03:42 -0600729 !!(enabled & TEXTURE_RECT_BIT));
Brian Paulaac19602009-05-21 10:05:04 -0600730 }
731 if (ctx->Extensions.ARB_texture_cube_map) {
732 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP,
Brian Paulb15ab1d2011-09-30 21:03:42 -0600733 !!(enabled & TEXTURE_CUBE_BIT));
Brian Paulaac19602009-05-21 10:05:04 -0600734 }
Brian Pauleb6c6432000-09-28 22:44:30 +0000735 }
736
Brian Paulaac19602009-05-21 10:05:04 -0600737 if (ctx->Texture.Unit[i].TexGenEnabled != genEnabled) {
Paul Berry1a1db172012-11-06 08:57:59 -0800738 _mesa_ActiveTexture(GL_TEXTURE0 + i);
Brian Paulb15ab1d2011-09-30 21:03:42 -0600739 _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, !!(genEnabled & S_BIT));
740 _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, !!(genEnabled & T_BIT));
741 _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, !!(genEnabled & R_BIT));
742 _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, !!(genEnabled & Q_BIT));
Brian Pauleb6c6432000-09-28 22:44:30 +0000743 }
744 }
745
Paul Berry1a1db172012-11-06 08:57:59 -0800746 _mesa_ActiveTexture(GL_TEXTURE0 + curTexUnitSave);
Brian Pauleb6c6432000-09-28 22:44:30 +0000747}
748
749
Brian145d7622007-08-16 10:05:00 +0100750/**
751 * Pop/restore texture attribute/group state.
752 */
Brian Paul93de8d32001-04-11 23:22:20 +0000753static void
Kristian Høgsbergf9995b32010-10-12 12:26:10 -0400754pop_texture_group(struct gl_context *ctx, struct texture_state *texstate)
Brian Paul93de8d32001-04-11 23:22:20 +0000755{
756 GLuint u;
757
Brian145d7622007-08-16 10:05:00 +0100758 _mesa_lock_context_textures(ctx);
759
Brian Paul93de8d32001-04-11 23:22:20 +0000760 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
Brian145d7622007-08-16 10:05:00 +0100761 const struct gl_texture_unit *unit = &texstate->Texture.Unit[u];
762 GLuint tgt;
Brian Paul93de8d32001-04-11 23:22:20 +0000763
Paul Berry1a1db172012-11-06 08:57:59 -0800764 _mesa_ActiveTexture(GL_TEXTURE0_ARB + u);
Brian Paulb15ab1d2011-09-30 21:03:42 -0600765 _mesa_set_enable(ctx, GL_TEXTURE_1D, !!(unit->Enabled & TEXTURE_1D_BIT));
766 _mesa_set_enable(ctx, GL_TEXTURE_2D, !!(unit->Enabled & TEXTURE_2D_BIT));
767 _mesa_set_enable(ctx, GL_TEXTURE_3D, !!(unit->Enabled & TEXTURE_3D_BIT));
Brian Paul93de8d32001-04-11 23:22:20 +0000768 if (ctx->Extensions.ARB_texture_cube_map) {
Brian Paul6a086732016-02-11 07:45:50 -0700769 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP,
Brian Paulb15ab1d2011-09-30 21:03:42 -0600770 !!(unit->Enabled & TEXTURE_CUBE_BIT));
Brian Paul8afe7de2002-06-15 03:03:06 +0000771 }
772 if (ctx->Extensions.NV_texture_rectangle) {
773 _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_NV,
Brian Paulb15ab1d2011-09-30 21:03:42 -0600774 !!(unit->Enabled & TEXTURE_RECT_BIT));
Brian Paul93de8d32001-04-11 23:22:20 +0000775 }
776 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode);
777 _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor);
Brian Paul9705cff2009-02-21 13:23:04 -0700778 _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenS.Mode);
779 _mesa_TexGeni(GL_T, GL_TEXTURE_GEN_MODE, unit->GenT.Mode);
780 _mesa_TexGeni(GL_R, GL_TEXTURE_GEN_MODE, unit->GenR.Mode);
781 _mesa_TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, unit->GenQ.Mode);
782 _mesa_TexGenfv(GL_S, GL_OBJECT_PLANE, unit->GenS.ObjectPlane);
783 _mesa_TexGenfv(GL_T, GL_OBJECT_PLANE, unit->GenT.ObjectPlane);
784 _mesa_TexGenfv(GL_R, GL_OBJECT_PLANE, unit->GenR.ObjectPlane);
785 _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->GenQ.ObjectPlane);
Brian Paula8446f72005-11-09 16:52:21 +0000786 /* Eye plane done differently to avoid re-transformation */
787 {
788 struct gl_texture_unit *destUnit = &ctx->Texture.Unit[u];
Brian Paul9705cff2009-02-21 13:23:04 -0700789 COPY_4FV(destUnit->GenS.EyePlane, unit->GenS.EyePlane);
790 COPY_4FV(destUnit->GenT.EyePlane, unit->GenT.EyePlane);
791 COPY_4FV(destUnit->GenR.EyePlane, unit->GenR.EyePlane);
792 COPY_4FV(destUnit->GenQ.EyePlane, unit->GenQ.EyePlane);
Brian Paula8446f72005-11-09 16:52:21 +0000793 if (ctx->Driver.TexGen) {
Brian Paul9705cff2009-02-21 13:23:04 -0700794 ctx->Driver.TexGen(ctx, GL_S, GL_EYE_PLANE, unit->GenS.EyePlane);
795 ctx->Driver.TexGen(ctx, GL_T, GL_EYE_PLANE, unit->GenT.EyePlane);
796 ctx->Driver.TexGen(ctx, GL_R, GL_EYE_PLANE, unit->GenR.EyePlane);
797 ctx->Driver.TexGen(ctx, GL_Q, GL_EYE_PLANE, unit->GenQ.EyePlane);
Brian Paula8446f72005-11-09 16:52:21 +0000798 }
799 }
Brian Paulb15ab1d2011-09-30 21:03:42 -0600800 _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, !!(unit->TexGenEnabled & S_BIT));
801 _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, !!(unit->TexGenEnabled & T_BIT));
802 _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, !!(unit->TexGenEnabled & R_BIT));
803 _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, !!(unit->TexGenEnabled & Q_BIT));
Ian Romanickf9a23522011-08-30 17:33:51 -0700804 _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS,
805 unit->LodBias);
Ian Romanickbde8bd92011-08-30 17:24:13 -0700806 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,
807 unit->Combine.ModeRGB);
808 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
809 unit->Combine.ModeA);
Brian Paul986a9bb2011-09-30 21:03:42 -0600810 {
Brian Pauldd9574d2011-10-01 08:27:46 -0600811 const GLuint n = ctx->Extensions.NV_texture_env_combine4 ? 4 : 3;
Brian Paul986a9bb2011-09-30 21:03:42 -0600812 GLuint i;
Brian Pauldd9574d2011-10-01 08:27:46 -0600813 for (i = 0; i < n; i++) {
Brian Paul986a9bb2011-09-30 21:03:42 -0600814 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB + i,
815 unit->Combine.SourceRGB[i]);
816 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA + i,
817 unit->Combine.SourceA[i]);
818 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB + i,
819 unit->Combine.OperandRGB[i]);
820 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA + i,
821 unit->Combine.OperandA[i]);
822 }
823 }
Ian Romanickbde8bd92011-08-30 17:24:13 -0700824 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE,
825 1 << unit->Combine.ScaleShiftRGB);
826 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE,
827 1 << unit->Combine.ScaleShiftA);
Brian Paul93de8d32001-04-11 23:22:20 +0000828
Brian145d7622007-08-16 10:05:00 +0100829 /* Restore texture object state for each target */
830 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
Brian Paul93de8d32001-04-11 23:22:20 +0000831 const struct gl_texture_object *obj = NULL;
Brian Paulecfaab82011-04-10 12:44:46 -0600832 const struct gl_sampler_object *samp;
Brian145d7622007-08-16 10:05:00 +0100833 GLenum target;
Brian Paul93de8d32001-04-11 23:22:20 +0000834
Brian0135ff52007-08-16 10:28:23 +0100835 obj = &texstate->SavedObj[u][tgt];
836
837 /* don't restore state for unsupported targets to prevent
838 * raising GL errors.
839 */
Brian Paul6a086732016-02-11 07:45:50 -0700840 if (obj->Target == GL_TEXTURE_CUBE_MAP &&
Brian0135ff52007-08-16 10:28:23 +0100841 !ctx->Extensions.ARB_texture_cube_map) {
842 continue;
843 }
844 else if (obj->Target == GL_TEXTURE_RECTANGLE_NV &&
845 !ctx->Extensions.NV_texture_rectangle) {
846 continue;
847 }
848 else if ((obj->Target == GL_TEXTURE_1D_ARRAY_EXT ||
849 obj->Target == GL_TEXTURE_2D_ARRAY_EXT) &&
Ian Romanick538a7f22013-11-20 13:41:23 -0800850 !ctx->Extensions.EXT_texture_array) {
Brian145d7622007-08-16 10:05:00 +0100851 continue;
Brian Paul93de8d32001-04-11 23:22:20 +0000852 }
Dave Airlie5b115862012-11-07 12:51:35 +1000853 else if (obj->Target == GL_TEXTURE_CUBE_MAP_ARRAY &&
854 !ctx->Extensions.ARB_texture_cube_map_array) {
855 continue;
856 } else if (obj->Target == GL_TEXTURE_BUFFER)
Brian Paul53245ff2011-04-06 12:45:21 -0600857 continue;
Chia-I Wu0c87f162011-10-23 18:52:38 +0800858 else if (obj->Target == GL_TEXTURE_EXTERNAL_OES)
859 continue;
Chris Forbesd04a4dd2012-11-24 21:46:56 +1300860 else if (obj->Target == GL_TEXTURE_2D_MULTISAMPLE ||
861 obj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
862 continue;
Brian Paul93de8d32001-04-11 23:22:20 +0000863
Brian145d7622007-08-16 10:05:00 +0100864 target = obj->Target;
865
Brian Paul58cfa0f2001-08-07 23:10:55 +0000866 _mesa_BindTexture(target, obj->Name);
867
Brian Paulecfaab82011-04-10 12:44:46 -0600868 samp = &obj->Sampler;
869
870 _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, samp->BorderColor.f);
871 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, samp->WrapS);
872 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, samp->WrapT);
873 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, samp->WrapR);
874 _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, samp->MinFilter);
875 _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, samp->MagFilter);
876 _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, samp->MinLod);
877 _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, samp->MaxLod);
878 _mesa_TexParameterf(target, GL_TEXTURE_LOD_BIAS, samp->LodBias);
Brian145d7622007-08-16 10:05:00 +0100879 _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority);
Brian Paul93de8d32001-04-11 23:22:20 +0000880 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel);
Brian41fc55d2007-04-17 08:29:37 -0600881 if (target != GL_TEXTURE_RECTANGLE_ARB)
882 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel);
Brian Paul93de8d32001-04-11 23:22:20 +0000883 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
884 _mesa_TexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
Brian Paulecfaab82011-04-10 12:44:46 -0600885 samp->MaxAnisotropy);
Brian Paul93de8d32001-04-11 23:22:20 +0000886 }
Kenneth Graunke608c3d22012-01-27 16:09:48 -0800887 if (ctx->Extensions.ARB_shadow) {
888 _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_MODE,
889 samp->CompareMode);
890 _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_FUNC,
891 samp->CompareFunc);
892 }
893 if (ctx->Extensions.ARB_depth_texture)
Pauli Nieminenc37efbf2012-06-12 21:38:46 +0300894 _mesa_TexParameteri(target, GL_DEPTH_TEXTURE_MODE, obj->DepthMode);
Brian Paul93de8d32001-04-11 23:22:20 +0000895 }
Brian Paul58cfa0f2001-08-07 23:10:55 +0000896
Brian145d7622007-08-16 10:05:00 +0100897 /* remove saved references to the texture objects */
Brian0135ff52007-08-16 10:28:23 +0100898 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
899 _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL);
900 }
Brian Paul58cfa0f2001-08-07 23:10:55 +0000901 }
Brian145d7622007-08-16 10:05:00 +0100902
Paul Berry1a1db172012-11-06 08:57:59 -0800903 _mesa_ActiveTexture(GL_TEXTURE0_ARB + texstate->Texture.CurrentUnit);
Brian145d7622007-08-16 10:05:00 +0100904
Brian Paula1471e42012-01-31 18:24:07 -0700905 _mesa_reference_shared_state(ctx, &texstate->SharedRef, NULL);
906
Brian145d7622007-08-16 10:05:00 +0100907 _mesa_unlock_context_textures(ctx);
Brian Paul93de8d32001-04-11 23:22:20 +0000908}
909
Brian Pauleb6c6432000-09-28 22:44:30 +0000910
jtgafb833d1999-08-19 00:55:39 +0000911/*
912 * This function is kind of long just because we have to call a lot
913 * of device driver functions to update device driver state.
Brian Paulf3da3892001-01-24 15:27:10 +0000914 *
915 * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions
916 * in order to restore GL state. This isn't terribly efficient but it
917 * ensures that dirty flags and any derived state gets updated correctly.
918 * We could at least check if the value to restore equals the current value
919 * and then skip the Mesa call.
jtgafb833d1999-08-19 00:55:39 +0000920 */
Kendall Bennettc40d1dd2003-10-21 22:22:17 +0000921void GLAPIENTRY
Brian Paul42fcf032000-02-02 22:03:31 +0000922_mesa_PopAttrib(void)
jtgafb833d1999-08-19 00:55:39 +0000923{
924 struct gl_attrib_node *attr, *next;
Brian Paul42fcf032000-02-02 22:03:31 +0000925 GET_CURRENT_CONTEXT(ctx);
Eric Anholta9754792013-01-16 16:20:38 -0800926 FLUSH_VERTICES(ctx, 0);
jtgafb833d1999-08-19 00:55:39 +0000927
Brian Paulf3da3892001-01-24 15:27:10 +0000928 if (ctx->AttribStackDepth == 0) {
Brian Paul08836342001-03-03 20:33:27 +0000929 _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" );
jtgafb833d1999-08-19 00:55:39 +0000930 return;
931 }
932
933 ctx->AttribStackDepth--;
934 attr = ctx->AttribStack[ctx->AttribStackDepth];
935
936 while (attr) {
937
Brian Paul9a33a112002-06-13 04:28:29 +0000938 if (MESA_VERBOSE & VERBOSE_API) {
Brian Paul4753d602002-06-15 02:38:15 +0000939 _mesa_debug(ctx, "glPopAttrib %s\n",
Kenneth Graunke2f11e922015-07-18 01:22:00 -0700940 _mesa_enum_to_string(attr->kind));
Brian Paul93de8d32001-04-11 23:22:20 +0000941 }
jtgafb833d1999-08-19 00:55:39 +0000942
943 switch (attr->kind) {
Brian Paul61391952015-05-15 11:22:25 -0600944 case DUMMY_BIT:
945 /* do nothing */
946 break;
947
jtgafb833d1999-08-19 00:55:39 +0000948 case GL_ACCUM_BUFFER_BIT:
Brian Paulf3da3892001-01-24 15:27:10 +0000949 {
950 const struct gl_accum_attrib *accum;
951 accum = (const struct gl_accum_attrib *) attr->data;
952 _mesa_ClearAccum(accum->ClearColor[0],
953 accum->ClearColor[1],
954 accum->ClearColor[2],
955 accum->ClearColor[3]);
956 }
jtgafb833d1999-08-19 00:55:39 +0000957 break;
958 case GL_COLOR_BUFFER_BIT:
959 {
Brian Paulf3da3892001-01-24 15:27:10 +0000960 const struct gl_colorbuffer_attrib *color;
Brian Paul37286732009-12-29 15:04:03 -0700961
Brian Paulf3da3892001-01-24 15:27:10 +0000962 color = (const struct gl_colorbuffer_attrib *) attr->data;
Brian Paul7c276322001-09-14 21:36:43 +0000963 _mesa_ClearIndex((GLfloat) color->ClearIndex);
Dave Airlie093dc9e2011-09-12 10:57:40 +0100964 _mesa_ClearColor(color->ClearColor.f[0],
965 color->ClearColor.f[1],
966 color->ClearColor.f[2],
967 color->ClearColor.f[3]);
Brian Paulf3da3892001-01-24 15:27:10 +0000968 _mesa_IndexMask(color->IndexMask);
Brian Paul36092fa2009-12-29 22:58:44 -0700969 if (!ctx->Extensions.EXT_draw_buffers2) {
Brian Paulfd5511d2009-12-29 16:17:14 -0700970 _mesa_ColorMask((GLboolean) (color->ColorMask[0][0] != 0),
971 (GLboolean) (color->ColorMask[0][1] != 0),
972 (GLboolean) (color->ColorMask[0][2] != 0),
973 (GLboolean) (color->ColorMask[0][3] != 0));
974 }
975 else {
976 GLuint i;
977 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
Paul Berry1a1db172012-11-06 08:57:59 -0800978 _mesa_ColorMaski(i,
Brian Paulfd5511d2009-12-29 16:17:14 -0700979 (GLboolean) (color->ColorMask[i][0] != 0),
980 (GLboolean) (color->ColorMask[i][1] != 0),
981 (GLboolean) (color->ColorMask[i][2] != 0),
982 (GLboolean) (color->ColorMask[i][3] != 0));
983 }
984 }
Brian Paul2f92adb2006-04-22 01:20:20 +0000985 {
986 /* Need to determine if more than one color output is
987 * specified. If so, call glDrawBuffersARB, else call
988 * glDrawBuffer(). This is a subtle, but essential point
989 * since GL_FRONT (for example) is illegal for the former
990 * function, but legal for the later.
991 */
992 GLboolean multipleBuffers = GL_FALSE;
Ian Romanick8aa209c2009-01-27 19:10:43 -0800993 GLuint i;
994
995 for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) {
996 if (color->DrawBuffer[i] != GL_NONE) {
997 multipleBuffers = GL_TRUE;
998 break;
999 }
Brian Paul2f92adb2006-04-22 01:20:20 +00001000 }
1001 /* Call the API_level functions, not _mesa_drawbuffers()
1002 * since we need to do error checking on the pop'd
1003 * GL_DRAW_BUFFER.
1004 * Ex: if GL_FRONT were pushed, but we're popping with a
1005 * user FBO bound, GL_FRONT will be illegal and we'll need
1006 * to record that error. Per OpenGL ARB decision.
1007 */
1008 if (multipleBuffers)
Paul Berry1a1db172012-11-06 08:57:59 -08001009 _mesa_DrawBuffers(ctx->Const.MaxDrawBuffers,
Brian Paul2f92adb2006-04-22 01:20:20 +00001010 color->DrawBuffer);
1011 else
1012 _mesa_DrawBuffer(color->DrawBuffer[0]);
Brian Paul730b2652006-04-14 02:25:35 +00001013 }
Brian Paulf3da3892001-01-24 15:27:10 +00001014 _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled);
Marek Olšáke5c6a922011-02-15 23:30:23 +01001015 _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRefUnclamped);
Brian Paul37286732009-12-29 15:04:03 -07001016 if (ctx->Color.BlendEnabled != color->BlendEnabled) {
Brian Paul1677d5c2009-12-29 23:04:27 -07001017 if (ctx->Extensions.EXT_draw_buffers2) {
1018 GLuint i;
1019 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
1020 _mesa_set_enablei(ctx, GL_BLEND, i,
1021 (color->BlendEnabled >> i) & 1);
1022 }
1023 }
1024 else {
1025 _mesa_set_enable(ctx, GL_BLEND, (color->BlendEnabled & 1));
Brian Paul37286732009-12-29 15:04:03 -07001026 }
1027 }
Brian Paul74713e22011-01-11 15:07:38 -07001028 if (ctx->Color._BlendFuncPerBuffer ||
1029 ctx->Color._BlendEquationPerBuffer) {
1030 /* set blend per buffer */
1031 GLuint buf;
1032 for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) {
Paul Berry1a1db172012-11-06 08:57:59 -08001033 _mesa_BlendFuncSeparateiARB(buf, color->Blend[buf].SrcRGB,
Brian Paul74713e22011-01-11 15:07:38 -07001034 color->Blend[buf].DstRGB,
1035 color->Blend[buf].SrcA,
1036 color->Blend[buf].DstA);
Paul Berry1a1db172012-11-06 08:57:59 -08001037 _mesa_BlendEquationSeparateiARB(buf,
Brian Paul74713e22011-01-11 15:07:38 -07001038 color->Blend[buf].EquationRGB,
1039 color->Blend[buf].EquationA);
1040 }
1041 }
1042 else {
1043 /* set same blend modes for all buffers */
Paul Berry1a1db172012-11-06 08:57:59 -08001044 _mesa_BlendFuncSeparate(color->Blend[0].SrcRGB,
Brian Paul74713e22011-01-11 15:07:38 -07001045 color->Blend[0].DstRGB,
1046 color->Blend[0].SrcA,
1047 color->Blend[0].DstA);
1048 /* This special case is because glBlendEquationSeparateEXT
1049 * cannot take GL_LOGIC_OP as a parameter.
1050 */
1051 if (color->Blend[0].EquationRGB ==
1052 color->Blend[0].EquationA) {
1053 _mesa_BlendEquation(color->Blend[0].EquationRGB);
1054 }
1055 else {
Paul Berry1a1db172012-11-06 08:57:59 -08001056 _mesa_BlendEquationSeparate(
Brian Paul74713e22011-01-11 15:07:38 -07001057 color->Blend[0].EquationRGB,
1058 color->Blend[0].EquationA);
1059 }
1060 }
Marek Olšáke5c6a922011-02-15 23:30:23 +01001061 _mesa_BlendColor(color->BlendColorUnclamped[0],
1062 color->BlendColorUnclamped[1],
1063 color->BlendColorUnclamped[2],
1064 color->BlendColorUnclamped[3]);
Brian Paulf3da3892001-01-24 15:27:10 +00001065 _mesa_LogicOp(color->LogicOp);
1066 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP,
1067 color->ColorLogicOpEnabled);
1068 _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP,
1069 color->IndexLogicOpEnabled);
1070 _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag);
Marek Olšák3264c3e2013-03-28 03:02:14 +01001071 if (ctx->Extensions.ARB_color_buffer_float)
1072 _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB,
1073 color->ClampFragmentColor);
Nicolai Hähnle613154f2017-01-16 12:13:50 +01001074 if (ctx->Extensions.ARB_color_buffer_float || ctx->Version >= 30)
1075 _mesa_ClampColor(GL_CLAMP_READ_COLOR_ARB, color->ClampReadColor);
Eric Anholt4bbd1202012-08-01 12:38:56 -07001076
1077 /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
Brian Paul1aee8802012-08-27 21:52:07 -06001078 if (ctx->Extensions.EXT_framebuffer_sRGB)
1079 _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB, color->sRGBEnabled);
jtgafb833d1999-08-19 00:55:39 +00001080 }
1081 break;
1082 case GL_CURRENT_BIT:
Keith Whitwellcab974c2000-12-26 05:09:27 +00001083 FLUSH_CURRENT( ctx, 0 );
Brian Paule197de52010-02-19 08:09:01 -07001084 memcpy( &ctx->Current, attr->data,
jtgafb833d1999-08-19 00:55:39 +00001085 sizeof(struct gl_current_attrib) );
1086 break;
1087 case GL_DEPTH_BUFFER_BIT:
1088 {
Brian Paulf3da3892001-01-24 15:27:10 +00001089 const struct gl_depthbuffer_attrib *depth;
1090 depth = (const struct gl_depthbuffer_attrib *) attr->data;
1091 _mesa_DepthFunc(depth->Func);
1092 _mesa_ClearDepth(depth->Clear);
1093 _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test);
1094 _mesa_DepthMask(depth->Mask);
Brian Paul4dd72fe2015-05-15 12:09:54 -06001095 if (ctx->Extensions.EXT_depth_bounds_test) {
1096 _mesa_set_enable(ctx, GL_DEPTH_BOUNDS_TEST_EXT,
1097 depth->BoundsTest);
1098 _mesa_DepthBoundsEXT(depth->BoundsMin, depth->BoundsMax);
1099 }
jtgafb833d1999-08-19 00:55:39 +00001100 }
1101 break;
1102 case GL_ENABLE_BIT:
1103 {
1104 const struct gl_enable_attrib *enable;
1105 enable = (const struct gl_enable_attrib *) attr->data;
Brian Pauleb6c6432000-09-28 22:44:30 +00001106 pop_enable_group(ctx, enable);
Keith Whitwella96308c2000-10-30 13:31:59 +00001107 ctx->NewState |= _NEW_ALL;
jtgafb833d1999-08-19 00:55:39 +00001108 }
1109 break;
1110 case GL_EVAL_BIT:
Brian Paule197de52010-02-19 08:09:01 -07001111 memcpy( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) );
Keith Whitwella96308c2000-10-30 13:31:59 +00001112 ctx->NewState |= _NEW_EVAL;
jtgafb833d1999-08-19 00:55:39 +00001113 break;
1114 case GL_FOG_BIT:
1115 {
Brian Paulf3da3892001-01-24 15:27:10 +00001116 const struct gl_fog_attrib *fog;
1117 fog = (const struct gl_fog_attrib *) attr->data;
1118 _mesa_set_enable(ctx, GL_FOG, fog->Enabled);
1119 _mesa_Fogfv(GL_FOG_COLOR, fog->Color);
1120 _mesa_Fogf(GL_FOG_DENSITY, fog->Density);
1121 _mesa_Fogf(GL_FOG_START, fog->Start);
1122 _mesa_Fogf(GL_FOG_END, fog->End);
1123 _mesa_Fogf(GL_FOG_INDEX, fog->Index);
1124 _mesa_Fogi(GL_FOG_MODE, fog->Mode);
jtgafb833d1999-08-19 00:55:39 +00001125 }
1126 break;
1127 case GL_HINT_BIT:
Brian Paulf3da3892001-01-24 15:27:10 +00001128 {
1129 const struct gl_hint_attrib *hint;
1130 hint = (const struct gl_hint_attrib *) attr->data;
Brian Paulf3da3892001-01-24 15:27:10 +00001131 _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT,
1132 hint->PerspectiveCorrection );
1133 _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth);
1134 _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth);
1135 _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth);
1136 _mesa_Hint(GL_FOG_HINT, hint->Fog);
Ian Romanick33fa5e42009-01-27 17:36:03 -08001137 _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB,
1138 hint->TextureCompression);
jtgafb833d1999-08-19 00:55:39 +00001139 }
1140 break;
1141 case GL_LIGHTING_BIT:
Brian Paulf3da3892001-01-24 15:27:10 +00001142 {
jtgafb833d1999-08-19 00:55:39 +00001143 GLuint i;
Brian Paulf3da3892001-01-24 15:27:10 +00001144 const struct gl_light_attrib *light;
1145 light = (const struct gl_light_attrib *) attr->data;
1146 /* lighting enable */
1147 _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled);
1148 /* per-light state */
Brian Paul049e3202005-06-30 14:22:23 +00001149 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top))
Brian Paul53f82c52004-10-02 16:39:09 +00001150 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
Keith Whitwell0cb28412002-02-13 00:53:19 +00001151
Brian Paul418a7db2005-11-10 16:22:56 +00001152 for (i = 0; i < ctx->Const.MaxLights; i++) {
Vinson Lee6130bb12010-01-04 12:06:04 -08001153 const struct gl_light *l = &light->Light[i];
Brian Paul662fbf82005-11-12 18:58:12 +00001154 _mesa_set_enable(ctx, GL_LIGHT0 + i, l->Enabled);
Vinson Lee6130bb12010-01-04 12:06:04 -08001155 _mesa_light(ctx, i, GL_AMBIENT, l->Ambient);
1156 _mesa_light(ctx, i, GL_DIFFUSE, l->Diffuse);
1157 _mesa_light(ctx, i, GL_SPECULAR, l->Specular );
1158 _mesa_light(ctx, i, GL_POSITION, l->EyePosition);
1159 _mesa_light(ctx, i, GL_SPOT_DIRECTION, l->SpotDirection);
1160 {
1161 GLfloat p[4] = { 0 };
1162 p[0] = l->SpotExponent;
1163 _mesa_light(ctx, i, GL_SPOT_EXPONENT, p);
1164 }
1165 {
1166 GLfloat p[4] = { 0 };
1167 p[0] = l->SpotCutoff;
1168 _mesa_light(ctx, i, GL_SPOT_CUTOFF, p);
1169 }
1170 {
1171 GLfloat p[4] = { 0 };
1172 p[0] = l->ConstantAttenuation;
1173 _mesa_light(ctx, i, GL_CONSTANT_ATTENUATION, p);
1174 }
1175 {
1176 GLfloat p[4] = { 0 };
1177 p[0] = l->LinearAttenuation;
1178 _mesa_light(ctx, i, GL_LINEAR_ATTENUATION, p);
1179 }
1180 {
1181 GLfloat p[4] = { 0 };
1182 p[0] = l->QuadraticAttenuation;
1183 _mesa_light(ctx, i, GL_QUADRATIC_ATTENUATION, p);
1184 }
Brian Paul478f0d22011-11-30 20:35:02 -07001185 }
Brian Paulf3da3892001-01-24 15:27:10 +00001186 /* light model */
1187 _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT,
1188 light->Model.Ambient);
1189 _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER,
1190 (GLfloat) light->Model.LocalViewer);
1191 _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE,
1192 (GLfloat) light->Model.TwoSide);
1193 _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL,
1194 (GLfloat) light->Model.ColorControl);
Brian Paulf3da3892001-01-24 15:27:10 +00001195 /* shade model */
Brian Paulba70e592001-01-29 22:15:44 +00001196 _mesa_ShadeModel(light->ShadeModel);
Brian Paulf3da3892001-01-24 15:27:10 +00001197 /* color material */
1198 _mesa_ColorMaterial(light->ColorMaterialFace,
1199 light->ColorMaterialMode);
1200 _mesa_set_enable(ctx, GL_COLOR_MATERIAL,
1201 light->ColorMaterialEnabled);
Brian Paul7cc55222006-11-20 15:14:35 +00001202 /* materials */
Brian Paule197de52010-02-19 08:09:01 -07001203 memcpy(&ctx->Light.Material, &light->Material,
Brian Paul7cc55222006-11-20 15:14:35 +00001204 sizeof(struct gl_material));
Marek Olšák3264c3e2013-03-28 03:02:14 +01001205 if (ctx->Extensions.ARB_color_buffer_float) {
1206 _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR_ARB,
1207 light->ClampVertexColor);
1208 }
jtgafb833d1999-08-19 00:55:39 +00001209 }
jtgafb833d1999-08-19 00:55:39 +00001210 break;
1211 case GL_LINE_BIT:
Brian Paulf3da3892001-01-24 15:27:10 +00001212 {
1213 const struct gl_line_attrib *line;
1214 line = (const struct gl_line_attrib *) attr->data;
1215 _mesa_set_enable(ctx, GL_LINE_SMOOTH, line->SmoothFlag);
1216 _mesa_set_enable(ctx, GL_LINE_STIPPLE, line->StippleFlag);
1217 _mesa_LineStipple(line->StippleFactor, line->StipplePattern);
1218 _mesa_LineWidth(line->Width);
jtgafb833d1999-08-19 00:55:39 +00001219 }
1220 break;
1221 case GL_LIST_BIT:
Brian Paule197de52010-02-19 08:09:01 -07001222 memcpy( &ctx->List, attr->data, sizeof(struct gl_list_attrib) );
jtgafb833d1999-08-19 00:55:39 +00001223 break;
1224 case GL_PIXEL_MODE_BIT:
Brian Paule197de52010-02-19 08:09:01 -07001225 memcpy( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) );
Brian Paule4b23562005-05-04 20:11:35 +00001226 /* XXX what other pixel state needs to be set by function calls? */
1227 _mesa_ReadBuffer(ctx->Pixel.ReadBuffer);
Keith Whitwella96308c2000-10-30 13:31:59 +00001228 ctx->NewState |= _NEW_PIXEL;
jtgafb833d1999-08-19 00:55:39 +00001229 break;
1230 case GL_POINT_BIT:
Brian Paulf3da3892001-01-24 15:27:10 +00001231 {
1232 const struct gl_point_attrib *point;
1233 point = (const struct gl_point_attrib *) attr->data;
1234 _mesa_PointSize(point->Size);
1235 _mesa_set_enable(ctx, GL_POINT_SMOOTH, point->SmoothFlag);
Brian Paul2871f572002-10-11 21:42:08 +00001236 if (ctx->Extensions.EXT_point_parameters) {
Brian Paul9228f1c2008-06-05 12:08:19 -06001237 _mesa_PointParameterfv(GL_DISTANCE_ATTENUATION_EXT,
1238 point->Params);
1239 _mesa_PointParameterf(GL_POINT_SIZE_MIN_EXT,
1240 point->MinSize);
1241 _mesa_PointParameterf(GL_POINT_SIZE_MAX_EXT,
1242 point->MaxSize);
1243 _mesa_PointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_EXT,
1244 point->Threshold);
Brian Paul2871f572002-10-11 21:42:08 +00001245 }
Ian Romanick63736722003-08-23 00:12:46 +00001246 if (ctx->Extensions.NV_point_sprite
1247 || ctx->Extensions.ARB_point_sprite) {
Brian Paul6c408b42002-05-27 17:04:52 +00001248 GLuint u;
1249 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
1250 _mesa_TexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV,
Mathias Fröhlich6749d772016-05-22 14:10:19 +02001251 !!(point->CoordReplace & (1u << u)));
Brian Paul6c408b42002-05-27 17:04:52 +00001252 }
1253 _mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite);
Alan Hourihaneb59dbd82007-10-28 20:07:37 +00001254 if (ctx->Extensions.NV_point_sprite)
Brian Paul9228f1c2008-06-05 12:08:19 -06001255 _mesa_PointParameteri(GL_POINT_SPRITE_R_MODE_NV,
1256 ctx->Point.SpriteRMode);
Mario Kleinereabbe5c2012-10-07 03:44:14 +02001257
Paul Berrydbd61352012-11-27 12:26:51 -08001258 if ((ctx->API == API_OPENGL_COMPAT && ctx->Version >= 20)
Mario Kleinereabbe5c2012-10-07 03:44:14 +02001259 || ctx->API == API_OPENGL_CORE)
1260 _mesa_PointParameterf(GL_POINT_SPRITE_COORD_ORIGIN,
1261 (GLfloat)ctx->Point.SpriteOrigin);
Brian Paul6c408b42002-05-27 17:04:52 +00001262 }
Brian Paulf3da3892001-01-24 15:27:10 +00001263 }
jtgafb833d1999-08-19 00:55:39 +00001264 break;
1265 case GL_POLYGON_BIT:
1266 {
Brian Paulf3da3892001-01-24 15:27:10 +00001267 const struct gl_polygon_attrib *polygon;
1268 polygon = (const struct gl_polygon_attrib *) attr->data;
1269 _mesa_CullFace(polygon->CullFaceMode);
1270 _mesa_FrontFace(polygon->FrontFace);
1271 _mesa_PolygonMode(GL_FRONT, polygon->FrontMode);
1272 _mesa_PolygonMode(GL_BACK, polygon->BackMode);
Ilia Mirkin81998dd2014-12-31 02:07:55 -05001273 _mesa_polygon_offset_clamp(ctx,
1274 polygon->OffsetFactor,
1275 polygon->OffsetUnits,
1276 polygon->OffsetClamp);
Brian Paulf3da3892001-01-24 15:27:10 +00001277 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag);
1278 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag);
1279 _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag);
1280 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_POINT,
1281 polygon->OffsetPoint);
1282 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_LINE,
1283 polygon->OffsetLine);
1284 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL,
1285 polygon->OffsetFill);
jtgafb833d1999-08-19 00:55:39 +00001286 }
1287 break;
1288 case GL_POLYGON_STIPPLE_BIT:
Brian Paule197de52010-02-19 08:09:01 -07001289 memcpy( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) );
Keith Whitwella96308c2000-10-30 13:31:59 +00001290 ctx->NewState |= _NEW_POLYGONSTIPPLE;
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001291 if (ctx->Driver.PolygonStipple)
Brian Paul959f8022000-03-19 01:10:11 +00001292 ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data );
jtgafb833d1999-08-19 00:55:39 +00001293 break;
1294 case GL_SCISSOR_BIT:
Brian Paulf3da3892001-01-24 15:27:10 +00001295 {
Ian Romanickc65db3e2014-01-07 19:06:59 -08001296 unsigned i;
Brian Paulf3da3892001-01-24 15:27:10 +00001297 const struct gl_scissor_attrib *scissor;
1298 scissor = (const struct gl_scissor_attrib *) attr->data;
Courtney Goeltzenleuchtera9c73fb2013-11-13 14:02:12 -07001299
Ian Romanickc65db3e2014-01-07 19:06:59 -08001300 for (i = 0; i < ctx->Const.MaxViewports; i++) {
1301 _mesa_set_scissor(ctx, i,
1302 scissor->ScissorArray[i].X,
1303 scissor->ScissorArray[i].Y,
1304 scissor->ScissorArray[i].Width,
1305 scissor->ScissorArray[i].Height);
1306 _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i,
1307 (scissor->EnableFlags >> i) & 1);
1308 }
Ilia Mirkind68c1e22016-06-09 22:50:43 -04001309 if (ctx->Extensions.EXT_window_rectangles) {
1310 STATIC_ASSERT(sizeof(struct gl_scissor_rect) ==
1311 4 * sizeof(GLint));
1312 _mesa_WindowRectanglesEXT(
1313 scissor->WindowRectMode, scissor->NumWindowRects,
1314 (const GLint *)scissor->WindowRects);
1315 }
Brian Paulf3da3892001-01-24 15:27:10 +00001316 }
jtgafb833d1999-08-19 00:55:39 +00001317 break;
1318 case GL_STENCIL_BUFFER_BIT:
Brian Paulf3da3892001-01-24 15:27:10 +00001319 {
1320 const struct gl_stencil_attrib *stencil;
1321 stencil = (const struct gl_stencil_attrib *) attr->data;
1322 _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
1323 _mesa_ClearStencil(stencil->Clear);
Daniel Borca79a98de2004-11-12 09:56:33 +00001324 if (ctx->Extensions.EXT_stencil_two_side) {
Brian Paul42c34ef2005-09-13 02:59:53 +00001325 _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
1326 stencil->TestTwoSide);
1327 _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
1328 ? GL_BACK : GL_FRONT);
Daniel Borca79a98de2004-11-12 09:56:33 +00001329 }
Brian Paul42c34ef2005-09-13 02:59:53 +00001330 /* front state */
Brian Paul878c3712005-09-13 04:42:09 +00001331 _mesa_StencilFuncSeparate(GL_FRONT,
1332 stencil->Function[0],
1333 stencil->Ref[0],
1334 stencil->ValueMask[0]);
1335 _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
1336 _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
1337 stencil->ZFailFunc[0],
1338 stencil->ZPassFunc[0]);
Brian Paul42c34ef2005-09-13 02:59:53 +00001339 /* back state */
Brian Paul878c3712005-09-13 04:42:09 +00001340 _mesa_StencilFuncSeparate(GL_BACK,
1341 stencil->Function[1],
Brian Paul42c34ef2005-09-13 02:59:53 +00001342 stencil->Ref[1],
1343 stencil->ValueMask[1]);
1344 _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
1345 _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
1346 stencil->ZFailFunc[1],
1347 stencil->ZPassFunc[1]);
Brian Paulf3da3892001-01-24 15:27:10 +00001348 }
jtgafb833d1999-08-19 00:55:39 +00001349 break;
1350 case GL_TRANSFORM_BIT:
Brian Paulf3da3892001-01-24 15:27:10 +00001351 {
1352 GLuint i;
1353 const struct gl_transform_attrib *xform;
1354 xform = (const struct gl_transform_attrib *) attr->data;
1355 _mesa_MatrixMode(xform->MatrixMode);
Brian Paul049e3202005-06-30 14:22:23 +00001356 if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top))
Brian Paul934bee02002-03-28 22:42:41 +00001357 _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
1358
1359 /* restore clip planes */
Paul Berry27bdc762011-09-07 17:44:28 -07001360 for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
Lars Henning Wendtd82876e2009-04-16 10:14:17 -06001361 const GLuint mask = 1 << i;
Brian Paul934bee02002-03-28 22:42:41 +00001362 const GLfloat *eyePlane = xform->EyeUserPlane[i];
1363 COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane);
Brian Paulb15ab1d2011-09-30 21:03:42 -06001364 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i,
1365 !!(xform->ClipPlanesEnabled & mask));
Brian Paul934bee02002-03-28 22:42:41 +00001366 if (ctx->Driver.ClipPlane)
Brian Paul4753d602002-06-15 02:38:15 +00001367 ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, eyePlane );
Brian Paulf3da3892001-01-24 15:27:10 +00001368 }
Brian Paul934bee02002-03-28 22:42:41 +00001369
Brian Paulf3da3892001-01-24 15:27:10 +00001370 /* normalize/rescale */
Brian Paul86a7cc62002-04-01 17:03:38 +00001371 if (xform->Normalize != ctx->Transform.Normalize)
1372 _mesa_set_enable(ctx, GL_NORMALIZE,ctx->Transform.Normalize);
1373 if (xform->RescaleNormals != ctx->Transform.RescaleNormals)
1374 _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT,
1375 ctx->Transform.RescaleNormals);
Eric Anholtb4922b52009-08-26 09:51:15 -07001376 if (xform->DepthClamp != ctx->Transform.DepthClamp)
1377 _mesa_set_enable(ctx, GL_DEPTH_CLAMP,
1378 ctx->Transform.DepthClamp);
Kenneth Graunke8ca8dd12014-11-03 18:16:41 -08001379 if (ctx->Extensions.ARB_clip_control)
1380 _mesa_ClipControl(xform->ClipOrigin, xform->ClipDepthMode);
jtgafb833d1999-08-19 00:55:39 +00001381 }
jtgafb833d1999-08-19 00:55:39 +00001382 break;
1383 case GL_TEXTURE_BIT:
jtgafb833d1999-08-19 00:55:39 +00001384 {
Brian145d7622007-08-16 10:05:00 +01001385 struct texture_state *texstate
1386 = (struct texture_state *) attr->data;
1387 pop_texture_group(ctx, texstate);
Keith Whitwella96308c2000-10-30 13:31:59 +00001388 ctx->NewState |= _NEW_TEXTURE;
jtgafb833d1999-08-19 00:55:39 +00001389 }
1390 break;
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001391 case GL_VIEWPORT_BIT:
Brian Paulf3da3892001-01-24 15:27:10 +00001392 {
Ian Romanick562f3532014-01-07 19:12:16 -08001393 unsigned i;
Brian Paulf3da3892001-01-24 15:27:10 +00001394 const struct gl_viewport_attrib *vp;
Brian Paul736fcbe2001-05-29 15:23:48 +00001395 vp = (const struct gl_viewport_attrib *) attr->data;
Ian Romanick562f3532014-01-07 19:12:16 -08001396
1397 for (i = 0; i < ctx->Const.MaxViewports; i++) {
1398 _mesa_set_viewport(ctx, i, vp[i].X, vp[i].Y, vp[i].Width,
1399 vp[i].Height);
1400 _mesa_set_depth_range(ctx, i, vp[i].Near, vp[i].Far);
1401 }
Brian Paulf3da3892001-01-24 15:27:10 +00001402 }
1403 break;
Brian Paul736fcbe2001-05-29 15:23:48 +00001404 case GL_MULTISAMPLE_BIT_ARB:
1405 {
1406 const struct gl_multisample_attrib *ms;
1407 ms = (const struct gl_multisample_attrib *) attr->data;
Eric Anholtb631b472012-02-13 13:36:06 -08001408
1409 TEST_AND_UPDATE(ctx->Multisample.Enabled,
1410 ms->Enabled,
1411 GL_MULTISAMPLE);
1412
1413 TEST_AND_UPDATE(ctx->Multisample.SampleCoverage,
1414 ms->SampleCoverage,
1415 GL_SAMPLE_COVERAGE);
1416
1417 TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage,
1418 ms->SampleAlphaToCoverage,
1419 GL_SAMPLE_ALPHA_TO_COVERAGE);
1420
1421 TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne,
1422 ms->SampleAlphaToOne,
1423 GL_SAMPLE_ALPHA_TO_ONE);
1424
Paul Berry1a1db172012-11-06 08:57:59 -08001425 _mesa_SampleCoverage(ms->SampleCoverageValue,
Brian Paul736fcbe2001-05-29 15:23:48 +00001426 ms->SampleCoverageInvert);
1427 }
1428 break;
1429
jtgafb833d1999-08-19 00:55:39 +00001430 default:
Brian Paul08836342001-03-03 20:33:27 +00001431 _mesa_problem( ctx, "Bad attrib flag in PopAttrib");
jtgafb833d1999-08-19 00:55:39 +00001432 break;
1433 }
1434
1435 next = attr->next;
Brian Paulfe72a062012-09-01 07:47:24 -06001436 free(attr->data);
1437 free(attr);
jtgafb833d1999-08-19 00:55:39 +00001438 attr = next;
1439 }
jtgafb833d1999-08-19 00:55:39 +00001440}
1441
1442
Brian Paul20202782004-02-11 22:06:05 +00001443/**
Brian Paul37c74af2008-09-04 14:58:02 -06001444 * Copy gl_pixelstore_attrib from src to dst, updating buffer
1445 * object refcounts.
1446 */
1447static void
Kristian Høgsbergf9995b32010-10-12 12:26:10 -04001448copy_pixelstore(struct gl_context *ctx,
Brian Paul37c74af2008-09-04 14:58:02 -06001449 struct gl_pixelstore_attrib *dst,
1450 const struct gl_pixelstore_attrib *src)
1451{
1452 dst->Alignment = src->Alignment;
1453 dst->RowLength = src->RowLength;
1454 dst->SkipPixels = src->SkipPixels;
1455 dst->SkipRows = src->SkipRows;
1456 dst->ImageHeight = src->ImageHeight;
1457 dst->SkipImages = src->SkipImages;
1458 dst->SwapBytes = src->SwapBytes;
1459 dst->LsbFirst = src->LsbFirst;
Brian Paul37c74af2008-09-04 14:58:02 -06001460 dst->Invert = src->Invert;
1461 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
1462}
1463
1464
jtgafb833d1999-08-19 00:55:39 +00001465#define GL_CLIENT_PACK_BIT (1<<20)
1466#define GL_CLIENT_UNPACK_BIT (1<<21)
1467
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001468/**
Kenneth Graunkeaac14152014-02-01 19:36:59 -08001469 * Copy gl_vertex_array_object from src to dest.
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001470 * 'dest' must be in an initialized state.
1471 */
1472static void
1473copy_array_object(struct gl_context *ctx,
Kenneth Graunkeaac14152014-02-01 19:36:59 -08001474 struct gl_vertex_array_object *dest,
1475 struct gl_vertex_array_object *src)
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001476{
1477 GLuint i;
1478
1479 /* skip Name */
1480 /* skip RefCount */
1481
1482 /* In theory must be the same anyway, but on recreate make sure it matches */
Ian Romanick09639902012-01-23 14:22:38 -08001483 dest->ARBsemantics = src->ARBsemantics;
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001484
Brian Paulc2e130f2015-02-28 08:57:11 -07001485 for (i = 0; i < ARRAY_SIZE(src->VertexAttrib); i++) {
Fredrik Höglund12cbe992013-04-03 22:08:47 +02001486 _mesa_copy_client_array(ctx, &dest->_VertexAttrib[i], &src->_VertexAttrib[i]);
Fredrik Höglund59b01ca2013-04-09 20:54:25 +02001487 _mesa_copy_vertex_attrib_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]);
Brian Paul910bc4d2016-10-19 17:58:44 -06001488 _mesa_copy_vertex_buffer_binding(ctx, &dest->BufferBinding[i], &src->BufferBinding[i]);
Fredrik Höglund59b01ca2013-04-09 20:54:25 +02001489 }
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001490
1491 /* _Enabled must be the same than on push */
1492 dest->_Enabled = src->_Enabled;
Mathias Fröhlich62d41162016-08-01 06:55:35 +02001493 /* The bitmask of bound VBOs needs to match the VertexBinding array */
1494 dest->VertexAttribBufferMask = src->VertexAttribBufferMask;
Fredrik Höglund9afbd042014-02-07 20:34:08 +01001495 dest->NewArrays = src->NewArrays;
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001496}
1497
1498/**
1499 * Copy gl_array_attrib from src to dest.
1500 * 'dest' must be in an initialized state.
1501 */
1502static void
1503copy_array_attrib(struct gl_context *ctx,
1504 struct gl_array_attrib *dest,
Ian Romanick34c353c2012-01-20 17:23:02 -08001505 struct gl_array_attrib *src,
1506 bool vbo_deleted)
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001507{
1508 /* skip ArrayObj */
1509 /* skip DefaultArrayObj, Objects */
1510 dest->ActiveTexture = src->ActiveTexture;
1511 dest->LockFirst = src->LockFirst;
1512 dest->LockCount = src->LockCount;
1513 dest->PrimitiveRestart = src->PrimitiveRestart;
Ian Romanick42ed81a2012-08-10 22:28:27 -07001514 dest->PrimitiveRestartFixedIndex = src->PrimitiveRestartFixedIndex;
1515 dest->_PrimitiveRestart = src->_PrimitiveRestart;
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001516 dest->RestartIndex = src->RestartIndex;
1517 /* skip NewState */
1518 /* skip RebindArrays */
1519
Ian Romanick34c353c2012-01-20 17:23:02 -08001520 if (!vbo_deleted)
Kenneth Graunke0dfe50f2014-02-01 19:14:38 -08001521 copy_array_object(ctx, dest->VAO, src->VAO);
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001522
1523 /* skip ArrayBufferObj */
Kenneth Graunkee1b1f2a2014-02-01 19:46:45 -08001524 /* skip IndexBufferObj */
Marek Olšák374f3e92014-09-01 20:01:03 +02001525
1526 /* Invalidate draw state. It will be updated during the next draw. */
1527 dest->DrawMethod = DRAW_NONE;
1528 dest->_DrawArrays = NULL;
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001529}
1530
1531/**
1532 * Save the content of src to dest.
1533 */
1534static void
1535save_array_attrib(struct gl_context *ctx,
1536 struct gl_array_attrib *dest,
1537 struct gl_array_attrib *src)
1538{
1539 /* Set the Name, needed for restore, but do never overwrite.
1540 * Needs to match value in the object hash. */
Kenneth Graunke0dfe50f2014-02-01 19:14:38 -08001541 dest->VAO->Name = src->VAO->Name;
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001542 /* And copy all of the rest. */
Ian Romanick34c353c2012-01-20 17:23:02 -08001543 copy_array_attrib(ctx, dest, src, false);
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001544
1545 /* Just reference them here */
1546 _mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj,
1547 src->ArrayBufferObj);
Kenneth Graunkee1b1f2a2014-02-01 19:46:45 -08001548 _mesa_reference_buffer_object(ctx, &dest->VAO->IndexBufferObj,
1549 src->VAO->IndexBufferObj);
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001550}
1551
1552/**
1553 * Restore the content of src to dest.
1554 */
1555static void
1556restore_array_attrib(struct gl_context *ctx,
1557 struct gl_array_attrib *dest,
1558 struct gl_array_attrib *src)
1559{
Ian Romanick34c353c2012-01-20 17:23:02 -08001560 /* The ARB_vertex_array_object spec says:
1561 *
1562 * "BindVertexArray fails and an INVALID_OPERATION error is generated
1563 * if array is not a name returned from a previous call to
1564 * GenVertexArrays, or if such a name has since been deleted with
1565 * DeleteVertexArrays."
1566 *
1567 * Therefore popping a deleted VAO cannot magically recreate it.
1568 *
1569 * The semantics of objects created using APPLE_vertex_array_objects behave
1570 * differently. These objects expect to be recreated by pop. Alas.
1571 */
Kenneth Graunke0dfe50f2014-02-01 19:14:38 -08001572 const bool arb_vao = (src->VAO->Name != 0
1573 && src->VAO->ARBsemantics);
Ian Romanick34c353c2012-01-20 17:23:02 -08001574
Kenneth Graunke0dfe50f2014-02-01 19:14:38 -08001575 if (arb_vao && !_mesa_IsVertexArray(src->VAO->Name))
Ian Romanick34c353c2012-01-20 17:23:02 -08001576 return;
1577
Kenneth Graunke0dfe50f2014-02-01 19:14:38 -08001578 _mesa_BindVertexArrayAPPLE(src->VAO->Name);
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001579
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001580 /* Restore or recreate the buffer objects by the names ... */
Ian Romanick34c353c2012-01-20 17:23:02 -08001581 if (!arb_vao
1582 || src->ArrayBufferObj->Name == 0
Paul Berry1a1db172012-11-06 08:57:59 -08001583 || _mesa_IsBuffer(src->ArrayBufferObj->Name)) {
Ian Romanick34c353c2012-01-20 17:23:02 -08001584 /* ... and restore its content */
1585 copy_array_attrib(ctx, dest, src, false);
1586
Paul Berry1a1db172012-11-06 08:57:59 -08001587 _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB,
Ian Romanick34c353c2012-01-20 17:23:02 -08001588 src->ArrayBufferObj->Name);
1589 } else {
1590 copy_array_attrib(ctx, dest, src, true);
1591 }
1592
1593 if (!arb_vao
Kenneth Graunkee1b1f2a2014-02-01 19:46:45 -08001594 || src->VAO->IndexBufferObj->Name == 0
1595 || _mesa_IsBuffer(src->VAO->IndexBufferObj->Name))
Paul Berry1a1db172012-11-06 08:57:59 -08001596 _mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,
Kenneth Graunkee1b1f2a2014-02-01 19:46:45 -08001597 src->VAO->IndexBufferObj->Name);
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001598}
1599
1600/**
1601 * init/alloc the fields of 'attrib'.
1602 * Needs to the init part matching free_array_attrib_data below.
1603 */
Juha-Pekka Heikkila2a83e412013-12-16 07:04:00 -07001604static bool
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001605init_array_attrib_data(struct gl_context *ctx,
1606 struct gl_array_attrib *attrib)
1607{
Kenneth Graunkeaac14152014-02-01 19:36:59 -08001608 /* Get a non driver gl_vertex_array_object. */
1609 attrib->VAO = CALLOC_STRUCT( gl_vertex_array_object );
Juha-Pekka Heikkila2a83e412013-12-16 07:04:00 -07001610
Kenneth Graunke0dfe50f2014-02-01 19:14:38 -08001611 if (attrib->VAO == NULL) {
Juha-Pekka Heikkila2a83e412013-12-16 07:04:00 -07001612 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
1613 return false;
1614 }
1615
Kenneth Graunkede47fd22014-02-01 20:48:51 -08001616 _mesa_initialize_vao(ctx, attrib->VAO, 0);
Juha-Pekka Heikkila2a83e412013-12-16 07:04:00 -07001617 return true;
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001618}
1619
1620/**
1621 * Free/unreference the fields of 'attrib' but don't delete it (that's
1622 * done later in the calling code).
1623 * Needs to the cleanup part matching init_array_attrib_data above.
1624 */
1625static void
1626free_array_attrib_data(struct gl_context *ctx,
1627 struct gl_array_attrib *attrib)
1628{
1629 /* We use a non driver array object, so don't just unref since we would
1630 * end up using the drivers DeleteArrayObject function for deletion. */
Kenneth Graunkede47fd22014-02-01 20:48:51 -08001631 _mesa_delete_vao(ctx, attrib->VAO);
Kenneth Graunke0dfe50f2014-02-01 19:14:38 -08001632 attrib->VAO = 0;
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001633 _mesa_reference_buffer_object(ctx, &attrib->ArrayBufferObj, NULL);
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001634}
1635
jtgafb833d1999-08-19 00:55:39 +00001636
Kendall Bennettc40d1dd2003-10-21 22:22:17 +00001637void GLAPIENTRY
Brian Paul42fcf032000-02-02 22:03:31 +00001638_mesa_PushClientAttrib(GLbitfield mask)
jtgafb833d1999-08-19 00:55:39 +00001639{
jtgafb833d1999-08-19 00:55:39 +00001640 struct gl_attrib_node *head;
1641
Brian Paul42fcf032000-02-02 22:03:31 +00001642 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +00001643
Brian Paulf3da3892001-01-24 15:27:10 +00001644 if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) {
Brian Paul08836342001-03-03 20:33:27 +00001645 _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" );
jtgafb833d1999-08-19 00:55:39 +00001646 return;
1647 }
1648
Brian Paul37c74af2008-09-04 14:58:02 -06001649 /* Build linked list of attribute nodes which save all attribute
1650 * groups specified by the mask.
1651 */
jtgafb833d1999-08-19 00:55:39 +00001652 head = NULL;
1653
1654 if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
1655 struct gl_pixelstore_attrib *attr;
1656 /* packing attribs */
Brian Paul37c74af2008-09-04 14:58:02 -06001657 attr = CALLOC_STRUCT( gl_pixelstore_attrib );
Juha-Pekka Heikkila2a83e412013-12-16 07:04:00 -07001658 if (attr == NULL) {
1659 _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" );
1660 goto end;
1661 }
1662 if (save_attrib_data(&head, GL_CLIENT_PACK_BIT, attr)) {
1663 copy_pixelstore(ctx, attr, &ctx->Pack);
1664 }
1665 else {
1666 _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" );
Brian Paul7fbb8ba2014-04-09 19:27:06 -06001667 free(attr);
Juha-Pekka Heikkila2a83e412013-12-16 07:04:00 -07001668 goto end;
1669 }
1670
jtgafb833d1999-08-19 00:55:39 +00001671 /* unpacking attribs */
Brian Paul11d694b2008-09-05 08:06:59 -06001672 attr = CALLOC_STRUCT( gl_pixelstore_attrib );
Juha-Pekka Heikkila2a83e412013-12-16 07:04:00 -07001673 if (attr == NULL) {
1674 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
1675 goto end;
1676 }
1677
1678 if (save_attrib_data(&head, GL_CLIENT_UNPACK_BIT, attr)) {
1679 copy_pixelstore(ctx, attr, &ctx->Unpack);
1680 }
1681 else {
1682 _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" );
Brian Paul7fbb8ba2014-04-09 19:27:06 -06001683 free(attr);
Juha-Pekka Heikkila2a83e412013-12-16 07:04:00 -07001684 goto end;
1685 }
jtgafb833d1999-08-19 00:55:39 +00001686 }
Brian Paul37c74af2008-09-04 14:58:02 -06001687
jtgafb833d1999-08-19 00:55:39 +00001688 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
1689 struct gl_array_attrib *attr;
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001690 attr = CALLOC_STRUCT( gl_array_attrib );
Juha-Pekka Heikkila2a83e412013-12-16 07:04:00 -07001691 if (attr == NULL) {
1692 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
1693 goto end;
1694 }
jtgafb833d1999-08-19 00:55:39 +00001695
Juha-Pekka Heikkila2a83e412013-12-16 07:04:00 -07001696 if (!init_array_attrib_data(ctx, attr)) {
Brian Paul7fbb8ba2014-04-09 19:27:06 -06001697 free(attr);
Juha-Pekka Heikkila2a83e412013-12-16 07:04:00 -07001698 goto end;
1699 }
1700
1701 if (save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr)) {
1702 save_array_attrib(ctx, attr, &ctx->Array);
1703 }
1704 else {
1705 free_array_attrib_data(ctx, attr);
1706 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
Brian Paul7fbb8ba2014-04-09 19:27:06 -06001707 free(attr);
Juha-Pekka Heikkila2a83e412013-12-16 07:04:00 -07001708 /* goto to keep safe from possible later changes */
1709 goto end;
1710 }
1711 }
1712end:
1713 if (head != NULL) {
1714 ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
1715 ctx->ClientAttribStackDepth++;
1716 }
jtgafb833d1999-08-19 00:55:39 +00001717}
1718
1719
1720
1721
Kendall Bennettc40d1dd2003-10-21 22:22:17 +00001722void GLAPIENTRY
Brian Paul42fcf032000-02-02 22:03:31 +00001723_mesa_PopClientAttrib(void)
jtgafb833d1999-08-19 00:55:39 +00001724{
Brian Paul37c74af2008-09-04 14:58:02 -06001725 struct gl_attrib_node *node, *next;
jtgafb833d1999-08-19 00:55:39 +00001726
Brian Paul42fcf032000-02-02 22:03:31 +00001727 GET_CURRENT_CONTEXT(ctx);
Eric Anholta9754792013-01-16 16:20:38 -08001728 FLUSH_VERTICES(ctx, 0);
jtgafb833d1999-08-19 00:55:39 +00001729
Brian Paulf3da3892001-01-24 15:27:10 +00001730 if (ctx->ClientAttribStackDepth == 0) {
Brian Paul08836342001-03-03 20:33:27 +00001731 _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" );
jtgafb833d1999-08-19 00:55:39 +00001732 return;
1733 }
1734
1735 ctx->ClientAttribStackDepth--;
Brian Paul37c74af2008-09-04 14:58:02 -06001736 node = ctx->ClientAttribStack[ctx->ClientAttribStackDepth];
jtgafb833d1999-08-19 00:55:39 +00001737
Brian Paul37c74af2008-09-04 14:58:02 -06001738 while (node) {
1739 switch (node->kind) {
jtgafb833d1999-08-19 00:55:39 +00001740 case GL_CLIENT_PACK_BIT:
Brian Paul37c74af2008-09-04 14:58:02 -06001741 {
1742 struct gl_pixelstore_attrib *store =
1743 (struct gl_pixelstore_attrib *) node->data;
1744 copy_pixelstore(ctx, &ctx->Pack, store);
1745 _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL);
Brian Paul7a6b71e2004-03-13 18:21:40 +00001746 }
jtgafb833d1999-08-19 00:55:39 +00001747 break;
1748 case GL_CLIENT_UNPACK_BIT:
Brian Paul37c74af2008-09-04 14:58:02 -06001749 {
1750 struct gl_pixelstore_attrib *store =
1751 (struct gl_pixelstore_attrib *) node->data;
1752 copy_pixelstore(ctx, &ctx->Unpack, store);
1753 _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL);
Brian Paul7a6b71e2004-03-13 18:21:40 +00001754 }
jtgafb833d1999-08-19 00:55:39 +00001755 break;
Ian Romanickee34e6e2006-06-12 16:26:29 +00001756 case GL_CLIENT_VERTEX_ARRAY_BIT: {
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001757 struct gl_array_attrib * attr =
Brian Paul37c74af2008-09-04 14:58:02 -06001758 (struct gl_array_attrib *) node->data;
Mathias Fröhlich597df3e2011-10-19 07:54:20 +02001759 restore_array_attrib(ctx, &ctx->Array, attr);
1760 free_array_attrib_data(ctx, attr);
Brian Paulebc9f222001-08-07 21:46:52 +00001761 ctx->NewState |= _NEW_ARRAY;
jtgafb833d1999-08-19 00:55:39 +00001762 break;
Ian Romanickee34e6e2006-06-12 16:26:29 +00001763 }
jtgafb833d1999-08-19 00:55:39 +00001764 default:
Brian Paul08836342001-03-03 20:33:27 +00001765 _mesa_problem( ctx, "Bad attrib flag in PopClientAttrib");
jtgafb833d1999-08-19 00:55:39 +00001766 break;
1767 }
1768
Brian Paul37c74af2008-09-04 14:58:02 -06001769 next = node->next;
Brian Paulfe72a062012-09-01 07:47:24 -06001770 free(node->data);
1771 free(node);
Brian Paul37c74af2008-09-04 14:58:02 -06001772 node = next;
jtgafb833d1999-08-19 00:55:39 +00001773 }
jtgafb833d1999-08-19 00:55:39 +00001774}
Keith Whitwell6dc85572003-07-17 13:43:59 +00001775
1776
Brian145d7622007-08-16 10:05:00 +01001777/**
1778 * Free any attribute state data that might be attached to the context.
1779 */
1780void
Kristian Høgsbergf9995b32010-10-12 12:26:10 -04001781_mesa_free_attrib_data(struct gl_context *ctx)
Brian145d7622007-08-16 10:05:00 +01001782{
1783 while (ctx->AttribStackDepth > 0) {
1784 struct gl_attrib_node *attr, *next;
1785
1786 ctx->AttribStackDepth--;
1787 attr = ctx->AttribStack[ctx->AttribStackDepth];
1788
1789 while (attr) {
1790 if (attr->kind == GL_TEXTURE_BIT) {
1791 struct texture_state *texstate = (struct texture_state*)attr->data;
Brian0135ff52007-08-16 10:28:23 +01001792 GLuint u, tgt;
Brian145d7622007-08-16 10:05:00 +01001793 /* clear references to the saved texture objects */
1794 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
Brian0135ff52007-08-16 10:28:23 +01001795 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
1796 _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL);
1797 }
Brian145d7622007-08-16 10:05:00 +01001798 }
Brian Paula1471e42012-01-31 18:24:07 -07001799 _mesa_reference_shared_state(ctx, &texstate->SharedRef, NULL);
Brian145d7622007-08-16 10:05:00 +01001800 }
1801 else {
1802 /* any other chunks of state that requires special handling? */
1803 }
1804
1805 next = attr->next;
Kristian Høgsberg32f2fd12010-02-19 11:58:49 -05001806 free(attr->data);
1807 free(attr);
Brian145d7622007-08-16 10:05:00 +01001808 attr = next;
1809 }
1810 }
1811}
1812
1813
Kristian Høgsbergf9995b32010-10-12 12:26:10 -04001814void _mesa_init_attrib( struct gl_context *ctx )
Keith Whitwell6dc85572003-07-17 13:43:59 +00001815{
1816 /* Renderer and client attribute stacks */
1817 ctx->AttribStackDepth = 0;
1818 ctx->ClientAttribStackDepth = 0;
1819}