state.c revision b527dd65c830a2b008816cf390d5be906e29bb23
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.3 4 * 5 * Copyright (C) 1999-2008 Brian Paul 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 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26/** 27 * \file state.c 28 * State management. 29 * 30 * This file manages recalculation of derived values in struct gl_context. 31 */ 32 33 34#include "glheader.h" 35#include "mtypes.h" 36#include "context.h" 37#include "debug.h" 38#include "macros.h" 39#include "ffvertex_prog.h" 40#include "framebuffer.h" 41#include "light.h" 42#include "matrix.h" 43#include "pixel.h" 44#include "program/program.h" 45#include "program/prog_parameter.h" 46#include "shaderobj.h" 47#include "state.h" 48#include "stencil.h" 49#include "texenvprogram.h" 50#include "texobj.h" 51#include "texstate.h" 52#include "varray.h" 53 54 55static void 56update_separate_specular(struct gl_context *ctx) 57{ 58 if (_mesa_need_secondary_color(ctx)) 59 ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; 60 else 61 ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR; 62} 63 64 65/** 66 * Helper for update_arrays(). 67 * \return min(current min, array->_MaxElement). 68 */ 69static GLuint 70update_min(GLuint min, struct gl_client_array *array) 71{ 72 _mesa_update_array_max_element(array); 73 return MIN2(min, array->_MaxElement); 74} 75 76 77/** 78 * Update ctx->Array._MaxElement (the max legal index into all enabled arrays). 79 * Need to do this upon new array state or new buffer object state. 80 */ 81static void 82update_arrays( struct gl_context *ctx ) 83{ 84 struct gl_array_object *arrayObj = ctx->Array.ArrayObj; 85 GLuint i, min = ~0; 86 87 /* find min of _MaxElement values for all enabled arrays. 88 * Note that the generic arrays always take precedence over 89 * the legacy arrays. 90 */ 91 92 /* 0 */ 93 if (ctx->VertexProgram._Current 94 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) { 95 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0]); 96 } 97 else if (arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { 98 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]); 99 } 100 101 /* 1 */ 102 if (ctx->VertexProgram._Enabled 103 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC1].Enabled) { 104 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC1]); 105 } 106 /* no conventional vertex weight array */ 107 108 /* 2 */ 109 if (ctx->VertexProgram._Enabled 110 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC2].Enabled) { 111 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC2]); 112 } 113 else if (arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { 114 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]); 115 } 116 117 /* 3 */ 118 if (ctx->VertexProgram._Enabled 119 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC3].Enabled) { 120 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC3]); 121 } 122 else if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { 123 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]); 124 } 125 126 /* 4 */ 127 if (ctx->VertexProgram._Enabled 128 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC4].Enabled) { 129 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC4]); 130 } 131 else if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { 132 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]); 133 } 134 135 /* 5 */ 136 if (ctx->VertexProgram._Enabled 137 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC5].Enabled) { 138 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC5]); 139 } 140 else if (arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { 141 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_FOG]); 142 } 143 144 /* 6 */ 145 if (ctx->VertexProgram._Enabled 146 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC6].Enabled) { 147 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC6]); 148 } 149 else if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { 150 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]); 151 } 152 153 /* 7 */ 154 if (ctx->VertexProgram._Enabled 155 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC7].Enabled) { 156 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC7]); 157 } 158 159 /* 8..15 */ 160 for (i = 0; i < VERT_ATTRIB_TEX_MAX; i++) { 161 if (ctx->VertexProgram._Enabled 162 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC8 + i].Enabled) { 163 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC8 + i]); 164 } 165 else if (i < ctx->Const.MaxTextureCoordUnits 166 && arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled) { 167 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)]); 168 } 169 } 170 171 /* 16..31 */ 172 if (ctx->VertexProgram._Current) { 173 for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) { 174 if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) { 175 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)]); 176 } 177 } 178 } 179 180 if (arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { 181 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]); 182 } 183 184 /* _MaxElement is one past the last legal array element */ 185 arrayObj->_MaxElement = min; 186} 187 188 189/** 190 * Update the following fields: 191 * ctx->VertexProgram._Enabled 192 * ctx->FragmentProgram._Enabled 193 * ctx->ATIFragmentShader._Enabled 194 * This needs to be done before texture state validation. 195 */ 196static void 197update_program_enables(struct gl_context *ctx) 198{ 199 /* These _Enabled flags indicate if the user-defined ARB/NV vertex/fragment 200 * program is enabled AND valid. Similarly for ATI fragment shaders. 201 * GLSL shaders not relevant here. 202 */ 203 ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled 204 && ctx->VertexProgram.Current->Base.Instructions; 205 ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled 206 && ctx->FragmentProgram.Current->Base.Instructions; 207 ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled 208 && ctx->ATIFragmentShader.Current->Instructions[0]; 209} 210 211 212/** 213 * Update the ctx->Vertex/Geometry/FragmentProgram._Current pointers to point 214 * to the current/active programs. Then call ctx->Driver.BindProgram() to 215 * tell the driver which programs to use. 216 * 217 * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment 218 * programs or programs derived from fixed-function state. 219 * 220 * This function needs to be called after texture state validation in case 221 * we're generating a fragment program from fixed-function texture state. 222 * 223 * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex 224 * or fragment program is being used. 225 */ 226static GLbitfield 227update_program(struct gl_context *ctx) 228{ 229 const struct gl_shader_program *vsProg = ctx->Shader.CurrentVertexProgram; 230 const struct gl_shader_program *gsProg = ctx->Shader.CurrentGeometryProgram; 231 const struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram; 232 const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current; 233 const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current; 234 const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current; 235 GLbitfield new_state = 0x0; 236 237 /* 238 * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current 239 * pointers to the programs that should be used for rendering. If either 240 * is NULL, use fixed-function code paths. 241 * 242 * These programs may come from several sources. The priority is as 243 * follows: 244 * 1. OpenGL 2.0/ARB vertex/fragment shaders 245 * 2. ARB/NV vertex/fragment programs 246 * 3. Programs derived from fixed-function state. 247 * 248 * Note: it's possible for a vertex shader to get used with a fragment 249 * program (and vice versa) here, but in practice that shouldn't ever 250 * come up, or matter. 251 */ 252 253 if (fsProg && fsProg->LinkStatus 254 && fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) { 255 /* Use GLSL fragment shader */ 256 _mesa_reference_shader_program(ctx, 257 &ctx->Shader._CurrentFragmentProgram, 258 fsProg); 259 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, 260 (struct gl_fragment_program *) 261 fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); 262 } 263 else if (ctx->FragmentProgram._Enabled) { 264 /* Use user-defined fragment program */ 265 _mesa_reference_shader_program(ctx, 266 &ctx->Shader._CurrentFragmentProgram, 267 NULL); 268 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, 269 ctx->FragmentProgram.Current); 270 } 271 else if (ctx->FragmentProgram._MaintainTexEnvProgram) { 272 /* Use fragment program generated from fixed-function state */ 273 struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx); 274 275 _mesa_reference_shader_program(ctx, 276 &ctx->Shader._CurrentFragmentProgram, 277 f); 278 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, 279 (struct gl_fragment_program *) 280 f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); 281 } 282 else { 283 /* No fragment program */ 284 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); 285 } 286 287 if (gsProg && gsProg->LinkStatus 288 && gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) { 289 /* Use GLSL geometry shader */ 290 _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, 291 (struct gl_geometry_program *) 292 gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program); 293 } else { 294 /* No geometry program */ 295 _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL); 296 } 297 298 /* Examine vertex program after fragment program as 299 * _mesa_get_fixed_func_vertex_program() needs to know active 300 * fragprog inputs. 301 */ 302 if (vsProg && vsProg->LinkStatus 303 && vsProg->_LinkedShaders[MESA_SHADER_VERTEX]) { 304 /* Use GLSL vertex shader */ 305 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, 306 (struct gl_vertex_program *) 307 vsProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program); 308 } 309 else if (ctx->VertexProgram._Enabled) { 310 /* Use user-defined vertex program */ 311 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, 312 ctx->VertexProgram.Current); 313 } 314 else if (ctx->VertexProgram._MaintainTnlProgram) { 315 /* Use vertex program generated from fixed-function state */ 316 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, 317 _mesa_get_fixed_func_vertex_program(ctx)); 318 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, 319 ctx->VertexProgram._Current); 320 } 321 else { 322 /* no vertex program */ 323 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); 324 } 325 326 /* Let the driver know what's happening: 327 */ 328 if (ctx->FragmentProgram._Current != prevFP) { 329 new_state |= _NEW_PROGRAM; 330 if (ctx->Driver.BindProgram) { 331 ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 332 (struct gl_program *) ctx->FragmentProgram._Current); 333 } 334 } 335 336 if (ctx->GeometryProgram._Current != prevGP) { 337 new_state |= _NEW_PROGRAM; 338 if (ctx->Driver.BindProgram) { 339 ctx->Driver.BindProgram(ctx, MESA_GEOMETRY_PROGRAM, 340 (struct gl_program *) ctx->GeometryProgram._Current); 341 } 342 } 343 344 if (ctx->VertexProgram._Current != prevVP) { 345 new_state |= _NEW_PROGRAM; 346 if (ctx->Driver.BindProgram) { 347 ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, 348 (struct gl_program *) ctx->VertexProgram._Current); 349 } 350 } 351 352 return new_state; 353} 354 355 356/** 357 * Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0. 358 */ 359static GLbitfield 360update_program_constants(struct gl_context *ctx) 361{ 362 GLbitfield new_state = 0x0; 363 364 if (ctx->FragmentProgram._Current) { 365 const struct gl_program_parameter_list *params = 366 ctx->FragmentProgram._Current->Base.Parameters; 367 if (params && params->StateFlags & ctx->NewState) { 368 new_state |= _NEW_PROGRAM_CONSTANTS; 369 } 370 } 371 372 if (ctx->GeometryProgram._Current) { 373 const struct gl_program_parameter_list *params = 374 ctx->GeometryProgram._Current->Base.Parameters; 375 /*FIXME: StateFlags is always 0 because we have unnamed constant 376 * not state changes */ 377 if (params /*&& params->StateFlags & ctx->NewState*/) { 378 new_state |= _NEW_PROGRAM_CONSTANTS; 379 } 380 } 381 382 if (ctx->VertexProgram._Current) { 383 const struct gl_program_parameter_list *params = 384 ctx->VertexProgram._Current->Base.Parameters; 385 if (params && params->StateFlags & ctx->NewState) { 386 new_state |= _NEW_PROGRAM_CONSTANTS; 387 } 388 } 389 390 return new_state; 391} 392 393 394 395 396static void 397update_viewport_matrix(struct gl_context *ctx) 398{ 399 const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; 400 401 ASSERT(depthMax > 0); 402 403 /* Compute scale and bias values. This is really driver-specific 404 * and should be maintained elsewhere if at all. 405 * NOTE: RasterPos uses this. 406 */ 407 _math_matrix_viewport(&ctx->Viewport._WindowMap, 408 ctx->Viewport.X, ctx->Viewport.Y, 409 ctx->Viewport.Width, ctx->Viewport.Height, 410 ctx->Viewport.Near, ctx->Viewport.Far, 411 depthMax); 412} 413 414 415/** 416 * Update derived multisample state. 417 */ 418static void 419update_multisample(struct gl_context *ctx) 420{ 421 ctx->Multisample._Enabled = GL_FALSE; 422 if (ctx->Multisample.Enabled && 423 ctx->DrawBuffer && 424 ctx->DrawBuffer->Visual.sampleBuffers) 425 ctx->Multisample._Enabled = GL_TRUE; 426} 427 428 429/** 430 * Update the ctx->Color._ClampFragmentColor field 431 */ 432static void 433update_clamp_fragment_color(struct gl_context *ctx) 434{ 435 if (ctx->Color.ClampFragmentColor == GL_FIXED_ONLY_ARB) 436 ctx->Color._ClampFragmentColor = 437 !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode; 438 else 439 ctx->Color._ClampFragmentColor = ctx->Color.ClampFragmentColor; 440} 441 442 443/** 444 * Update the ctx->Color._ClampVertexColor field 445 */ 446static void 447update_clamp_vertex_color(struct gl_context *ctx) 448{ 449 if (ctx->Light.ClampVertexColor == GL_FIXED_ONLY_ARB) 450 ctx->Light._ClampVertexColor = 451 !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode; 452 else 453 ctx->Light._ClampVertexColor = ctx->Light.ClampVertexColor; 454} 455 456 457/** 458 * Update the ctx->Color._ClampReadColor field 459 */ 460static void 461update_clamp_read_color(struct gl_context *ctx) 462{ 463 if (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB) 464 ctx->Color._ClampReadColor = 465 !ctx->ReadBuffer || !ctx->ReadBuffer->Visual.floatMode; 466 else 467 ctx->Color._ClampReadColor = ctx->Color.ClampReadColor; 468} 469 470/** 471 * Update the ctx->VertexProgram._TwoSideEnabled flag. 472 */ 473static void 474update_twoside(struct gl_context *ctx) 475{ 476 if (ctx->Shader.CurrentVertexProgram || 477 ctx->VertexProgram._Enabled) { 478 ctx->VertexProgram._TwoSideEnabled = ctx->VertexProgram.TwoSideEnabled; 479 } else { 480 ctx->VertexProgram._TwoSideEnabled = (ctx->Light.Enabled && 481 ctx->Light.Model.TwoSide); 482 } 483} 484 485 486/* 487 * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET 488 * in ctx->_TriangleCaps if needed. 489 */ 490static void 491update_polygon(struct gl_context *ctx) 492{ 493 ctx->_TriangleCaps &= ~(DD_TRI_CULL_FRONT_BACK | DD_TRI_OFFSET); 494 495 if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) 496 ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; 497 498 if ( ctx->Polygon.OffsetPoint 499 || ctx->Polygon.OffsetLine 500 || ctx->Polygon.OffsetFill) 501 ctx->_TriangleCaps |= DD_TRI_OFFSET; 502} 503 504 505/** 506 * Update the ctx->_TriangleCaps bitfield. 507 * XXX that bitfield should really go away someday! 508 * This function must be called after other update_*() functions since 509 * there are dependencies on some other derived values. 510 */ 511#if 0 512static void 513update_tricaps(struct gl_context *ctx, GLbitfield new_state) 514{ 515 ctx->_TriangleCaps = 0; 516 517 /* 518 * Points 519 */ 520 if (1/*new_state & _NEW_POINT*/) { 521 if (ctx->Point.SmoothFlag) 522 ctx->_TriangleCaps |= DD_POINT_SMOOTH; 523 if (ctx->Point._Attenuated) 524 ctx->_TriangleCaps |= DD_POINT_ATTEN; 525 } 526 527 /* 528 * Lines 529 */ 530 if (1/*new_state & _NEW_LINE*/) { 531 if (ctx->Line.SmoothFlag) 532 ctx->_TriangleCaps |= DD_LINE_SMOOTH; 533 if (ctx->Line.StippleFlag) 534 ctx->_TriangleCaps |= DD_LINE_STIPPLE; 535 } 536 537 /* 538 * Polygons 539 */ 540 if (1/*new_state & _NEW_POLYGON*/) { 541 if (ctx->Polygon.SmoothFlag) 542 ctx->_TriangleCaps |= DD_TRI_SMOOTH; 543 if (ctx->Polygon.StippleFlag) 544 ctx->_TriangleCaps |= DD_TRI_STIPPLE; 545 if (ctx->Polygon.FrontMode != GL_FILL 546 || ctx->Polygon.BackMode != GL_FILL) 547 ctx->_TriangleCaps |= DD_TRI_UNFILLED; 548 if (ctx->Polygon.CullFlag 549 && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) 550 ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; 551 if (ctx->Polygon.OffsetPoint || 552 ctx->Polygon.OffsetLine || 553 ctx->Polygon.OffsetFill) 554 ctx->_TriangleCaps |= DD_TRI_OFFSET; 555 } 556 557 /* 558 * Lighting and shading 559 */ 560 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) 561 ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; 562 if (ctx->Light.ShadeModel == GL_FLAT) 563 ctx->_TriangleCaps |= DD_FLATSHADE; 564 if (_mesa_need_secondary_color(ctx)) 565 ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; 566 567 /* 568 * Stencil 569 */ 570 if (ctx->Stencil._TestTwoSide) 571 ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL; 572} 573#endif 574 575 576/** 577 * Compute derived GL state. 578 * If __struct gl_contextRec::NewState is non-zero then this function \b must 579 * be called before rendering anything. 580 * 581 * Calls dd_function_table::UpdateState to perform any internal state 582 * management necessary. 583 * 584 * \sa _mesa_update_modelview_project(), _mesa_update_texture(), 585 * _mesa_update_buffer_bounds(), 586 * _mesa_update_lighting() and _mesa_update_tnl_spaces(). 587 */ 588void 589_mesa_update_state_locked( struct gl_context *ctx ) 590{ 591 GLbitfield new_state = ctx->NewState; 592 GLbitfield prog_flags = _NEW_PROGRAM; 593 GLbitfield new_prog_state = 0x0; 594 595 if (new_state == _NEW_CURRENT_ATTRIB) 596 goto out; 597 598 if (MESA_VERBOSE & VERBOSE_STATE) 599 _mesa_print_state("_mesa_update_state", new_state); 600 601 /* Determine which state flags effect vertex/fragment program state */ 602 if (ctx->FragmentProgram._MaintainTexEnvProgram) { 603 prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG | 604 _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE | 605 _NEW_PROGRAM | _NEW_FRAG_CLAMP | _NEW_COLOR); 606 } 607 if (ctx->VertexProgram._MaintainTnlProgram) { 608 prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | 609 _NEW_TRANSFORM | _NEW_POINT | 610 _NEW_FOG | _NEW_LIGHT | 611 _MESA_NEW_NEED_EYE_COORDS); 612 } 613 614 /* 615 * Now update derived state info 616 */ 617 618 if (new_state & prog_flags) 619 update_program_enables( ctx ); 620 621 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) 622 _mesa_update_modelview_project( ctx, new_state ); 623 624 if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) 625 _mesa_update_texture( ctx, new_state ); 626 627 if (new_state & _NEW_BUFFERS) 628 _mesa_update_framebuffer(ctx); 629 630 if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT)) 631 _mesa_update_draw_buffer_bounds( ctx ); 632 633 if (new_state & _NEW_POLYGON) 634 update_polygon( ctx ); 635 636 if (new_state & _NEW_LIGHT) 637 _mesa_update_lighting( ctx ); 638 639 if (new_state & (_NEW_LIGHT | _NEW_PROGRAM)) 640 update_twoside( ctx ); 641 642 if (new_state & (_NEW_LIGHT | _NEW_BUFFERS)) 643 update_clamp_vertex_color(ctx); 644 645 if (new_state & (_NEW_STENCIL | _NEW_BUFFERS)) 646 _mesa_update_stencil( ctx ); 647 648 if (new_state & _NEW_PIXEL) 649 _mesa_update_pixel( ctx, new_state ); 650 651 if (new_state & _DD_NEW_SEPARATE_SPECULAR) 652 update_separate_specular( ctx ); 653 654 if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT)) 655 update_viewport_matrix(ctx); 656 657 if (new_state & (_NEW_MULTISAMPLE | _NEW_BUFFERS)) 658 update_multisample( ctx ); 659 660 if (new_state & (_NEW_COLOR | _NEW_BUFFERS)) 661 update_clamp_read_color(ctx); 662 663 if(new_state & (_NEW_FRAG_CLAMP | _NEW_BUFFERS)) 664 update_clamp_fragment_color(ctx); 665 666#if 0 667 if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT 668 | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR)) 669 update_tricaps( ctx, new_state ); 670#endif 671 672 /* ctx->_NeedEyeCoords is now up to date. 673 * 674 * If the truth value of this variable has changed, update for the 675 * new lighting space and recompute the positions of lights and the 676 * normal transform. 677 * 678 * If the lighting space hasn't changed, may still need to recompute 679 * light positions & normal transforms for other reasons. 680 */ 681 if (new_state & _MESA_NEW_NEED_EYE_COORDS) 682 _mesa_update_tnl_spaces( ctx, new_state ); 683 684 if (new_state & prog_flags) { 685 /* When we generate programs from fixed-function vertex/fragment state 686 * this call may generate/bind a new program. If so, we need to 687 * propogate the _NEW_PROGRAM flag to the driver. 688 */ 689 new_prog_state |= update_program( ctx ); 690 } 691 692 if (new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) 693 update_arrays( ctx ); 694 695 out: 696 new_prog_state |= update_program_constants(ctx); 697 698 /* 699 * Give the driver a chance to act upon the new_state flags. 700 * The driver might plug in different span functions, for example. 701 * Also, this is where the driver can invalidate the state of any 702 * active modules (such as swrast_setup, swrast, tnl, etc). 703 * 704 * Set ctx->NewState to zero to avoid recursion if 705 * Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?) 706 */ 707 new_state = ctx->NewState | new_prog_state; 708 ctx->NewState = 0; 709 ctx->Driver.UpdateState(ctx, new_state); 710 ctx->Array.NewState = 0; 711 if (!ctx->Array.RebindArrays) 712 ctx->Array.RebindArrays = (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) != 0; 713} 714 715 716/* This is the usual entrypoint for state updates: 717 */ 718void 719_mesa_update_state( struct gl_context *ctx ) 720{ 721 _mesa_lock_context_textures(ctx); 722 _mesa_update_state_locked(ctx); 723 _mesa_unlock_context_textures(ctx); 724} 725 726 727 728 729/** 730 * Want to figure out which fragment program inputs are actually 731 * constant/current values from ctx->Current. These should be 732 * referenced as a tracked state variable rather than a fragment 733 * program input, to save the overhead of putting a constant value in 734 * every submitted vertex, transferring it to hardware, interpolating 735 * it across the triangle, etc... 736 * 737 * When there is a VP bound, just use vp->outputs. But when we're 738 * generating vp from fixed function state, basically want to 739 * calculate: 740 * 741 * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) | 742 * potential_vp_outputs ) 743 * 744 * Where potential_vp_outputs is calculated by looking at enabled 745 * texgen, etc. 746 * 747 * The generated fragment program should then only declare inputs that 748 * may vary or otherwise differ from the ctx->Current values. 749 * Otherwise, the fp should track them as state values instead. 750 */ 751void 752_mesa_set_varying_vp_inputs( struct gl_context *ctx, 753 GLbitfield64 varying_inputs ) 754{ 755 if (ctx->varying_vp_inputs != varying_inputs) { 756 ctx->varying_vp_inputs = varying_inputs; 757 ctx->NewState |= _NEW_ARRAY; 758 /*printf("%s %x\n", __FUNCTION__, varying_inputs);*/ 759 } 760} 761 762 763/** 764 * Used by drivers to tell core Mesa that the driver is going to 765 * install/ use its own vertex program. In particular, this will 766 * prevent generated fragment programs from using state vars instead 767 * of ordinary varyings/inputs. 768 */ 769void 770_mesa_set_vp_override(struct gl_context *ctx, GLboolean flag) 771{ 772 if (ctx->VertexProgram._Overriden != flag) { 773 ctx->VertexProgram._Overriden = flag; 774 775 /* Set one of the bits which will trigger fragment program 776 * regeneration: 777 */ 778 ctx->NewState |= _NEW_PROGRAM; 779 } 780} 781