1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * 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 "arrayobj.h" 37#include "context.h" 38#include "debug.h" 39#include "macros.h" 40#include "ffvertex_prog.h" 41#include "framebuffer.h" 42#include "light.h" 43#include "matrix.h" 44#include "pixel.h" 45#include "program/program.h" 46#include "program/prog_parameter.h" 47#include "shaderobj.h" 48#include "state.h" 49#include "stencil.h" 50#include "texenvprogram.h" 51#include "texobj.h" 52#include "texstate.h" 53#include "varray.h" 54#include "vbo/vbo.h" 55#include "viewport.h" 56#include "blend.h" 57 58 59void 60_mesa_update_allow_draw_out_of_order(struct gl_context *ctx) 61{ 62 /* Out-of-order drawing is useful when vertex array draws and immediate 63 * mode are interleaved. 64 * 65 * Example with 3 draws: 66 * glBegin(); 67 * glVertex(); 68 * glEnd(); 69 * glDrawElements(); 70 * glBegin(); 71 * glVertex(); 72 * glEnd(); 73 * 74 * Out-of-order drawing changes the execution order like this: 75 * glDrawElements(); 76 * glBegin(); 77 * glVertex(); 78 * glVertex(); 79 * glEnd(); 80 * 81 * If out-of-order draws are enabled, immediate mode vertices are not 82 * flushed before glDrawElements, resulting in fewer draws and lower CPU 83 * overhead. This helps workstation applications. 84 * 85 * This is a simplified version of out-of-order determination to catch 86 * common cases. 87 * 88 * RadeonSI has a complete and more complicated out-of-order determination 89 * for driver-internal reasons. 90 */ 91 /* Only the compatibility profile with immediate mode needs this. */ 92 if (ctx->API != API_OPENGL_COMPAT || !ctx->Const.AllowDrawOutOfOrder) 93 return; 94 95 /* If all of these are NULL, GLSL is disabled. */ 96 struct gl_program *vs = 97 ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; 98 struct gl_program *tcs = 99 ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; 100 struct gl_program *tes = 101 ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; 102 struct gl_program *gs = 103 ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; 104 struct gl_program *fs = 105 ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; 106 GLenum16 depth_func = ctx->Depth.Func; 107 108 /* Z fighting and any primitives with equal Z shouldn't be reordered 109 * with LESS/LEQUAL/GREATER/GEQUAL functions. 110 * 111 * When drawing 2 primitive with equal Z: 112 * - with LEQUAL/GEQUAL, the last primitive wins the Z test. 113 * - with LESS/GREATER, the first primitive wins the Z test. 114 * 115 * Here we ignore that on the basis that such cases don't occur in real 116 * apps, and we they do occur, they occur with blending where out-of-order 117 * drawing is always disabled. 118 */ 119 bool previous_state = ctx->_AllowDrawOutOfOrder; 120 ctx->_AllowDrawOutOfOrder = 121 ctx->DrawBuffer && 122 ctx->DrawBuffer->Visual.depthBits && 123 ctx->Depth.Test && 124 ctx->Depth.Mask && 125 (depth_func == GL_NEVER || 126 depth_func == GL_LESS || 127 depth_func == GL_LEQUAL || 128 depth_func == GL_GREATER || 129 depth_func == GL_GEQUAL) && 130 (!ctx->DrawBuffer->Visual.stencilBits || 131 !ctx->Stencil.Enabled) && 132 (!ctx->Color.ColorMask || 133 (!ctx->Color.BlendEnabled && 134 (!ctx->Color.ColorLogicOpEnabled || 135 ctx->Color._LogicOp == COLOR_LOGICOP_COPY))) && 136 (!vs || !vs->info.writes_memory) && 137 (!tes || !tes->info.writes_memory) && 138 (!tcs || !tcs->info.writes_memory) && 139 (!gs || !gs->info.writes_memory) && 140 (!fs || !fs->info.writes_memory || !fs->info.fs.early_fragment_tests); 141 142 /* If we are disabling out-of-order drawing, we need to flush queued 143 * vertices. 144 */ 145 if (previous_state && !ctx->_AllowDrawOutOfOrder) 146 FLUSH_VERTICES(ctx, 0, 0); 147} 148 149 150/** 151 * Update the ctx->*Program._Current pointers to point to the 152 * current/active programs. 153 * 154 * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment 155 * programs or programs derived from fixed-function state. 156 * 157 * This function needs to be called after texture state validation in case 158 * we're generating a fragment program from fixed-function texture state. 159 * 160 * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex 161 * or fragment program is being used. 162 */ 163static GLbitfield 164update_program(struct gl_context *ctx) 165{ 166 struct gl_program *vsProg = 167 ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; 168 struct gl_program *tcsProg = 169 ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; 170 struct gl_program *tesProg = 171 ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; 172 struct gl_program *gsProg = 173 ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; 174 struct gl_program *fsProg = 175 ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; 176 struct gl_program *csProg = 177 ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; 178 const struct gl_program *prevVP = ctx->VertexProgram._Current; 179 const struct gl_program *prevFP = ctx->FragmentProgram._Current; 180 const struct gl_program *prevGP = ctx->GeometryProgram._Current; 181 const struct gl_program *prevTCP = ctx->TessCtrlProgram._Current; 182 const struct gl_program *prevTEP = ctx->TessEvalProgram._Current; 183 const struct gl_program *prevCP = ctx->ComputeProgram._Current; 184 185 /* 186 * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current 187 * pointers to the programs that should be used for rendering. If either 188 * is NULL, use fixed-function code paths. 189 * 190 * These programs may come from several sources. The priority is as 191 * follows: 192 * 1. OpenGL 2.0/ARB vertex/fragment shaders 193 * 2. ARB/NV vertex/fragment programs 194 * 3. ATI fragment shader 195 * 4. Programs derived from fixed-function state. 196 * 197 * Note: it's possible for a vertex shader to get used with a fragment 198 * program (and vice versa) here, but in practice that shouldn't ever 199 * come up, or matter. 200 */ 201 202 if (fsProg) { 203 /* Use GLSL fragment shader */ 204 _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, fsProg); 205 _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 206 NULL); 207 } 208 else if (_mesa_arb_fragment_program_enabled(ctx)) { 209 /* Use user-defined fragment program */ 210 _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, 211 ctx->FragmentProgram.Current); 212 _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 213 NULL); 214 } 215 else if (_mesa_ati_fragment_shader_enabled(ctx) && 216 ctx->ATIFragmentShader.Current->Program) { 217 /* Use the enabled ATI fragment shader's associated program */ 218 _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, 219 ctx->ATIFragmentShader.Current->Program); 220 _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 221 NULL); 222 } 223 else if (ctx->FragmentProgram._MaintainTexEnvProgram) { 224 /* Use fragment program generated from fixed-function state */ 225 struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx); 226 227 _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, 228 f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); 229 _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 230 f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); 231 } 232 else { 233 /* No fragment program */ 234 _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, NULL); 235 _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 236 NULL); 237 } 238 239 if (gsProg) { 240 /* Use GLSL geometry shader */ 241 _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, gsProg); 242 } else { 243 /* No geometry program */ 244 _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL); 245 } 246 247 if (tesProg) { 248 /* Use GLSL tessellation evaluation shader */ 249 _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, tesProg); 250 } 251 else { 252 /* No tessellation evaluation program */ 253 _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL); 254 } 255 256 if (tcsProg) { 257 /* Use GLSL tessellation control shader */ 258 _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, tcsProg); 259 } 260 else { 261 /* No tessellation control program */ 262 _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, NULL); 263 } 264 265 /* Examine vertex program after fragment program as 266 * _mesa_get_fixed_func_vertex_program() needs to know active 267 * fragprog inputs. 268 */ 269 if (vsProg) { 270 /* Use GLSL vertex shader */ 271 assert(VP_MODE_SHADER == ctx->VertexProgram._VPMode); 272 _mesa_reference_program(ctx, &ctx->VertexProgram._Current, vsProg); 273 } 274 else if (_mesa_arb_vertex_program_enabled(ctx)) { 275 /* Use user-defined vertex program */ 276 assert(VP_MODE_SHADER == ctx->VertexProgram._VPMode); 277 _mesa_reference_program(ctx, &ctx->VertexProgram._Current, 278 ctx->VertexProgram.Current); 279 } 280 else if (ctx->VertexProgram._MaintainTnlProgram) { 281 /* Use vertex program generated from fixed-function state */ 282 assert(VP_MODE_FF == ctx->VertexProgram._VPMode); 283 _mesa_reference_program(ctx, &ctx->VertexProgram._Current, 284 _mesa_get_fixed_func_vertex_program(ctx)); 285 _mesa_reference_program(ctx, &ctx->VertexProgram._TnlProgram, 286 ctx->VertexProgram._Current); 287 } 288 else { 289 /* no vertex program */ 290 assert(VP_MODE_FF == ctx->VertexProgram._VPMode); 291 _mesa_reference_program(ctx, &ctx->VertexProgram._Current, NULL); 292 } 293 294 if (csProg) { 295 /* Use GLSL compute shader */ 296 _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, csProg); 297 } else { 298 /* no compute program */ 299 _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, NULL); 300 } 301 302 /* Let the driver know what's happening: 303 */ 304 if (ctx->FragmentProgram._Current != prevFP || 305 ctx->VertexProgram._Current != prevVP || 306 ctx->GeometryProgram._Current != prevGP || 307 ctx->TessEvalProgram._Current != prevTEP || 308 ctx->TessCtrlProgram._Current != prevTCP || 309 ctx->ComputeProgram._Current != prevCP) 310 return _NEW_PROGRAM; 311 312 return 0; 313} 314 315 316static GLbitfield 317update_single_program_constants(struct gl_context *ctx, 318 struct gl_program *prog, 319 gl_shader_stage stage) 320{ 321 if (prog) { 322 const struct gl_program_parameter_list *params = prog->Parameters; 323 if (params && params->StateFlags & ctx->NewState) { 324 if (ctx->DriverFlags.NewShaderConstants[stage]) 325 ctx->NewDriverState |= ctx->DriverFlags.NewShaderConstants[stage]; 326 else 327 return _NEW_PROGRAM_CONSTANTS; 328 } 329 } 330 return 0; 331} 332 333 334/** 335 * This updates fixed-func state constants such as gl_ModelViewMatrix. 336 * Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0. 337 */ 338static GLbitfield 339update_program_constants(struct gl_context *ctx) 340{ 341 GLbitfield new_state = 342 update_single_program_constants(ctx, ctx->VertexProgram._Current, 343 MESA_SHADER_VERTEX) | 344 update_single_program_constants(ctx, ctx->FragmentProgram._Current, 345 MESA_SHADER_FRAGMENT); 346 347 if (ctx->API == API_OPENGL_COMPAT && 348 ctx->Const.GLSLVersionCompat >= 150) { 349 new_state |= 350 update_single_program_constants(ctx, ctx->GeometryProgram._Current, 351 MESA_SHADER_GEOMETRY); 352 353 if (_mesa_has_ARB_tessellation_shader(ctx)) { 354 new_state |= 355 update_single_program_constants(ctx, ctx->TessCtrlProgram._Current, 356 MESA_SHADER_TESS_CTRL) | 357 update_single_program_constants(ctx, ctx->TessEvalProgram._Current, 358 MESA_SHADER_TESS_EVAL); 359 } 360 } 361 362 return new_state; 363} 364 365 366static void 367update_fixed_func_program_usage(struct gl_context *ctx) 368{ 369 ctx->FragmentProgram._UsesTexEnvProgram = 370 ctx->FragmentProgram._MaintainTexEnvProgram && 371 !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] && /* GLSL*/ 372 !_mesa_arb_fragment_program_enabled(ctx) && 373 !(_mesa_ati_fragment_shader_enabled(ctx) && 374 ctx->ATIFragmentShader.Current->Program); 375 376 ctx->VertexProgram._UsesTnlProgram = 377 ctx->VertexProgram._MaintainTnlProgram && 378 !ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] && /* GLSL */ 379 !_mesa_arb_vertex_program_enabled(ctx); 380} 381 382 383/** 384 * Compute derived GL state. 385 * If __struct gl_contextRec::NewState is non-zero then this function \b must 386 * be called before rendering anything. 387 * 388 * Calls dd_function_table::UpdateState to perform any internal state 389 * management necessary. 390 * 391 * \sa _mesa_update_modelview_project(), _mesa_update_texture(), 392 * _mesa_update_buffer_bounds(), 393 * _mesa_update_lighting() and _mesa_update_tnl_spaces(). 394 */ 395void 396_mesa_update_state_locked( struct gl_context *ctx ) 397{ 398 GLbitfield new_state = ctx->NewState; 399 GLbitfield new_prog_state = 0x0; 400 const GLbitfield checked_states = 401 _NEW_BUFFERS | _NEW_MODELVIEW | _NEW_PROJECTION | _NEW_TEXTURE_MATRIX | 402 _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE | _NEW_PROGRAM | 403 _NEW_LIGHT_CONSTANTS | _NEW_POINT | _NEW_FF_VERT_PROGRAM | 404 _NEW_FF_FRAG_PROGRAM | _NEW_TNL_SPACES; 405 406 /* we can skip a bunch of state validation checks if the dirty 407 * state matches one or more bits in 'computed_states'. 408 */ 409 if (!(new_state & checked_states)) 410 goto out; 411 412 if (MESA_VERBOSE & VERBOSE_STATE) 413 _mesa_print_state("_mesa_update_state", new_state); 414 415 if (new_state & _NEW_BUFFERS) 416 _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer); 417 418 /* Handle Core and Compatibility contexts separately. */ 419 if (ctx->API == API_OPENGL_COMPAT || 420 ctx->API == API_OPENGLES) { 421 /* Update derived state. */ 422 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) 423 _mesa_update_modelview_project( ctx, new_state ); 424 425 if (new_state & _NEW_TEXTURE_MATRIX) 426 new_state |= _mesa_update_texture_matrices(ctx); 427 428 if (new_state & (_NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE | _NEW_PROGRAM)) 429 new_state |= _mesa_update_texture_state(ctx); 430 431 if (new_state & _NEW_LIGHT_CONSTANTS) 432 new_state |= _mesa_update_lighting(ctx); 433 434 /* ctx->_NeedEyeCoords is determined here. 435 * 436 * If the truth value of this variable has changed, update for the 437 * new lighting space and recompute the positions of lights and the 438 * normal transform. 439 * 440 * If the lighting space hasn't changed, may still need to recompute 441 * light positions & normal transforms for other reasons. 442 */ 443 if (new_state & (_NEW_TNL_SPACES | _NEW_LIGHT_CONSTANTS | 444 _NEW_MODELVIEW)) { 445 if (_mesa_update_tnl_spaces(ctx, new_state)) 446 new_state |= _NEW_FF_VERT_PROGRAM; 447 } 448 449 if (new_state & _NEW_PROGRAM) 450 update_fixed_func_program_usage(ctx); 451 452 /* Determine which states affect fixed-func vertex/fragment program. */ 453 GLbitfield prog_flags = _NEW_PROGRAM; 454 455 if (ctx->FragmentProgram._UsesTexEnvProgram) { 456 prog_flags |= _NEW_BUFFERS | _NEW_TEXTURE_OBJECT | 457 _NEW_FF_FRAG_PROGRAM | _NEW_TEXTURE_STATE; 458 } 459 460 if (ctx->VertexProgram._UsesTnlProgram) 461 prog_flags |= _NEW_FF_VERT_PROGRAM; 462 463 if (new_state & prog_flags) { 464 /* When we generate programs from fixed-function vertex/fragment state 465 * this call may generate/bind a new program. If so, we need to 466 * propogate the _NEW_PROGRAM flag to the driver. 467 */ 468 new_prog_state |= update_program(ctx); 469 } 470 } else { 471 /* GL Core and GLES 2/3 contexts */ 472 if (new_state & (_NEW_TEXTURE_OBJECT | _NEW_PROGRAM)) 473 _mesa_update_texture_state(ctx); 474 475 if (new_state & _NEW_PROGRAM) 476 update_program(ctx); 477 } 478 479 out: 480 new_prog_state |= update_program_constants(ctx); 481 482 ctx->NewState |= new_prog_state; 483 484 /* 485 * Give the driver a chance to act upon the new_state flags. 486 * The driver might plug in different span functions, for example. 487 * Also, this is where the driver can invalidate the state of any 488 * active modules (such as swrast_setup, swrast, tnl, etc). 489 */ 490 ctx->Driver.UpdateState(ctx); 491 ctx->NewState = 0; 492} 493 494 495/* This is the usual entrypoint for state updates: 496 */ 497void 498_mesa_update_state( struct gl_context *ctx ) 499{ 500 _mesa_lock_context_textures(ctx); 501 _mesa_update_state_locked(ctx); 502 _mesa_unlock_context_textures(ctx); 503} 504 505 506/** 507 * Used by drivers to tell core Mesa that the driver is going to 508 * install/ use its own vertex program. In particular, this will 509 * prevent generated fragment programs from using state vars instead 510 * of ordinary varyings/inputs. 511 */ 512void 513_mesa_set_vp_override(struct gl_context *ctx, GLboolean flag) 514{ 515 if (ctx->VertexProgram._Overriden != flag) { 516 ctx->VertexProgram._Overriden = flag; 517 518 /* Set one of the bits which will trigger fragment program 519 * regeneration: 520 */ 521 ctx->NewState |= _NEW_PROGRAM; 522 } 523} 524 525 526static void 527set_vertex_processing_mode(struct gl_context *ctx, gl_vertex_processing_mode m) 528{ 529 if (ctx->VertexProgram._VPMode == m) 530 return; 531 532 /* On change we may get new maps into the current values */ 533 ctx->NewDriverState |= ctx->DriverFlags.NewArray; 534 535 /* Finally memorize the value */ 536 ctx->VertexProgram._VPMode = m; 537 538 /* The gl_context::VertexProgram._VaryingInputs value is only used when in 539 * VP_MODE_FF mode and the fixed-func pipeline is emulated by shaders. 540 */ 541 ctx->VertexProgram._VPModeOptimizesConstantAttribs = 542 m == VP_MODE_FF && 543 ctx->VertexProgram._MaintainTnlProgram && 544 ctx->FragmentProgram._MaintainTexEnvProgram; 545 546 /* Set a filter mask for the net enabled vao arrays. 547 * This is to mask out arrays that would otherwise supersede required current 548 * values for the fixed function shaders for example. 549 */ 550 switch (m) { 551 case VP_MODE_FF: 552 /* When no vertex program is active (or the vertex program is generated 553 * from fixed-function state). We put the material values into the 554 * generic slots. Since the vao has no material arrays, mute these 555 * slots from the enabled arrays so that the current material values 556 * are pulled instead of the vao arrays. 557 */ 558 ctx->VertexProgram._VPModeInputFilter = VERT_BIT_FF_ALL; 559 break; 560 561 case VP_MODE_SHADER: 562 /* There are no shaders in OpenGL ES 1.x, so this code path should be 563 * impossible to reach. The meta code is careful to not use shaders in 564 * ES1. 565 */ 566 assert(ctx->API != API_OPENGLES); 567 568 /* Other parts of the code assume that inputs[VERT_ATTRIB_POS] through 569 * inputs[VERT_ATTRIB_GENERIC0-1] will be non-NULL. However, in OpenGL 570 * ES 2.0+ or OpenGL core profile, none of these arrays should ever 571 * be enabled. 572 */ 573 if (ctx->API == API_OPENGL_COMPAT) 574 ctx->VertexProgram._VPModeInputFilter = VERT_BIT_ALL; 575 else 576 ctx->VertexProgram._VPModeInputFilter = VERT_BIT_GENERIC_ALL; 577 break; 578 579 default: 580 assert(0); 581 } 582 583 /* Since we only track the varying inputs while being in fixed function 584 * vertex processing mode, we may need to update fixed-func shaders 585 * for zero-stride vertex attribs. 586 */ 587 _mesa_set_varying_vp_inputs(ctx, ctx->Array._DrawVAOEnabledAttribs); 588} 589 590 591/** 592 * Update ctx->VertexProgram._VPMode. 593 * This is to distinguish whether we're running 594 * a vertex program/shader, 595 * a fixed-function TNL program or 596 * a fixed function vertex transformation without any program. 597 */ 598void 599_mesa_update_vertex_processing_mode(struct gl_context *ctx) 600{ 601 if (ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]) 602 set_vertex_processing_mode(ctx, VP_MODE_SHADER); 603 else if (_mesa_arb_vertex_program_enabled(ctx)) 604 set_vertex_processing_mode(ctx, VP_MODE_SHADER); 605 else 606 set_vertex_processing_mode(ctx, VP_MODE_FF); 607} 608 609 610void 611_mesa_reset_vertex_processing_mode(struct gl_context *ctx) 612{ 613 ctx->VertexProgram._VPMode = -1; /* force the update */ 614 _mesa_update_vertex_processing_mode(ctx); 615} 616