summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/ir_uniform.h27
-rw-r--r--src/glsl/link_uniform_initializers.cpp25
-rw-r--r--src/glsl/link_uniforms.cpp126
-rw-r--r--src/glsl/tests/set_uniform_initializer_tests.cpp10
4 files changed, 109 insertions, 79 deletions
diff --git a/src/glsl/ir_uniform.h b/src/glsl/ir_uniform.h
index 30e6f260d75..8198c481983 100644
--- a/src/glsl/ir_uniform.h
+++ b/src/glsl/ir_uniform.h
@@ -99,15 +99,24 @@ struct gl_uniform_storage {
*/
bool initialized;
- /**
- * Base sampler index
- *
- * If \c ::base_type is \c GLSL_TYPE_SAMPLER, this represents the index of
- * this sampler. If \c ::array_elements is not zero, the array will use
- * sampler indexes \c ::sampler through \c ::sampler + \c ::array_elements
- * - 1, inclusive.
- */
- uint8_t sampler;
+ struct {
+ /**
+ * Base sampler index
+ *
+ * If \c ::base_type is \c GLSL_TYPE_SAMPLER, this represents the index
+ * of this sampler. If \c ::array_elements is not zero, the array will
+ * use sampler indices \c ::sampler through \c ::sampler +
+ * \c ::array_elements - 1, inclusive.
+ *
+ * Note that the index may be different in each shader stage.
+ */
+ uint8_t index;
+
+ /**
+ * Whether this sampler is used in this shader stage.
+ */
+ bool active;
+ } sampler[MESA_SHADER_TYPES];
/**
* Storage used by the driver for the uniform
diff --git a/src/glsl/link_uniform_initializers.cpp b/src/glsl/link_uniform_initializers.cpp
index 836a360fafd..54d9bf1f528 100644
--- a/src/glsl/link_uniform_initializers.cpp
+++ b/src/glsl/link_uniform_initializers.cpp
@@ -138,8 +138,16 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
}
if (base_type == GLSL_TYPE_SAMPLER) {
- for (unsigned int i = 0; i < storage->array_elements; i++) {
- prog->SamplerUnits[storage->sampler + i] = storage->storage[i].i;
+ for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
+ gl_shader *shader = prog->_LinkedShaders[sh];
+
+ if (shader && storage->sampler[sh].active) {
+ for (unsigned i = 0; i < storage->array_elements; i++) {
+ unsigned index = storage->sampler[sh].index + i;
+
+ shader->SamplerUnits[index] = storage->storage[i].i;
+ }
+ }
}
}
} else {
@@ -148,8 +156,17 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
val->type->base_type,
val->type->components());
- if (storage->type->is_sampler())
- prog->SamplerUnits[storage->sampler] = storage->storage[0].i;
+ if (storage->type->is_sampler()) {
+ for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
+ gl_shader *shader = prog->_LinkedShaders[sh];
+
+ if (shader && storage->sampler[sh].active) {
+ unsigned index = storage->sampler[sh].index;
+
+ shader->SamplerUnits[index] = storage->storage[0].i;
+ }
+ }
+ }
}
storage->initialized = true;
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
index d457e4d0cd9..04218be7ac9 100644
--- a/src/glsl/link_uniforms.cpp
+++ b/src/glsl/link_uniforms.cpp
@@ -263,15 +263,19 @@ public:
parcel_out_uniform_storage(struct string_to_uint_map *map,
struct gl_uniform_storage *uniforms,
union gl_constant_value *values)
- : map(map), uniforms(uniforms), next_sampler(0), values(values)
+ : map(map), uniforms(uniforms), values(values)
{
- memset(this->targets, 0, sizeof(this->targets));
}
- void start_shader()
+ void start_shader(gl_shader_type shader_type)
{
+ assert(shader_type < MESA_SHADER_TYPES);
+ this->shader_type = shader_type;
+
this->shader_samplers_used = 0;
this->shader_shadow_samplers = 0;
+ this->next_sampler = 0;
+ memset(this->targets, 0, sizeof(this->targets));
}
void set_and_process(struct gl_shader_program *prog,
@@ -335,8 +339,37 @@ public:
int ubo_block_index;
int ubo_byte_offset;
bool ubo_row_major;
+ gl_shader_type shader_type;
private:
+ void handle_samplers(const glsl_type *base_type,
+ struct gl_uniform_storage *uniform)
+ {
+ if (base_type->is_sampler()) {
+ uniform->sampler[shader_type].index = this->next_sampler;
+ uniform->sampler[shader_type].active = true;
+
+ /* Increment the sampler by 1 for non-arrays and by the number of
+ * array elements for arrays.
+ */
+ this->next_sampler +=
+ MAX2(1, uniform->array_elements);
+
+ const gl_texture_index target = base_type->sampler_index();
+ const unsigned shadow = base_type->sampler_shadow;
+ for (unsigned i = uniform->sampler[shader_type].index;
+ i < MIN2(this->next_sampler, MAX_SAMPLERS);
+ i++) {
+ this->targets[i] = target;
+ this->shader_samplers_used |= 1U << i;
+ this->shader_shadow_samplers |= shadow << i;
+ }
+ } else {
+ uniform->sampler[shader_type].index = ~0;
+ uniform->sampler[shader_type].active = false;
+ }
+ }
+
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major)
{
@@ -354,31 +387,6 @@ private:
if (!found)
return;
- /* If there is already storage associated with this uniform, it means
- * that it was set while processing an earlier shader stage. For
- * 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 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->uniforms[id].array_elements = type->length;
@@ -388,26 +396,16 @@ private:
base_type = type;
}
- if (base_type->is_sampler()) {
- this->uniforms[id].sampler = this->next_sampler;
+ /* This assigns sampler uniforms to sampler units. */
+ handle_samplers(base_type, &this->uniforms[id]);
- /* Increment the sampler by 1 for non-arrays and by the number of
- * array elements for arrays.
- */
- 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 < MIN2(this->next_sampler, MAX_SAMPLERS)
- ; i++) {
- this->targets[i] = target;
- this->shader_samplers_used |= 1U << i;
- this->shader_shadow_samplers |= shadow << i;
- }
-
- } else {
- this->uniforms[id].sampler = ~0;
+ /* If there is already storage associated with this uniform, it means
+ * that it was set while processing an earlier shader stage. For
+ * 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) {
+ return;
}
this->uniforms[id].name = ralloc_strdup(this->uniforms, name);
@@ -633,17 +631,6 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
prog->UniformHash = new string_to_uint_map;
}
- /* Uniforms that lack an initializer in the shader code have an initial
- * value of zero. This includes sampler uniforms.
- *
- * Page 24 (page 30 of the PDF) of the GLSL 1.20 spec says:
- *
- * "The link time initial value is either the value of the variable's
- * initializer, if present, or 0 if no initializer is present. Sampler
- * types cannot have initializers."
- */
- memset(prog->SamplerUnits, 0, sizeof(prog->SamplerUnits));
-
/* First pass: Count the uniform resources used by the user-defined
* uniforms. While this happens, each active uniform will have an index
* assigned to it.
@@ -656,6 +643,18 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
if (prog->_LinkedShaders[i] == NULL)
continue;
+ /* Uniforms that lack an initializer in the shader code have an initial
+ * value of zero. This includes sampler uniforms.
+ *
+ * Page 24 (page 30 of the PDF) of the GLSL 1.20 spec says:
+ *
+ * "The link time initial value is either the value of the variable's
+ * initializer, if present, or 0 if no initializer is present. Sampler
+ * types cannot have initializers."
+ */
+ memset(prog->_LinkedShaders[i]->SamplerUnits, 0,
+ sizeof(gl_shader::SamplerUnits));
+
link_update_uniform_buffer_variables(prog->_LinkedShaders[i]);
/* Reset various per-shader target counts.
@@ -706,9 +705,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
if (prog->_LinkedShaders[i] == NULL)
continue;
- /* Reset various per-shader target counts.
- */
- parcel.start_shader();
+ parcel.start_shader((gl_shader_type)i);
foreach_list(node, prog->_LinkedShaders[i]->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
@@ -726,10 +723,11 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
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));
- memcpy(prog->SamplerTargets, parcel.targets, sizeof(prog->SamplerTargets));
+ assert(sizeof(gl_shader::SamplerTargets) == sizeof(parcel.targets));
+ memcpy(prog->_LinkedShaders[i]->SamplerTargets, parcel.targets,
+ sizeof(gl_shader::SamplerTargets));
+ }
#ifndef NDEBUG
for (unsigned i = 0; i < num_user_uniforms; i++) {
diff --git a/src/glsl/tests/set_uniform_initializer_tests.cpp b/src/glsl/tests/set_uniform_initializer_tests.cpp
index 55831f914ca..5c6d4a51491 100644
--- a/src/glsl/tests/set_uniform_initializer_tests.cpp
+++ b/src/glsl/tests/set_uniform_initializer_tests.cpp
@@ -116,7 +116,10 @@ establish_uniform_storage(struct gl_shader_program *prog, unsigned num_storage,
prog->UniformStorage[index_to_set].type = type;
prog->UniformStorage[index_to_set].array_elements = array_size;
prog->UniformStorage[index_to_set].initialized = false;
- prog->UniformStorage[index_to_set].sampler = ~0;
+ for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
+ prog->UniformStorage[index_to_set].sampler[sh].index = ~0;
+ prog->UniformStorage[index_to_set].sampler[sh].active = false;
+ }
prog->UniformStorage[index_to_set].num_driver_storage = 0;
prog->UniformStorage[index_to_set].driver_storage = NULL;
prog->UniformStorage[index_to_set].storage =
@@ -134,7 +137,10 @@ establish_uniform_storage(struct gl_shader_program *prog, unsigned num_storage,
prog->UniformStorage[i].type = glsl_type::void_type;
prog->UniformStorage[i].array_elements = 0;
prog->UniformStorage[i].initialized = false;
- prog->UniformStorage[i].sampler = ~0;
+ for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
+ prog->UniformStorage[i].sampler[sh].index = ~0;
+ prog->UniformStorage[i].sampler[sh].active = false;
+ }
prog->UniformStorage[i].num_driver_storage = 0;
prog->UniformStorage[i].driver_storage = NULL;
prog->UniformStorage[i].storage = NULL;