ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

state.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.