state.c revision af69d88d
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 "blend.h" 55 56 57/** 58 * Update the following fields: 59 * ctx->VertexProgram._Enabled 60 * ctx->FragmentProgram._Enabled 61 * ctx->ATIFragmentShader._Enabled 62 * This needs to be done before texture state validation. 63 */ 64static void 65update_program_enables(struct gl_context *ctx) 66{ 67 /* These _Enabled flags indicate if the user-defined ARB/NV vertex/fragment 68 * program is enabled AND valid. Similarly for ATI fragment shaders. 69 * GLSL shaders not relevant here. 70 */ 71 ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled 72 && ctx->VertexProgram.Current->Base.Instructions; 73 ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled 74 && ctx->FragmentProgram.Current->Base.Instructions; 75 ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled 76 && ctx->ATIFragmentShader.Current->Instructions[0]; 77} 78 79 80/** 81 * Update the ctx->Vertex/Geometry/FragmentProgram._Current pointers to point 82 * to the current/active programs. Then call ctx->Driver.BindProgram() to 83 * tell the driver which programs to use. 84 * 85 * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment 86 * programs or programs derived from fixed-function state. 87 * 88 * This function needs to be called after texture state validation in case 89 * we're generating a fragment program from fixed-function texture state. 90 * 91 * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex 92 * or fragment program is being used. 93 */ 94static GLbitfield 95update_program(struct gl_context *ctx) 96{ 97 const struct gl_shader_program *vsProg = 98 ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; 99 const struct gl_shader_program *gsProg = 100 ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; 101 struct gl_shader_program *fsProg = 102 ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; 103 const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current; 104 const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current; 105 const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current; 106 GLbitfield new_state = 0x0; 107 108 /* 109 * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current 110 * pointers to the programs that should be used for rendering. If either 111 * is NULL, use fixed-function code paths. 112 * 113 * These programs may come from several sources. The priority is as 114 * follows: 115 * 1. OpenGL 2.0/ARB vertex/fragment shaders 116 * 2. ARB/NV vertex/fragment programs 117 * 3. Programs derived from fixed-function state. 118 * 119 * Note: it's possible for a vertex shader to get used with a fragment 120 * program (and vice versa) here, but in practice that shouldn't ever 121 * come up, or matter. 122 */ 123 124 if (fsProg && fsProg->LinkStatus 125 && fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) { 126 /* Use GLSL fragment shader */ 127 _mesa_reference_shader_program(ctx, 128 &ctx->_Shader->_CurrentFragmentProgram, 129 fsProg); 130 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, 131 gl_fragment_program(fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program)); 132 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, 133 NULL); 134 } 135 else if (ctx->FragmentProgram._Enabled) { 136 /* Use user-defined fragment program */ 137 _mesa_reference_shader_program(ctx, 138 &ctx->_Shader->_CurrentFragmentProgram, 139 NULL); 140 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, 141 ctx->FragmentProgram.Current); 142 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, 143 NULL); 144 } 145 else if (ctx->FragmentProgram._MaintainTexEnvProgram) { 146 /* Use fragment program generated from fixed-function state */ 147 struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx); 148 149 _mesa_reference_shader_program(ctx, 150 &ctx->_Shader->_CurrentFragmentProgram, 151 f); 152 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, 153 gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program)); 154 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, 155 gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program)); 156 } 157 else { 158 /* No fragment program */ 159 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); 160 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, 161 NULL); 162 } 163 164 if (gsProg && gsProg->LinkStatus 165 && gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) { 166 /* Use GLSL geometry shader */ 167 _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, 168 gl_geometry_program(gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program)); 169 } else { 170 /* No geometry program */ 171 _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL); 172 } 173 174 /* Examine vertex program after fragment program as 175 * _mesa_get_fixed_func_vertex_program() needs to know active 176 * fragprog inputs. 177 */ 178 if (vsProg && vsProg->LinkStatus 179 && vsProg->_LinkedShaders[MESA_SHADER_VERTEX]) { 180 /* Use GLSL vertex shader */ 181 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, 182 gl_vertex_program(vsProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program)); 183 } 184 else if (ctx->VertexProgram._Enabled) { 185 /* Use user-defined vertex program */ 186 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, 187 ctx->VertexProgram.Current); 188 } 189 else if (ctx->VertexProgram._MaintainTnlProgram) { 190 /* Use vertex program generated from fixed-function state */ 191 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, 192 _mesa_get_fixed_func_vertex_program(ctx)); 193 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, 194 ctx->VertexProgram._Current); 195 } 196 else { 197 /* no vertex program */ 198 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); 199 } 200 201 /* Let the driver know what's happening: 202 */ 203 if (ctx->FragmentProgram._Current != prevFP) { 204 new_state |= _NEW_PROGRAM; 205 if (ctx->Driver.BindProgram) { 206 ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 207 (struct gl_program *) ctx->FragmentProgram._Current); 208 } 209 } 210 211 if (ctx->GeometryProgram._Current != prevGP) { 212 new_state |= _NEW_PROGRAM; 213 if (ctx->Driver.BindProgram) { 214 ctx->Driver.BindProgram(ctx, MESA_GEOMETRY_PROGRAM, 215 (struct gl_program *) ctx->GeometryProgram._Current); 216 } 217 } 218 219 if (ctx->VertexProgram._Current != prevVP) { 220 new_state |= _NEW_PROGRAM; 221 if (ctx->Driver.BindProgram) { 222 ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, 223 (struct gl_program *) ctx->VertexProgram._Current); 224 } 225 } 226 227 return new_state; 228} 229 230 231/** 232 * Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0. 233 */ 234static GLbitfield 235update_program_constants(struct gl_context *ctx) 236{ 237 GLbitfield new_state = 0x0; 238 239 if (ctx->FragmentProgram._Current) { 240 const struct gl_program_parameter_list *params = 241 ctx->FragmentProgram._Current->Base.Parameters; 242 if (params && params->StateFlags & ctx->NewState) { 243 new_state |= _NEW_PROGRAM_CONSTANTS; 244 } 245 } 246 247 if (ctx->GeometryProgram._Current) { 248 const struct gl_program_parameter_list *params = 249 ctx->GeometryProgram._Current->Base.Parameters; 250 /*FIXME: StateFlags is always 0 because we have unnamed constant 251 * not state changes */ 252 if (params /*&& params->StateFlags & ctx->NewState*/) { 253 new_state |= _NEW_PROGRAM_CONSTANTS; 254 } 255 } 256 257 if (ctx->VertexProgram._Current) { 258 const struct gl_program_parameter_list *params = 259 ctx->VertexProgram._Current->Base.Parameters; 260 if (params && params->StateFlags & ctx->NewState) { 261 new_state |= _NEW_PROGRAM_CONSTANTS; 262 } 263 } 264 265 return new_state; 266} 267 268 269 270 271static void 272update_viewport_matrix(struct gl_context *ctx) 273{ 274 const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; 275 unsigned i; 276 277 ASSERT(depthMax > 0); 278 279 /* Compute scale and bias values. This is really driver-specific 280 * and should be maintained elsewhere if at all. 281 * NOTE: RasterPos uses this. 282 */ 283 for (i = 0; i < ctx->Const.MaxViewports; i++) { 284 _math_matrix_viewport(&ctx->ViewportArray[i]._WindowMap, 285 ctx->ViewportArray[i].X, ctx->ViewportArray[i].Y, 286 ctx->ViewportArray[i].Width, ctx->ViewportArray[i].Height, 287 ctx->ViewportArray[i].Near, ctx->ViewportArray[i].Far, 288 depthMax); 289 } 290} 291 292 293/** 294 * Update derived multisample state. 295 */ 296static void 297update_multisample(struct gl_context *ctx) 298{ 299 ctx->Multisample._Enabled = GL_FALSE; 300 if (ctx->Multisample.Enabled && 301 ctx->DrawBuffer && 302 ctx->DrawBuffer->Visual.sampleBuffers) 303 ctx->Multisample._Enabled = GL_TRUE; 304} 305 306 307/** 308 * Update the ctx->VertexProgram._TwoSideEnabled flag. 309 */ 310static void 311update_twoside(struct gl_context *ctx) 312{ 313 if (ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] || 314 ctx->VertexProgram._Enabled) { 315 ctx->VertexProgram._TwoSideEnabled = ctx->VertexProgram.TwoSideEnabled; 316 } else { 317 ctx->VertexProgram._TwoSideEnabled = (ctx->Light.Enabled && 318 ctx->Light.Model.TwoSide); 319 } 320} 321 322 323/** 324 * Compute derived GL state. 325 * If __struct gl_contextRec::NewState is non-zero then this function \b must 326 * be called before rendering anything. 327 * 328 * Calls dd_function_table::UpdateState to perform any internal state 329 * management necessary. 330 * 331 * \sa _mesa_update_modelview_project(), _mesa_update_texture(), 332 * _mesa_update_buffer_bounds(), 333 * _mesa_update_lighting() and _mesa_update_tnl_spaces(). 334 */ 335void 336_mesa_update_state_locked( struct gl_context *ctx ) 337{ 338 GLbitfield new_state = ctx->NewState; 339 GLbitfield prog_flags = _NEW_PROGRAM; 340 GLbitfield new_prog_state = 0x0; 341 342 if (new_state == _NEW_CURRENT_ATTRIB) 343 goto out; 344 345 if (MESA_VERBOSE & VERBOSE_STATE) 346 _mesa_print_state("_mesa_update_state", new_state); 347 348 /* Determine which state flags effect vertex/fragment program state */ 349 if (ctx->FragmentProgram._MaintainTexEnvProgram) { 350 prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG | 351 _NEW_VARYING_VP_INPUTS | _NEW_LIGHT | _NEW_POINT | 352 _NEW_RENDERMODE | _NEW_PROGRAM | _NEW_FRAG_CLAMP | 353 _NEW_COLOR); 354 } 355 if (ctx->VertexProgram._MaintainTnlProgram) { 356 prog_flags |= (_NEW_VARYING_VP_INPUTS | _NEW_TEXTURE | 357 _NEW_TEXTURE_MATRIX | _NEW_TRANSFORM | _NEW_POINT | 358 _NEW_FOG | _NEW_LIGHT | 359 _MESA_NEW_NEED_EYE_COORDS); 360 } 361 362 /* 363 * Now update derived state info 364 */ 365 366 if (new_state & prog_flags) 367 update_program_enables( ctx ); 368 369 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) 370 _mesa_update_modelview_project( ctx, new_state ); 371 372 if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) 373 _mesa_update_texture( ctx, new_state ); 374 375 if (new_state & _NEW_BUFFERS) 376 _mesa_update_framebuffer(ctx); 377 378 if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT)) 379 _mesa_update_draw_buffer_bounds( ctx ); 380 381 if (new_state & _NEW_LIGHT) 382 _mesa_update_lighting( ctx ); 383 384 if (new_state & (_NEW_LIGHT | _NEW_PROGRAM)) 385 update_twoside( ctx ); 386 387 if (new_state & (_NEW_STENCIL | _NEW_BUFFERS)) 388 _mesa_update_stencil( ctx ); 389 390 if (new_state & _NEW_PIXEL) 391 _mesa_update_pixel( ctx, new_state ); 392 393 if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT)) 394 update_viewport_matrix(ctx); 395 396 if (new_state & (_NEW_MULTISAMPLE | _NEW_BUFFERS)) 397 update_multisample( ctx ); 398 399 /* ctx->_NeedEyeCoords is now up to date. 400 * 401 * If the truth value of this variable has changed, update for the 402 * new lighting space and recompute the positions of lights and the 403 * normal transform. 404 * 405 * If the lighting space hasn't changed, may still need to recompute 406 * light positions & normal transforms for other reasons. 407 */ 408 if (new_state & _MESA_NEW_NEED_EYE_COORDS) 409 _mesa_update_tnl_spaces( ctx, new_state ); 410 411 if (new_state & prog_flags) { 412 /* When we generate programs from fixed-function vertex/fragment state 413 * this call may generate/bind a new program. If so, we need to 414 * propogate the _NEW_PROGRAM flag to the driver. 415 */ 416 new_prog_state |= update_program( ctx ); 417 } 418 419 if (new_state & _NEW_ARRAY) 420 _mesa_update_vao_client_arrays(ctx, ctx->Array.VAO); 421 422 if (ctx->Const.CheckArrayBounds && 423 new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) { 424 _mesa_update_vao_max_element(ctx, ctx->Array.VAO); 425 } 426 427 out: 428 new_prog_state |= update_program_constants(ctx); 429 430 /* 431 * Give the driver a chance to act upon the new_state flags. 432 * The driver might plug in different span functions, for example. 433 * Also, this is where the driver can invalidate the state of any 434 * active modules (such as swrast_setup, swrast, tnl, etc). 435 * 436 * Set ctx->NewState to zero to avoid recursion if 437 * Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?) 438 */ 439 new_state = ctx->NewState | new_prog_state; 440 ctx->NewState = 0; 441 ctx->Driver.UpdateState(ctx, new_state); 442 ctx->Array.VAO->NewArrays = 0x0; 443} 444 445 446/* This is the usual entrypoint for state updates: 447 */ 448void 449_mesa_update_state( struct gl_context *ctx ) 450{ 451 _mesa_lock_context_textures(ctx); 452 _mesa_update_state_locked(ctx); 453 _mesa_unlock_context_textures(ctx); 454} 455 456 457 458 459/** 460 * Want to figure out which fragment program inputs are actually 461 * constant/current values from ctx->Current. These should be 462 * referenced as a tracked state variable rather than a fragment 463 * program input, to save the overhead of putting a constant value in 464 * every submitted vertex, transferring it to hardware, interpolating 465 * it across the triangle, etc... 466 * 467 * When there is a VP bound, just use vp->outputs. But when we're 468 * generating vp from fixed function state, basically want to 469 * calculate: 470 * 471 * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) | 472 * potential_vp_outputs ) 473 * 474 * Where potential_vp_outputs is calculated by looking at enabled 475 * texgen, etc. 476 * 477 * The generated fragment program should then only declare inputs that 478 * may vary or otherwise differ from the ctx->Current values. 479 * Otherwise, the fp should track them as state values instead. 480 */ 481void 482_mesa_set_varying_vp_inputs( struct gl_context *ctx, 483 GLbitfield64 varying_inputs ) 484{ 485 if (ctx->varying_vp_inputs != varying_inputs) { 486 ctx->varying_vp_inputs = varying_inputs; 487 488 /* Only the fixed-func generated programs need to use the flag 489 * and the fixed-func fragment program uses it only if there is also 490 * a fixed-func vertex program, so this only depends on the latter. 491 * 492 * It's okay to check the VP pointer here, because this is called after 493 * _mesa_update_state in the vbo module. */ 494 if (ctx->VertexProgram._TnlProgram || 495 ctx->FragmentProgram._TexEnvProgram) { 496 ctx->NewState |= _NEW_VARYING_VP_INPUTS; 497 } 498 /*printf("%s %x\n", __FUNCTION__, varying_inputs);*/ 499 } 500} 501 502 503/** 504 * Used by drivers to tell core Mesa that the driver is going to 505 * install/ use its own vertex program. In particular, this will 506 * prevent generated fragment programs from using state vars instead 507 * of ordinary varyings/inputs. 508 */ 509void 510_mesa_set_vp_override(struct gl_context *ctx, GLboolean flag) 511{ 512 if (ctx->VertexProgram._Overriden != flag) { 513 ctx->VertexProgram._Overriden = flag; 514 515 /* Set one of the bits which will trigger fragment program 516 * regeneration: 517 */ 518 ctx->NewState |= _NEW_PROGRAM; 519 } 520} 521