From 010dc29283cfc7791a29ba8a0570d8f7f9edef05 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 10 Nov 2011 12:32:35 -0800 Subject: [PATCH] mesa: Only update sampler uniforms that are used by the shader stage Previously a vertex shader that used no samplers would get updated (by calling the driver's ProgramStringNotify) when a sampler in the fragment shader was updated. This was discovered while investigating some spurious code generation for shaders in Cogs. The behavior in Cogs is especially pessimal because it ping-pongs sampler uniform settings: glUniform1i(sampler1, 0); glUniform1i(sampler2, 1); draw(); glUniform1i(sampler1, 1); glUniform1i(sampler2, 0); draw(); glUniform1i(sampler1, 0); glUniform1i(sampler2, 1); draw(); // etc. ProgramStringNotify is still too big of a hammer. Applications like Cogs will still defeat the shader cache. A lighter-weight mechanism that can work with the shader cache is needed. However, this patch at least restores the previous behavior. Signed-off-by: Ian Romanick Reviewed-by: Kenneth Graunke --- src/mesa/main/uniform_query.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp index 5371d6a..33ba53c 100644 --- a/src/mesa/main/uniform_query.cpp +++ b/src/mesa/main/uniform_query.cpp @@ -698,11 +698,27 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, prog = shProg->_LinkedShaders[i]->Program; + /* If the shader stage doesn't use any samplers, don't bother + * checking if any samplers have changed. + */ + if (prog->SamplersUsed == 0) + continue; + assert(sizeof(prog->SamplerUnits) == sizeof(shProg->SamplerUnits)); - if (memcmp(prog->SamplerUnits, - shProg->SamplerUnits, - sizeof(shProg->SamplerUnits)) != 0) { + /* Determine if any of the samplers used by this shader stage have + * been modified. + */ + bool changed = false; + for (unsigned j = 0; j < Elements(prog->SamplerUnits); j++) { + if ((prog->SamplersUsed & (1U << j)) != 0 + && (prog->SamplerUnits[j] != shProg->SamplerUnits[j])) { + changed = true; + break; + } + } + + if (changed) { if (!flushed) { FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM); flushed = true; -- 2.7.4