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 <ian.d.romanick@intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
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)
{
* 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()) {
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 {
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
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();
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));
unsigned Version; /**< GLSL version used for linking */
- unsigned num_samplers; /**< Number of samplers used by this shader.
- * This field is only set post-linking.
- */
+ /**
+ * \name Sampler tracking
+ *
+ * \note Each of these fields is only set post-linking.
+ */
+ /*@{*/
+ unsigned num_samplers; /**< Number of samplers used by this shader. */
+ GLbitfield active_samplers; /**< Bitfield of which samplers are used */
+ GLbitfield shadow_samplers; /**< Samplers used for shadow sampling. */
+ /*@}*/
+
/**
* Number of uniform components used by this shader.
*
bool flushed = false;
for (i = 0; i < MESA_SHADER_TYPES; i++) {
- struct gl_program *prog;
-
- if (shProg->_LinkedShaders[i] == NULL)
- continue;
-
- prog = shProg->_LinkedShaders[i]->Program;
+ struct gl_shader *const sh = shProg->_LinkedShaders[i];
/* If the shader stage doesn't use any samplers, don't bother
* checking if any samplers have changed.
*/
- if (prog->SamplersUsed == 0)
+ if (sh == NULL || sh->active_samplers == 0)
continue;
+ struct gl_program *const prog = sh->Program;
+
assert(sizeof(prog->SamplerUnits) == sizeof(shProg->SamplerUnits));
/* Determine if any of the samplers used by this shader stage have
*/
bool changed = false;
for (unsigned j = 0; j < Elements(prog->SamplerUnits); j++) {
- if ((prog->SamplersUsed & (1U << j)) != 0
+ if ((sh->active_samplers & (1U << j)) != 0
&& (prog->SamplerUnits[j] != shProg->SamplerUnits[j])) {
changed = true;
break;
}
}
-
-/**
- * Count resources used by the given gpu program (number of texture
- * samplers, etc).
- */
-static void
-count_resources(struct gl_shader_program *shProg, struct gl_program *prog)
-{
- unsigned int i;
-
- prog->SamplersUsed = 0;
-
- for (i = 0; i < prog->NumInstructions; i++) {
- struct prog_instruction *inst = &prog->Instructions[i];
-
- if (_mesa_is_tex_instruction(inst->Opcode)) {
- prog->SamplersUsed |= 1 << inst->TexSrcUnit;
- if (inst->TexShadow) {
- prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
- }
- }
- }
-
- _mesa_update_shader_textures_used(shProg, prog);
-}
-
class add_uniform_to_shader : public uniform_field_visitor {
public:
add_uniform_to_shader(struct gl_shader_program *shader_program,
mesa_instructions = NULL;
do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER);
- count_resources(shader_program, prog);
+
+ prog->SamplersUsed = shader->active_samplers;
+ prog->ShadowSamplers = shader->shadow_samplers;
+ _mesa_update_shader_textures_used(shader_program, prog);
/* Set the gl_FragDepth layout. */
if (target == GL_FRAGMENT_PROGRAM_ARB) {