[Mesa-dev] [PATCH] mesa: Only update sampler uniforms that are used by the shader stage
Ian Romanick
idr at freedesktop.org
Mon Nov 14 11:25:32 PST 2011
From: Ian Romanick <ian.d.romanick at intel.com>
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 <ian.d.romanick at intel.com>
---
src/mesa/main/uniform_query.cpp | 22 +++++++++++++++++++---
1 files 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;
--
1.7.6.4
More information about the mesa-dev
mailing list