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#include "state_tracker/st_context.h" 59 60void 61_mesa_update_allow_draw_out_of_order(struct gl_context *ctx) 62{ 63 /* Out-of-order drawing is useful when vertex array draws and immediate 64 * mode are interleaved. 65 * 66 * Example with 3 draws: 67 * glBegin(); 68 * glVertex(); 69 * glEnd(); 70 * glDrawElements(); 71 * glBegin(); 72 * glVertex(); 73 * glEnd(); 74 * 75 * Out-of-order drawing changes the execution order like this: 76 * glDrawElements(); 77 * glBegin(); 78 * glVertex(); 79 * glVertex(); 80 * glEnd(); 81 * 82 * If out-of-order draws are enabled, immediate mode vertices are not 83 * flushed before glDrawElements, resulting in fewer draws and lower CPU 84 * overhead. This helps workstation applications. 85 * 86 * This is a simplified version of out-of-order determination to catch 87 * common cases. 88 * 89 * RadeonSI has a complete and more complicated out-of-order determination 90 * for driver-internal reasons. 91 */ 92 /* Only the compatibility profile with immediate mode needs this. */ 93 if (!ctx->Const.AllowDrawOutOfOrder) 94 return; 95 96 assert(ctx->API == API_OPENGL_COMPAT); 97 98 /* If all of these are NULL, GLSL is disabled. */ 99 struct gl_program *vs = 100 ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; 101 struct gl_program *tcs = 102 ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; 103 struct gl_program *tes = 104 ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; 105 struct gl_program *gs = 106 ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; 107 struct gl_program *fs = 108 ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; 109 GLenum16 depth_func = ctx->Depth.Func; 110 111 /* Z fighting and any primitives with equal Z shouldn't be reordered 112 * with LESS/LEQUAL/GREATER/GEQUAL functions. 113 * 114 * When drawing 2 primitive with equal Z: 115 * - with LEQUAL/GEQUAL, the last primitive wins the Z test. 116 * - with LESS/GREATER, the first primitive wins the Z test. 117 * 118 * Here we ignore that on the basis that such cases don't occur in real 119 * apps, and we they do occur, they occur with blending where out-of-order 120 * drawing is always disabled. 121 */ 122 bool previous_state = ctx->_AllowDrawOutOfOrder; 123 ctx->_AllowDrawOutOfOrder = 124 ctx->DrawBuffer && 125 ctx->DrawBuffer->Visual.depthBits && 126 ctx->Depth.Test && 127 ctx->Depth.Mask && 128 (depth_func == GL_NEVER || 129 depth_func == GL_LESS || 130 depth_func == GL_LEQUAL || 131 depth_func == GL_GREATER || 132 depth_func == GL_GEQUAL) && 133 (!ctx->DrawBuffer->Visual.stencilBits || 134 !ctx->Stencil.Enabled) && 135 (!ctx->Color.ColorMask || 136 (!ctx->Color.BlendEnabled && 137 (!ctx->Color.ColorLogicOpEnabled || 138 ctx->Color._LogicOp == COLOR_LOGICOP_COPY))) && 139 (!vs || !vs->info.writes_memory) && 140 (!tes || !tes->info.writes_memory) && 141 (!tcs || !tcs->info.writes_memory) && 142 (!gs || !gs->info.writes_memory) && 143 (!fs || !fs->info.writes_memory || !fs->info.fs.early_fragment_tests); 144 145 /* If we are disabling out-of-order drawing, we need to flush queued 146 * vertices. 147 */ 148 if (previous_state && !ctx->_AllowDrawOutOfOrder) 149 FLUSH_VERTICES(ctx, 0, 0); 150} 151 152 153/** 154 * Update the ctx->*Program._Current pointers to point to the 155 * current/active programs. 156 * 157 * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment 158 * programs or programs derived from fixed-function state. 159 * 160 * This function needs to be called after texture state validation in case 161 * we're generating a fragment program from fixed-function texture state. 162 * 163 * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex 164 * or fragment program is being used. 165 */ 166static GLbitfield 167update_program(struct gl_context *ctx) 168{ 169 struct gl_program *vsProg = 170 ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; 171 struct gl_program *tcsProg = 172 ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; 173 struct gl_program *tesProg = 174 ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; 175 struct gl_program *gsProg = 176 ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; 177 struct gl_program *fsProg = 178 ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; 179 struct gl_program *csProg = 180 ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; 181 const struct gl_program *prevVP = ctx->VertexProgram._Current; 182 const struct gl_program *prevFP = ctx->FragmentProgram._Current; 183 const struct gl_program *prevGP = ctx->GeometryProgram._Current; 184 const struct gl_program *prevTCP = ctx->TessCtrlProgram._Current; 185 const struct gl_program *prevTEP = ctx->TessEvalProgram._Current; 186 const struct gl_program *prevCP = ctx->ComputeProgram._Current; 187 188 /* 189 * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current 190 * pointers to the programs that should be used for rendering. If either 191 * is NULL, use fixed-function code paths. 192 * 193 * These programs may come from several sources. The priority is as 194 * follows: 195 * 1. OpenGL 2.0/ARB vertex/fragment shaders 196 * 2. ARB/NV vertex/fragment programs 197 * 3. ATI fragment shader 198 * 4. Programs derived from fixed-function state. 199 * 200 * Note: it's possible for a vertex shader to get used with a fragment 201 * program (and vice versa) here, but in practice that shouldn't ever 202 * come up, or matter. 203 */ 204 205 if (fsProg) { 206 /* Use GLSL fragment shader */ 207 _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, fsProg); 208 _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 209 NULL); 210 } 211 else if (_mesa_arb_fragment_program_enabled(ctx)) { 212 /* Use user-defined fragment program */ 213 _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, 214 ctx->FragmentProgram.Current); 215 _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 216 NULL); 217 } 218 else if (_mesa_ati_fragment_shader_enabled(ctx) && 219 ctx->ATIFragmentShader.Current->Program) { 220 /* Use the enabled ATI fragment shader's associated program */ 221 _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, 222 ctx->ATIFragmentShader.Current->Program); 223 _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 224 NULL); 225 } 226 else { 227 /* Use fragment program generated from fixed-function state */ 228 struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx); 229 230 _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, 231 f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); 232 _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 233 f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); 234 } 235 236 if (gsProg) { 237 /* Use GLSL geometry shader */ 238 _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, gsProg); 239 } else { 240 /* No geometry program */ 241 _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL); 242 } 243 244 if (tesProg) { 245 /* Use GLSL tessellation evaluation shader */ 246 _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, tesProg); 247 } 248 else { 249 /* No tessellation evaluation program */ 250 _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL); 251 } 252 253 if (tcsProg) { 254 /* Use GLSL tessellation control shader */ 255 _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, tcsProg); 256 } 257 else { 258 /* No tessellation control program */ 259 _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, NULL); 260 } 261 262 /* Examine vertex program after fragment program as 263 * _mesa_get_fixed_func_vertex_program() needs to know active 264 * fragprog inputs. 265 */ 266 if (vsProg) { 267 /* Use GLSL vertex shader */ 268 assert(VP_MODE_SHADER == ctx->VertexProgram._VPMode); 269 _mesa_reference_program(ctx, &ctx->VertexProgram._Current, vsProg); 270 } 271 else if (_mesa_arb_vertex_program_enabled(ctx)) { 272 /* Use user-defined vertex program */ 273 assert(VP_MODE_SHADER == ctx->VertexProgram._VPMode); 274 _mesa_reference_program(ctx, &ctx->VertexProgram._Current, 275 ctx->VertexProgram.Current); 276 } 277 else { 278 /* Use vertex program generated from fixed-function state */ 279 assert(VP_MODE_FF == ctx->VertexProgram._VPMode); 280 _mesa_reference_program(ctx, &ctx->VertexProgram._Current, 281 _mesa_get_fixed_func_vertex_program(ctx)); 282 _mesa_reference_program(ctx, &ctx->VertexProgram._TnlProgram, 283 ctx->VertexProgram._Current); 284 } 285 286 if (csProg) { 287 /* Use GLSL compute shader */ 288 _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, csProg); 289 } else { 290 /* no compute program */ 291 _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, NULL); 292 } 293 294 bool vp_changed = ctx->VertexProgram._Current != prevVP; 295 bool tep_changed = ctx->TessEvalProgram._Current != prevTEP; 296 bool gp_changed = ctx->GeometryProgram._Current != prevGP; 297 if (ctx->GeometryProgram._Current) { 298 ctx->LastVertexStageDirty |= gp_changed; 299 } else if (ctx->TessEvalProgram._Current) { 300 ctx->LastVertexStageDirty |= gp_changed | tep_changed; 301 } else { 302 ctx->LastVertexStageDirty |= gp_changed | tep_changed | vp_changed; 303 } 304 305 /* Let the driver know what's happening: 306 */ 307 if (ctx->FragmentProgram._Current != prevFP || 308 ctx->VertexProgram._Current != prevVP || 309 ctx->GeometryProgram._Current != prevGP || 310 ctx->TessEvalProgram._Current != prevTEP || 311 ctx->TessCtrlProgram._Current != prevTCP || 312 ctx->ComputeProgram._Current != prevCP) 313 return _NEW_PROGRAM; 314 315 return 0; 316} 317 318 319static GLbitfield 320update_single_program_constants(struct gl_context *ctx, 321 struct gl_program *prog, 322 gl_shader_stage stage) 323{ 324 if (prog) { 325 const struct gl_program_parameter_list *params = prog->Parameters; 326 if (params && params->StateFlags & ctx->NewState) { 327 if (ctx->DriverFlags.NewShaderConstants[stage]) 328 ctx->NewDriverState |= ctx->DriverFlags.NewShaderConstants[stage]; 329 else 330 return _NEW_PROGRAM_CONSTANTS; 331 } 332 } 333 return 0; 334} 335 336 337/** 338 * This updates fixed-func state constants such as gl_ModelViewMatrix. 339 * Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0. 340 */ 341static GLbitfield 342update_program_constants(struct gl_context *ctx) 343{ 344 GLbitfield new_state = 345 update_single_program_constants(ctx, ctx->VertexProgram._Current, 346 MESA_SHADER_VERTEX) | 347 update_single_program_constants(ctx, ctx->FragmentProgram._Current, 348 MESA_SHADER_FRAGMENT); 349 350 if (ctx->API == API_OPENGL_COMPAT && 351 ctx->Const.GLSLVersionCompat >= 150) { 352 new_state |= 353 update_single_program_constants(ctx, ctx->GeometryProgram._Current, 354 MESA_SHADER_GEOMETRY); 355 356 if (_mesa_has_ARB_tessellation_shader(ctx)) { 357 new_state |= 358 update_single_program_constants(ctx, ctx->TessCtrlProgram._Current, 359 MESA_SHADER_TESS_CTRL) | 360 update_single_program_constants(ctx, ctx->TessEvalProgram._Current, 361 MESA_SHADER_TESS_EVAL); 362 } 363 } 364 365 return new_state; 366} 367 368 369static void 370update_fixed_func_program_usage(struct gl_context *ctx) 371{ 372 ctx->FragmentProgram._UsesTexEnvProgram = 373 !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] && /* GLSL*/ 374 !_mesa_arb_fragment_program_enabled(ctx) && 375 !(_mesa_ati_fragment_shader_enabled(ctx) && 376 ctx->ATIFragmentShader.Current->Program); 377 378 ctx->VertexProgram._UsesTnlProgram = 379 !ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] && /* GLSL */ 380 !_mesa_arb_vertex_program_enabled(ctx); 381} 382 383 384/** 385 * Compute derived GL state. 386 * If __struct gl_contextRec::NewState is non-zero then this function \b must 387 * be called before rendering anything. 388 * 389 * Calls dd_function_table::UpdateState to perform any internal state 390 * management necessary. 391 * 392 * \sa _mesa_update_modelview_project(), _mesa_update_texture(), 393 * _mesa_update_buffer_bounds(), 394 * _mesa_update_lighting() and _mesa_update_tnl_spaces(). 395 */ 396void 397_mesa_update_state_locked( struct gl_context *ctx ) 398{ 399 GLbitfield new_state = ctx->NewState; 400 GLbitfield new_prog_state = 0x0; 401 const GLbitfield checked_states = 402 _NEW_BUFFERS | _NEW_MODELVIEW | _NEW_PROJECTION | _NEW_TEXTURE_MATRIX | 403 _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE | _NEW_PROGRAM | 404 _NEW_LIGHT_CONSTANTS | _NEW_POINT | _NEW_FF_VERT_PROGRAM | 405 _NEW_FF_FRAG_PROGRAM | _NEW_TNL_SPACES; 406 407 /* we can skip a bunch of state validation checks if the dirty 408 * state matches one or more bits in 'computed_states'. 409 */ 410 if (!(new_state & checked_states)) 411 goto out; 412 413 if (MESA_VERBOSE & VERBOSE_STATE) 414 _mesa_print_state("_mesa_update_state", new_state); 415 416 if (new_state & _NEW_BUFFERS) 417 _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer); 418 419 /* Handle Core and Compatibility contexts separately. */ 420 if (ctx->API == API_OPENGL_COMPAT || 421 ctx->API == API_OPENGLES) { 422 /* Update derived state. */ 423 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) 424 _mesa_update_modelview_project( ctx, new_state ); 425 426 if (new_state & _NEW_TEXTURE_MATRIX) 427 new_state |= _mesa_update_texture_matrices(ctx); 428 429 if (new_state & (_NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE | _NEW_PROGRAM)) 430 new_state |= _mesa_update_texture_state(ctx); 431 432 if (new_state & _NEW_LIGHT_CONSTANTS) 433 new_state |= _mesa_update_lighting(ctx); 434 435 /* ctx->_NeedEyeCoords is determined here. 436 * 437 * If the truth value of this variable has changed, update for the 438 * new lighting space and recompute the positions of lights and the 439 * normal transform. 440 * 441 * If the lighting space hasn't changed, may still need to recompute 442 * light positions & normal transforms for other reasons. 443 */ 444 if (new_state & (_NEW_TNL_SPACES | _NEW_LIGHT_CONSTANTS | 445 _NEW_MODELVIEW)) { 446 if (_mesa_update_tnl_spaces(ctx, new_state)) 447 new_state |= _NEW_FF_VERT_PROGRAM; 448 } 449 450 if (new_state & _NEW_PROGRAM) 451 update_fixed_func_program_usage(ctx); 452 453 /* Determine which states affect fixed-func vertex/fragment program. */ 454 GLbitfield prog_flags = _NEW_PROGRAM; 455 456 if (ctx->FragmentProgram._UsesTexEnvProgram) { 457 prog_flags |= _NEW_BUFFERS | _NEW_TEXTURE_OBJECT | 458 _NEW_FF_FRAG_PROGRAM | _NEW_TEXTURE_STATE; 459 } 460 461 if (ctx->VertexProgram._UsesTnlProgram) 462 prog_flags |= _NEW_FF_VERT_PROGRAM; 463 464 if (new_state & prog_flags) { 465 /* When we generate programs from fixed-function vertex/fragment state 466 * this call may generate/bind a new program. If so, we need to 467 * propogate the _NEW_PROGRAM flag to the driver. 468 */ 469 new_prog_state |= update_program(ctx); 470 } 471 } else { 472 /* GL Core and GLES 2/3 contexts */ 473 if (new_state & (_NEW_TEXTURE_OBJECT | _NEW_PROGRAM)) 474 _mesa_update_texture_state(ctx); 475 476 if (new_state & _NEW_PROGRAM) 477 update_program(ctx); 478 } 479 480 out: 481 new_prog_state |= update_program_constants(ctx); 482 483 ctx->NewState |= new_prog_state; 484 485 /* 486 * Give the driver a chance to act upon the new_state flags. 487 * The driver might plug in different span functions, for example. 488 * Also, this is where the driver can invalidate the state of any 489 * active modules (such as swrast_setup, swrast, tnl, etc). 490 */ 491 st_invalidate_state(ctx); 492 ctx->NewState = 0; 493} 494 495 496/* This is the usual entrypoint for state updates: 497 */ 498void 499_mesa_update_state( struct gl_context *ctx ) 500{ 501 _mesa_lock_context_textures(ctx); 502 _mesa_update_state_locked(ctx); 503 _mesa_unlock_context_textures(ctx); 504} 505 506 507/** 508 * Used by drivers to tell core Mesa that the driver is going to 509 * install/ use its own vertex program. In particular, this will 510 * prevent generated fragment programs from using state vars instead 511 * of ordinary varyings/inputs. 512 */ 513void 514_mesa_set_vp_override(struct gl_context *ctx, GLboolean flag) 515{ 516 if (ctx->VertexProgram._Overriden != flag) { 517 ctx->VertexProgram._Overriden = flag; 518 519 /* Set one of the bits which will trigger fragment program 520 * regeneration: 521 */ 522 ctx->NewState |= _NEW_PROGRAM; 523 } 524} 525 526 527static void 528set_vertex_processing_mode(struct gl_context *ctx, gl_vertex_processing_mode m) 529{ 530 if (ctx->VertexProgram._VPMode == m) 531 return; 532 533 /* On change we may get new maps into the current values */ 534 ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; 535 ctx->Array.NewVertexElements = true; 536 537 /* Finally memorize the value */ 538 ctx->VertexProgram._VPMode = m; 539 540 /* The gl_context::VertexProgram._VaryingInputs value is only used when in 541 * VP_MODE_FF mode and the fixed-func pipeline is emulated by shaders. 542 */ 543 ctx->VertexProgram._VPModeOptimizesConstantAttribs = 544 m == VP_MODE_FF; 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