diff options
Diffstat (limited to 'src/mesa/main/state.c')
-rw-r--r-- | src/mesa/main/state.c | 163 |
1 files changed, 108 insertions, 55 deletions
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index a962f1cb41d..0a39279bff3 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -51,6 +51,16 @@ #include "texstate.h" +static void +update_separate_specular(GLcontext *ctx) +{ + if (NEED_SECONDARY_COLOR(ctx)) + ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; + else + ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR; +} + + /** * Update state dependent on vertex arrays. */ @@ -163,25 +173,47 @@ update_arrays( GLcontext *ctx ) } +/** + * Update the following fields: + * ctx->VertexProgram._Enabled + * ctx->FragmentProgram._Enabled + * ctx->ATIFragmentShader._Enabled + * This needs to be done before texture state validation. + */ static void -update_program(GLcontext *ctx) +update_program_enables(GLcontext *ctx) { - const struct gl_shader_program *shProg = ctx->Shader.CurrentProgram; - const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current; - const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current; - /* These _Enabled flags indicate if the program is enabled AND valid. */ ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled && ctx->VertexProgram.Current->Base.Instructions; ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled && ctx->FragmentProgram.Current->Base.Instructions; ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled - && ctx->ATIFragmentShader.Current->Instructions; + && ctx->ATIFragmentShader.Current->Instructions[0]; +} + + +/** + * Update vertex/fragment program state. In particular, update these fields: + * ctx->VertexProgram._Current + * ctx->VertexProgram._TnlProgram, + * These point to the highest priority enabled vertex/fragment program or are + * NULL if fixed-function processing is to be done. + * + * This function needs to be called after texture state validation in case + * we're generating a fragment program from fixed-function texture state. + */ +static void +update_program(GLcontext *ctx) +{ + const struct gl_shader_program *shProg = ctx->Shader.CurrentProgram; + const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current; + const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current; /* * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current - * pointers to the programs that should be enabled/used. These will only - * be NULL if we need to use the fixed-function code. + * pointers to the programs that should be used for rendering. If either + * is NULL, use fixed-function code paths. * * These programs may come from several sources. The priority is as * follows: @@ -194,56 +226,37 @@ update_program(GLcontext *ctx) * come up, or matter. */ - /** - ** Fragment program - **/ -#if 1 - /* XXX get rid of this someday? */ - ctx->FragmentProgram._Active = GL_FALSE; -#endif if (shProg && shProg->LinkStatus && shProg->FragmentProgram) { - /* user-defined fragment shader */ + /* Use shader programs */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, shProg->FragmentProgram); } else if (ctx->FragmentProgram._Enabled) { - /* use user-defined fragment program */ + /* use user-defined vertex program */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, ctx->FragmentProgram.Current); } else if (ctx->FragmentProgram._MaintainTexEnvProgram) { - /* fragment program generated from fixed-function state */ + /* Use fragment program generated from fixed-function state. + */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, _mesa_get_fixed_func_fragment_program(ctx)); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, ctx->FragmentProgram._Current); - - /* XXX get rid of this confusing stuff someday? */ - ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled; - if (ctx->FragmentProgram._UseTexEnvProgram) - ctx->FragmentProgram._Active = GL_TRUE; } else { /* no fragment program */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); } - if (ctx->FragmentProgram._Current != prevFP && ctx->Driver.BindProgram) { - ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, - (struct gl_program *) ctx->FragmentProgram._Current); - } - - /** - ** Vertex program - **/ -#if 1 - /* XXX get rid of this someday? */ - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL); -#endif + /* Examine vertex program after fragment program as + * _mesa_get_fixed_func_vertex_program() needs to know active + * fragprog inputs. + */ if (shProg && shProg->LinkStatus && shProg->VertexProgram) { - /* user-defined vertex shader */ + /* Use shader programs */ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, - shProg->VertexProgram); + shProg->VertexProgram); } else if (ctx->VertexProgram._Enabled) { /* use user-defined vertex program */ @@ -251,20 +264,28 @@ update_program(GLcontext *ctx) ctx->VertexProgram.Current); } else if (ctx->VertexProgram._MaintainTnlProgram) { - /* vertex program generated from fixed-function state */ + /* Use vertex program generated from fixed-function state. + */ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, _mesa_get_fixed_func_vertex_program(ctx)); _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, ctx->VertexProgram._Current); } else { - /* no vertex program / used fixed-function code */ + /* no vertex program */ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); } + /* Let the driver know what's happening: + */ + if (ctx->FragmentProgram._Current != prevFP && ctx->Driver.BindProgram) { + ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, + (struct gl_program *) ctx->FragmentProgram._Current); + } + if (ctx->VertexProgram._Current != prevVP && ctx->Driver.BindProgram) { ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, - (struct gl_program *) ctx->VertexProgram._Current); + (struct gl_program *) ctx->VertexProgram._Current); } } @@ -315,6 +336,24 @@ update_color(GLcontext *ctx) } +/* + * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET + * in ctx->_TriangleCaps if needed. + */ +static void +update_polygon(GLcontext *ctx) +{ + ctx->_TriangleCaps &= ~(DD_TRI_CULL_FRONT_BACK | DD_TRI_OFFSET); + + if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) + ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; + + if ( ctx->Polygon.OffsetPoint + || ctx->Polygon.OffsetLine + || ctx->Polygon.OffsetFill) + ctx->_TriangleCaps |= DD_TRI_OFFSET; +} + /** * Update the ctx->_TriangleCaps bitfield. @@ -322,6 +361,7 @@ update_color(GLcontext *ctx) * This function must be called after other update_*() functions since * there are dependencies on some other derived values. */ +#if 0 static void update_tricaps(GLcontext *ctx, GLbitfield new_state) { @@ -387,6 +427,7 @@ update_tricaps(GLcontext *ctx, GLbitfield new_state) if (ctx->Stencil._TestTwoSide) ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL; } +#endif /** @@ -413,6 +454,24 @@ _mesa_update_state_locked( GLcontext *ctx ) if (MESA_VERBOSE & VERBOSE_STATE) _mesa_print_state("_mesa_update_state", new_state); + /* Determine which state flags effect vertex/fragment program state */ + if (ctx->FragmentProgram._MaintainTexEnvProgram) { + prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR); + } + if (ctx->VertexProgram._MaintainTnlProgram) { + prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | + _NEW_TRANSFORM | _NEW_POINT | + _NEW_FOG | _NEW_LIGHT | + _MESA_NEW_NEED_EYE_COORDS); + } + + /* + * Now update derived state info + */ + + if (new_state & prog_flags) + update_program_enables( ctx ); + if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) _mesa_update_modelview_project( ctx, new_state ); @@ -425,6 +484,9 @@ _mesa_update_state_locked( GLcontext *ctx ) if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT)) _mesa_update_draw_buffer_bounds( ctx ); + if (new_state & _NEW_POLYGON) + update_polygon( ctx ); + if (new_state & _NEW_LIGHT) _mesa_update_lighting( ctx ); @@ -432,10 +494,13 @@ _mesa_update_state_locked( GLcontext *ctx ) _mesa_update_stencil( ctx ); #if FEATURE_pixel_transfer - if (new_state & _IMAGE_NEW_TRANSFER_STATE) + if (new_state & _MESA_NEW_TRANSFER_STATE) _mesa_update_pixel( ctx, new_state ); #endif + if (new_state & _DD_NEW_SEPARATE_SPECULAR) + update_separate_specular( ctx ); + if (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) update_arrays( ctx ); @@ -448,9 +513,11 @@ _mesa_update_state_locked( GLcontext *ctx ) if (new_state & _NEW_COLOR) update_color( ctx ); +#if 0 if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR)) update_tricaps( ctx, new_state ); +#endif /* ctx->_NeedEyeCoords is now up to date. * @@ -464,23 +531,9 @@ _mesa_update_state_locked( GLcontext *ctx ) if (new_state & _MESA_NEW_NEED_EYE_COORDS) _mesa_update_tnl_spaces( ctx, new_state ); - if (ctx->FragmentProgram._MaintainTexEnvProgram) { - prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE_MATRIX | _NEW_LIGHT | - _NEW_RENDERMODE | - _NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR); - } - if (ctx->VertexProgram._MaintainTnlProgram) { - prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | - _NEW_RENDERMODE | - _NEW_TRANSFORM | _NEW_POINT | - _NEW_FOG | _NEW_LIGHT | - _MESA_NEW_NEED_EYE_COORDS); - } if (new_state & prog_flags) update_program( ctx ); - - /* * Give the driver a chance to act upon the new_state flags. * The driver might plug in different span functions, for example. |