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