diff options
Diffstat (limited to 'src/mesa/main/state.c')
-rw-r--r-- | src/mesa/main/state.c | 98 |
1 files changed, 66 insertions, 32 deletions
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index d60b9a13d8b..3323887cb02 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -62,6 +62,7 @@ #if FEATURE_EXT_framebuffer_object #include "fbobject.h" #endif +#include "ffvertex_prog.h" #include "framebuffer.h" #include "hint.h" #include "histogram.h" @@ -951,13 +952,12 @@ update_arrays( GLcontext *ctx ) } -/** - * Update derived vertex/fragment program 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; /* These _Enabled flags indicate if the program is enabled AND valid. */ ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled @@ -969,13 +969,18 @@ update_program(GLcontext *ctx) /* * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current - * pointers to the programs that should be enabled/used. + * pointers to the programs that should be enabled/used. These will only + * be NULL if we need to use the fixed-function code. * * These programs may come from several sources. The priority is as * follows: * 1. OpenGL 2.0/ARB vertex/fragment shaders * 2. ARB/NV vertex/fragment programs * 3. Programs derived from fixed-function state. + * + * Note: it's possible for a vertex shader to get used with a fragment + * program (and vice versa) here, but in practice that shouldn't ever + * come up, or matter. */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); @@ -991,23 +996,6 @@ update_program(GLcontext *ctx) shProg->FragmentProgram); } else { - if (ctx->VertexProgram._Enabled) { - /* use user-defined vertex program */ - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, - ctx->VertexProgram.Current); - } - else if (ctx->VertexProgram._MaintainTnlProgram) { - /* Use vertex program generated from fixed-function state. - * The _Current pointer will get set in - * _tnl_UpdateFixedFunctionProgram() later if appropriate. - */ - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); - } - else { - /* no vertex program */ - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); - } - if (ctx->FragmentProgram._Enabled) { /* use user-defined vertex program */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, @@ -1015,15 +1003,38 @@ update_program(GLcontext *ctx) } else if (ctx->FragmentProgram._MaintainTexEnvProgram) { /* Use fragment program generated from fixed-function state. - * The _Current pointer will get set in _mesa_UpdateTexEnvProgram() - * later if appropriate. */ - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, + _mesa_get_fixed_func_fragment_program(ctx)); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, + ctx->FragmentProgram._Current); } else { /* no fragment program */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); } + + /* Examine vertex program after fragment program as + * _mesa_get_fixed_func_vertex_program() needs to know active + * fragprog inputs. + */ + if (ctx->VertexProgram._Enabled) { + /* use user-defined vertex program */ + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, + ctx->VertexProgram.Current); + } + else if (ctx->VertexProgram._MaintainTnlProgram) { + /* 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 */ + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); + } } if (ctx->VertexProgram._Current) @@ -1032,12 +1043,28 @@ update_program(GLcontext *ctx) assert(ctx->FragmentProgram._Current->Base.Parameters); + /* XXX: get rid of _Active flag. + */ +#if 1 ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled; if (ctx->FragmentProgram._MaintainTexEnvProgram && !ctx->FragmentProgram._Enabled) { if (ctx->FragmentProgram._UseTexEnvProgram) ctx->FragmentProgram._Active = GL_TRUE; } +#endif + + /* 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); + } } @@ -1197,13 +1224,11 @@ void _mesa_update_state_locked( GLcontext *ctx ) { GLbitfield new_state = ctx->NewState; + GLbitfield prog_flags = _NEW_PROGRAM; if (MESA_VERBOSE & VERBOSE_STATE) _mesa_print_state("_mesa_update_state", new_state); - if (new_state & _NEW_PROGRAM) - update_program( ctx ); - if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) _mesa_update_modelview_project( ctx, new_state ); @@ -1249,11 +1274,6 @@ _mesa_update_state_locked( GLcontext *ctx ) update_tricaps( ctx, new_state ); #endif - if (ctx->FragmentProgram._MaintainTexEnvProgram) { - if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR | _NEW_FOG)) - _mesa_UpdateTexEnvProgram(ctx); - } - /* ctx->_NeedEyeCoords is now up to date. * * If the truth value of this variable has changed, update for the @@ -1266,6 +1286,20 @@ _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_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); + } + 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. |