summaryrefslogtreecommitdiff
path: root/src/mesa/main/state.c
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2009-03-03 13:52:24 -0700
committerBrian Paul <brianp@vmware.com>2009-03-03 13:55:25 -0700
commitde1caa550700ae38ff791c30f6d482f3efddebd0 (patch)
tree7aeb0c7fdb042be1039ffb33895943187a0b447e /src/mesa/main/state.c
parent317a7da2c452f35ef627aec6fc4d31406758725d (diff)
mesa: fix sw fallback state validation bug
When a hw driver fell back to swrast, swrast wasn't always getting informed of program changes. When fixed function is translated into shaders, flags like _NEW_LIGHT, _NEW_TEXTURE, etc. should really signal _NEW_PROGRAM. In this case, swrast wasn't seeing _NEW_PROGRAM when new fragment shaders were generated.
Diffstat (limited to 'src/mesa/main/state.c')
-rw-r--r--src/mesa/main/state.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 9ea932ea96..9d03ee744d 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -202,13 +202,17 @@ update_program_enables(GLcontext *ctx)
*
* This function needs to be called after texture state validation in case
* we're generating a fragment program from fixed-function texture state.
+ *
+ * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex
+ * or fragment program is being used.
*/
-static void
+static GLbitfield
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;
+ GLbitfield new_state = 0x0;
/*
* Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
@@ -278,15 +282,23 @@ update_program(GLcontext *ctx)
/* 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->FragmentProgram._Current != prevFP) {
+ new_state |= _NEW_PROGRAM;
+ if (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);
+ if (ctx->VertexProgram._Current != prevVP) {
+ new_state |= _NEW_PROGRAM;
+ if (ctx->Driver.BindProgram) {
+ ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
+ (struct gl_program *) ctx->VertexProgram._Current);
+ }
}
+
+ return new_state;
}
@@ -447,6 +459,7 @@ _mesa_update_state_locked( GLcontext *ctx )
{
GLbitfield new_state = ctx->NewState;
GLbitfield prog_flags = _NEW_PROGRAM;
+ GLbitfield new_prog_state = 0x0;
if (new_state == _NEW_CURRENT_ATTRIB)
goto out;
@@ -531,8 +544,13 @@ _mesa_update_state_locked( GLcontext *ctx )
if (new_state & _MESA_NEW_NEED_EYE_COORDS)
_mesa_update_tnl_spaces( ctx, new_state );
- if (new_state & prog_flags)
- update_program( ctx );
+ if (new_state & prog_flags) {
+ /* When we generate programs from fixed-function vertex/fragment state
+ * this call may generate/bind a new program. If so, we need to
+ * propogate the _NEW_PROGRAM flag to the driver.
+ */
+ new_prog_state |= update_program( ctx );
+ }
/*
* Give the driver a chance to act upon the new_state flags.
@@ -544,7 +562,7 @@ _mesa_update_state_locked( GLcontext *ctx )
* Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?)
*/
out:
- new_state = ctx->NewState;
+ new_state = ctx->NewState | new_prog_state;
ctx->NewState = 0;
ctx->Driver.UpdateState(ctx, new_state);
ctx->Array.NewState = 0;