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