Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenstate.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.1 00004 * 00005 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 00034 #include "glheader.h" 00035 #include "mtypes.h" 00036 #include "context.h" 00037 #include "debug.h" 00038 #include "macros.h" 00039 #include "ffvertex_prog.h" 00040 #include "framebuffer.h" 00041 #include "light.h" 00042 #include "matrix.h" 00043 #if FEATURE_pixel_transfer 00044 #include "pixel.h" 00045 #endif 00046 #include "shader/program.h" 00047 #include "state.h" 00048 #include "stencil.h" 00049 #include "texenvprogram.h" 00050 #include "texobj.h" 00051 #include "texstate.h" 00052 00053 00054 static void 00055 update_separate_specular(GLcontext *ctx) 00056 { 00057 if (NEED_SECONDARY_COLOR(ctx)) 00058 ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; 00059 else 00060 ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR; 00061 } 00062 00063 00067 static void 00068 update_arrays( GLcontext *ctx ) 00069 { 00070 GLuint i, min; 00071 00072 /* find min of _MaxElement values for all enabled arrays */ 00073 00074 /* 0 */ 00075 if (ctx->VertexProgram._Current 00076 && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { 00077 min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement; 00078 } 00079 else if (ctx->Array.ArrayObj->Vertex.Enabled) { 00080 min = ctx->Array.ArrayObj->Vertex._MaxElement; 00081 } 00082 else { 00083 /* can't draw anything without vertex positions! */ 00084 min = 0; 00085 } 00086 00087 /* 1 */ 00088 if (ctx->VertexProgram._Enabled 00089 && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT].Enabled) { 00090 min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]._MaxElement); 00091 } 00092 /* no conventional vertex weight array */ 00093 00094 /* 2 */ 00095 if (ctx->VertexProgram._Enabled 00096 && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { 00097 min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]._MaxElement); 00098 } 00099 else if (ctx->Array.ArrayObj->Normal.Enabled) { 00100 min = MIN2(min, ctx->Array.ArrayObj->Normal._MaxElement); 00101 } 00102 00103 /* 3 */ 00104 if (ctx->VertexProgram._Enabled 00105 && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { 00106 min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]._MaxElement); 00107 } 00108 else if (ctx->Array.ArrayObj->Color.Enabled) { 00109 min = MIN2(min, ctx->Array.ArrayObj->Color._MaxElement); 00110 } 00111 00112 /* 4 */ 00113 if (ctx->VertexProgram._Enabled 00114 && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { 00115 min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]._MaxElement); 00116 } 00117 else if (ctx->Array.ArrayObj->SecondaryColor.Enabled) { 00118 min = MIN2(min, ctx->Array.ArrayObj->SecondaryColor._MaxElement); 00119 } 00120 00121 /* 5 */ 00122 if (ctx->VertexProgram._Enabled 00123 && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { 00124 min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG]._MaxElement); 00125 } 00126 else if (ctx->Array.ArrayObj->FogCoord.Enabled) { 00127 min = MIN2(min, ctx->Array.ArrayObj->FogCoord._MaxElement); 00128 } 00129 00130 /* 6 */ 00131 if (ctx->VertexProgram._Enabled 00132 && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { 00133 min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]._MaxElement); 00134 } 00135 else if (ctx->Array.ArrayObj->Index.Enabled) { 00136 min = MIN2(min, ctx->Array.ArrayObj->Index._MaxElement); 00137 } 00138 00139 00140 /* 7 */ 00141 if (ctx->VertexProgram._Enabled 00142 && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { 00143 min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]._MaxElement); 00144 } 00145 00146 /* 8..15 */ 00147 for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) { 00148 if (ctx->VertexProgram._Enabled 00149 && ctx->Array.ArrayObj->VertexAttrib[i].Enabled) { 00150 min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement); 00151 } 00152 else if (i - VERT_ATTRIB_TEX0 < ctx->Const.MaxTextureCoordUnits 00153 && ctx->Array.ArrayObj->TexCoord[i - VERT_ATTRIB_TEX0].Enabled) { 00154 min = MIN2(min, ctx->Array.ArrayObj->TexCoord[i - VERT_ATTRIB_TEX0]._MaxElement); 00155 } 00156 } 00157 00158 /* 16..31 */ 00159 if (ctx->VertexProgram._Current) { 00160 for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { 00161 if (ctx->Array.ArrayObj->VertexAttrib[i].Enabled) { 00162 min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement); 00163 } 00164 } 00165 } 00166 00167 if (ctx->Array.ArrayObj->EdgeFlag.Enabled) { 00168 min = MIN2(min, ctx->Array.ArrayObj->EdgeFlag._MaxElement); 00169 } 00170 00171 /* _MaxElement is one past the last legal array element */ 00172 ctx->Array._MaxElement = min; 00173 } 00174 00175 00183 static void 00184 update_program_enables(GLcontext *ctx) 00185 { 00186 /* These _Enabled flags indicate if the program is enabled AND valid. */ 00187 ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled 00188 && ctx->VertexProgram.Current->Base.Instructions; 00189 ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled 00190 && ctx->FragmentProgram.Current->Base.Instructions; 00191 ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled 00192 && ctx->ATIFragmentShader.Current->Instructions[0]; 00193 } 00194 00195 00209 static GLbitfield 00210 update_program(GLcontext *ctx) 00211 { 00212 const struct gl_shader_program *shProg = ctx->Shader.CurrentProgram; 00213 const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current; 00214 const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current; 00215 GLbitfield new_state = 0x0; 00216 00217 /* 00218 * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current 00219 * pointers to the programs that should be used for rendering. If either 00220 * is NULL, use fixed-function code paths. 00221 * 00222 * These programs may come from several sources. The priority is as 00223 * follows: 00224 * 1. OpenGL 2.0/ARB vertex/fragment shaders 00225 * 2. ARB/NV vertex/fragment programs 00226 * 3. Programs derived from fixed-function state. 00227 * 00228 * Note: it's possible for a vertex shader to get used with a fragment 00229 * program (and vice versa) here, but in practice that shouldn't ever 00230 * come up, or matter. 00231 */ 00232 00233 if (shProg && shProg->LinkStatus && shProg->FragmentProgram) { 00234 /* Use shader programs */ 00235 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, 00236 shProg->FragmentProgram); 00237 } 00238 else if (ctx->FragmentProgram._Enabled) { 00239 /* use user-defined vertex program */ 00240 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, 00241 ctx->FragmentProgram.Current); 00242 } 00243 else if (ctx->FragmentProgram._MaintainTexEnvProgram) { 00244 /* Use fragment program generated from fixed-function state. 00245 */ 00246 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, 00247 _mesa_get_fixed_func_fragment_program(ctx)); 00248 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, 00249 ctx->FragmentProgram._Current); 00250 } 00251 else { 00252 /* no fragment program */ 00253 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); 00254 } 00255 00256 /* Examine vertex program after fragment program as 00257 * _mesa_get_fixed_func_vertex_program() needs to know active 00258 * fragprog inputs. 00259 */ 00260 if (shProg && shProg->LinkStatus && shProg->VertexProgram) { 00261 /* Use shader programs */ 00262 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, 00263 shProg->VertexProgram); 00264 } 00265 else if (ctx->VertexProgram._Enabled) { 00266 /* use user-defined vertex program */ 00267 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, 00268 ctx->VertexProgram.Current); 00269 } 00270 else if (ctx->VertexProgram._MaintainTnlProgram) { 00271 /* Use vertex program generated from fixed-function state. 00272 */ 00273 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, 00274 _mesa_get_fixed_func_vertex_program(ctx)); 00275 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, 00276 ctx->VertexProgram._Current); 00277 } 00278 else { 00279 /* no vertex program */ 00280 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); 00281 } 00282 00283 /* Let the driver know what's happening: 00284 */ 00285 if (ctx->FragmentProgram._Current != prevFP) { 00286 new_state |= _NEW_PROGRAM; 00287 if (ctx->Driver.BindProgram) { 00288 ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 00289 (struct gl_program *) ctx->FragmentProgram._Current); 00290 } 00291 } 00292 00293 if (ctx->VertexProgram._Current != prevVP) { 00294 new_state |= _NEW_PROGRAM; 00295 if (ctx->Driver.BindProgram) { 00296 ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, 00297 (struct gl_program *) ctx->VertexProgram._Current); 00298 } 00299 } 00300 00301 return new_state; 00302 } 00303 00304 00305 static void 00306 update_viewport_matrix(GLcontext *ctx) 00307 { 00308 const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; 00309 00310 ASSERT(depthMax > 0); 00311 00312 /* Compute scale and bias values. This is really driver-specific 00313 * and should be maintained elsewhere if at all. 00314 * NOTE: RasterPos uses this. 00315 */ 00316 _math_matrix_viewport(&ctx->Viewport._WindowMap, 00317 ctx->Viewport.X, ctx->Viewport.Y, 00318 ctx->Viewport.Width, ctx->Viewport.Height, 00319 ctx->Viewport.Near, ctx->Viewport.Far, 00320 depthMax); 00321 } 00322 00323 00327 static void 00328 update_multisample(GLcontext *ctx) 00329 { 00330 ctx->Multisample._Enabled = GL_FALSE; 00331 if (ctx->Multisample.Enabled && 00332 ctx->DrawBuffer && 00333 ctx->DrawBuffer->Visual.sampleBuffers) 00334 ctx->Multisample._Enabled = GL_TRUE; 00335 } 00336 00337 00341 static void 00342 update_color(GLcontext *ctx) 00343 { 00344 /* This is needed to support 1.1's RGB logic ops AND 00345 * 1.0's blending logicops. 00346 */ 00347 ctx->Color._LogicOpEnabled = RGBA_LOGICOP_ENABLED(ctx); 00348 } 00349 00350 00351 /* 00352 * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET 00353 * in ctx->_TriangleCaps if needed. 00354 */ 00355 static void 00356 update_polygon(GLcontext *ctx) 00357 { 00358 ctx->_TriangleCaps &= ~(DD_TRI_CULL_FRONT_BACK | DD_TRI_OFFSET); 00359 00360 if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) 00361 ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; 00362 00363 if ( ctx->Polygon.OffsetPoint 00364 || ctx->Polygon.OffsetLine 00365 || ctx->Polygon.OffsetFill) 00366 ctx->_TriangleCaps |= DD_TRI_OFFSET; 00367 } 00368 00369 00376 #if 0 00377 static void 00378 update_tricaps(GLcontext *ctx, GLbitfield new_state) 00379 { 00380 ctx->_TriangleCaps = 0; 00381 00382 /* 00383 * Points 00384 */ 00385 if (1/*new_state & _NEW_POINT*/) { 00386 if (ctx->Point.SmoothFlag) 00387 ctx->_TriangleCaps |= DD_POINT_SMOOTH; 00388 if (ctx->Point.Size != 1.0F) 00389 ctx->_TriangleCaps |= DD_POINT_SIZE; 00390 if (ctx->Point._Attenuated) 00391 ctx->_TriangleCaps |= DD_POINT_ATTEN; 00392 } 00393 00394 /* 00395 * Lines 00396 */ 00397 if (1/*new_state & _NEW_LINE*/) { 00398 if (ctx->Line.SmoothFlag) 00399 ctx->_TriangleCaps |= DD_LINE_SMOOTH; 00400 if (ctx->Line.StippleFlag) 00401 ctx->_TriangleCaps |= DD_LINE_STIPPLE; 00402 if (ctx->Line.Width != 1.0) 00403 ctx->_TriangleCaps |= DD_LINE_WIDTH; 00404 } 00405 00406 /* 00407 * Polygons 00408 */ 00409 if (1/*new_state & _NEW_POLYGON*/) { 00410 if (ctx->Polygon.SmoothFlag) 00411 ctx->_TriangleCaps |= DD_TRI_SMOOTH; 00412 if (ctx->Polygon.StippleFlag) 00413 ctx->_TriangleCaps |= DD_TRI_STIPPLE; 00414 if (ctx->Polygon.FrontMode != GL_FILL 00415 || ctx->Polygon.BackMode != GL_FILL) 00416 ctx->_TriangleCaps |= DD_TRI_UNFILLED; 00417 if (ctx->Polygon.CullFlag 00418 && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) 00419 ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; 00420 if (ctx->Polygon.OffsetPoint || 00421 ctx->Polygon.OffsetLine || 00422 ctx->Polygon.OffsetFill) 00423 ctx->_TriangleCaps |= DD_TRI_OFFSET; 00424 } 00425 00426 /* 00427 * Lighting and shading 00428 */ 00429 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) 00430 ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; 00431 if (ctx->Light.ShadeModel == GL_FLAT) 00432 ctx->_TriangleCaps |= DD_FLATSHADE; 00433 if (NEED_SECONDARY_COLOR(ctx)) 00434 ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; 00435 00436 /* 00437 * Stencil 00438 */ 00439 if (ctx->Stencil._TestTwoSide) 00440 ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL; 00441 } 00442 #endif 00443 00444 00457 void 00458 _mesa_update_state_locked( GLcontext *ctx ) 00459 { 00460 GLbitfield new_state = ctx->NewState; 00461 GLbitfield prog_flags = _NEW_PROGRAM; 00462 GLbitfield new_prog_state = 0x0; 00463 00464 if (MESA_VERBOSE & VERBOSE_STATE) 00465 _mesa_print_state("_mesa_update_state", new_state); 00466 00467 /* Determine which state flags effect vertex/fragment program state */ 00468 if (ctx->FragmentProgram._MaintainTexEnvProgram) { 00469 prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR); 00470 } 00471 if (ctx->VertexProgram._MaintainTnlProgram) { 00472 prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | 00473 _NEW_TRANSFORM | _NEW_POINT | 00474 _NEW_FOG | _NEW_LIGHT | 00475 _MESA_NEW_NEED_EYE_COORDS); 00476 } 00477 00478 /* 00479 * Now update derived state info 00480 */ 00481 00482 if (new_state & prog_flags) 00483 update_program_enables( ctx ); 00484 00485 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) 00486 _mesa_update_modelview_project( ctx, new_state ); 00487 00488 if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) 00489 _mesa_update_texture( ctx, new_state ); 00490 00491 if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) 00492 _mesa_update_framebuffer(ctx); 00493 00494 if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT)) 00495 _mesa_update_draw_buffer_bounds( ctx ); 00496 00497 if (new_state & _NEW_POLYGON) 00498 update_polygon( ctx ); 00499 00500 if (new_state & _NEW_LIGHT) 00501 _mesa_update_lighting( ctx ); 00502 00503 if (new_state & _NEW_STENCIL) 00504 _mesa_update_stencil( ctx ); 00505 00506 #if FEATURE_pixel_transfer 00507 if (new_state & _IMAGE_NEW_TRANSFER_STATE) 00508 _mesa_update_pixel( ctx, new_state ); 00509 #endif 00510 00511 if (new_state & _DD_NEW_SEPARATE_SPECULAR) 00512 update_separate_specular( ctx ); 00513 00514 if (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) 00515 update_arrays( ctx ); 00516 00517 if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT)) 00518 update_viewport_matrix(ctx); 00519 00520 if (new_state & _NEW_MULTISAMPLE) 00521 update_multisample( ctx ); 00522 00523 if (new_state & _NEW_COLOR) 00524 update_color( ctx ); 00525 00526 #if 0 00527 if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT 00528 | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR)) 00529 update_tricaps( ctx, new_state ); 00530 #endif 00531 00532 /* ctx->_NeedEyeCoords is now up to date. 00533 * 00534 * If the truth value of this variable has changed, update for the 00535 * new lighting space and recompute the positions of lights and the 00536 * normal transform. 00537 * 00538 * If the lighting space hasn't changed, may still need to recompute 00539 * light positions & normal transforms for other reasons. 00540 */ 00541 if (new_state & _MESA_NEW_NEED_EYE_COORDS) 00542 _mesa_update_tnl_spaces( ctx, new_state ); 00543 00544 if (new_state & prog_flags) { 00545 /* When we generate programs from fixed-function vertex/fragment state 00546 * this call may generate/bind a new program. If so, we need to 00547 * propogate the _NEW_PROGRAM flag to the driver. 00548 */ 00549 new_prog_state |= update_program( ctx ); 00550 } 00551 00552 /* 00553 * Give the driver a chance to act upon the new_state flags. 00554 * The driver might plug in different span functions, for example. 00555 * Also, this is where the driver can invalidate the state of any 00556 * active modules (such as swrast_setup, swrast, tnl, etc). 00557 * 00558 * Set ctx->NewState to zero to avoid recursion if 00559 * Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?) 00560 */ 00561 new_state = ctx->NewState | new_prog_state; 00562 ctx->NewState = 0; 00563 ctx->Driver.UpdateState(ctx, new_state); 00564 ctx->Array.NewState = 0; 00565 } 00566 00567 00568 /* This is the usual entrypoint for state updates: 00569 */ 00570 void 00571 _mesa_update_state( GLcontext *ctx ) 00572 { 00573 _mesa_lock_context_textures(ctx); 00574 _mesa_update_state_locked(ctx); 00575 _mesa_unlock_context_textures(ctx); 00576 } Generated on Sun May 27 2012 04:20:28 for ReactOS by
1.7.6.1
|