diff options
author | Ian Romanick <[email protected]> | 2011-11-14 21:58:50 -0800 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2012-01-11 12:51:24 -0800 |
commit | 6c0df75803e1944f82a1468dcca47d23de82ea6b (patch) | |
tree | 7a908c29bbf66656cb33ac9a431a98536a76aeb5 /src/glsl/link_uniforms.cpp | |
parent | 6a992c3288b6f7a5d94172c9ad1908e71e58233e (diff) |
linker: Calculate used samplers and shadow samplers in the linker
It used to be done in ir_to_mesa, and that was kind of a bad place.
I didn't change st_glsl_to_tgsi because there is some strange stuff
happening in the code that generates glDrawPixels shaders. It looked
like this would break horribly if I touched anything.
Signed-off-by: Ian Romanick <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/glsl/link_uniforms.cpp')
-rw-r--r-- | src/glsl/link_uniforms.cpp | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp index 47d34cf0b79..02f57d91174 100644 --- a/src/glsl/link_uniforms.cpp +++ b/src/glsl/link_uniforms.cpp @@ -212,6 +212,12 @@ public: memset(this->targets, 0, sizeof(this->targets)); } + void start_shader() + { + this->shader_samplers_used = 0; + this->shader_shadow_samplers = 0; + } + private: virtual void visit_field(const glsl_type *type, const char *name) { @@ -230,8 +236,25 @@ private: * example, we may be processing the uniform in the fragment shader, but * the uniform was already processed in the vertex shader. */ - if (this->uniforms[id].storage != NULL) + if (this->uniforms[id].storage != NULL) { + /* If the uniform already has storage set from another shader stage, + * mark the samplers used for this shader stage. + */ + if (type->contains_sampler()) { + const unsigned count = MAX2(1, this->uniforms[id].array_elements); + const unsigned shadow = (type->is_array()) + ? type->fields.array->sampler_shadow : type->sampler_shadow; + + for (unsigned i = 0; i < count; i++) { + const unsigned s = this->uniforms[id].sampler + i; + + this->shader_samplers_used |= 1U << s; + this->shader_shadow_samplers |= shadow << s; + } + } + return; + } const glsl_type *base_type; if (type->is_array()) { @@ -251,10 +274,13 @@ private: this->next_sampler += MAX2(1, this->uniforms[id].array_elements); const gl_texture_index target = base_type->sampler_index(); + const unsigned shadow = base_type->sampler_shadow; for (unsigned i = this->uniforms[id].sampler ; i < this->next_sampler ; i++) { this->targets[i] = target; + this->shader_samplers_used |= 1U << i; + this->shader_shadow_samplers |= shadow << i; } } else { @@ -280,6 +306,16 @@ public: union gl_constant_value *values; gl_texture_index targets[MAX_SAMPLERS]; + + /** + * Mask of samplers used by the current shader stage. + */ + unsigned shader_samplers_used; + + /** + * Mask of samplers used by the current shader stage for shadows. + */ + unsigned shader_shadow_samplers; }; void @@ -356,6 +392,10 @@ link_assign_uniform_locations(struct gl_shader_program *prog) if (prog->_LinkedShaders[i] == NULL) continue; + /* Reset various per-shader target counts. + */ + parcel.start_shader(); + foreach_list(node, prog->_LinkedShaders[i]->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); @@ -369,6 +409,9 @@ link_assign_uniform_locations(struct gl_shader_program *prog) parcel.process(var); } + + prog->_LinkedShaders[i]->active_samplers = parcel.shader_samplers_used; + prog->_LinkedShaders[i]->shadow_samplers = parcel.shader_shadow_samplers; } assert(sizeof(prog->SamplerTargets) == sizeof(parcel.targets)); |