summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Forbes <chrisf@ijw.co.nz>2014-05-16 22:07:24 +1200
committerChris Forbes <chrisf@ijw.co.nz>2014-07-26 16:46:03 +1200
commitbe237a61297936227b2f4afc2ac28f60c3c76bbf (patch)
tree81883e71375d3e77935079314ea218d1b4cd28d7
parentc59802d3a147956d4f33586bb6221cd236987ee2 (diff)
glsl: Accept nonconstant array references in lower_ubo_reference
Instead of falling back to just the block name (which we won't find), look for the first element of the block array. We'll deal with the rest in the backend by arranging for the blocks to be laid out contiguously. V2: Squashed together patches 3, 5 of V1, plus a naming tweak. Signed-off-by: Chris Forbes <chrisf@ijw.co.nz> Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
-rw-r--r--src/glsl/lower_ubo_reference.cpp43
1 files changed, 32 insertions, 11 deletions
diff --git a/src/glsl/lower_ubo_reference.cpp b/src/glsl/lower_ubo_reference.cpp
index 9729ea071b3..67b752d3d22 100644
--- a/src/glsl/lower_ubo_reference.cpp
+++ b/src/glsl/lower_ubo_reference.cpp
@@ -69,9 +69,11 @@ public:
* \c UniformBlocks array.
*/
static const char *
-interface_field_name(void *mem_ctx, char *base_name, ir_dereference *d)
+interface_field_name(void *mem_ctx, char *base_name, ir_dereference *d,
+ ir_rvalue **nonconst_block_index)
{
- ir_constant *previous_index = NULL;
+ ir_rvalue *previous_index = NULL;
+ *nonconst_block_index = NULL;
while (d != NULL) {
switch (d->ir_type) {
@@ -79,13 +81,21 @@ interface_field_name(void *mem_ctx, char *base_name, ir_dereference *d)
ir_dereference_variable *v = (ir_dereference_variable *) d;
if (previous_index
&& v->var->is_interface_instance()
- && v->var->type->is_array())
- return ralloc_asprintf(mem_ctx,
- "%s[%d]",
- base_name,
- previous_index->get_uint_component(0));
- else
+ && v->var->type->is_array()) {
+
+ ir_constant *const_index = previous_index->as_constant();
+ if (!const_index) {
+ *nonconst_block_index = previous_index;
+ return ralloc_asprintf(mem_ctx, "%s[0]", base_name);
+ } else {
+ return ralloc_asprintf(mem_ctx,
+ "%s[%d]",
+ base_name,
+ const_index->get_uint_component(0));
+ }
+ } else {
return base_name;
+ }
break;
}
@@ -101,7 +111,8 @@ interface_field_name(void *mem_ctx, char *base_name, ir_dereference *d)
ir_dereference_array *a = (ir_dereference_array *) d;
d = a->array->as_dereference();
- previous_index = a->array_index->as_constant();
+ previous_index = a->array_index;
+
break;
}
@@ -131,14 +142,24 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue)
mem_ctx = ralloc_parent(*rvalue);
+ ir_rvalue *nonconst_block_index;
const char *const field_name =
interface_field_name(mem_ctx, (char *) var->get_interface_type()->name,
- deref);
+ deref, &nonconst_block_index);
this->uniform_block = NULL;
for (unsigned i = 0; i < shader->NumUniformBlocks; i++) {
if (strcmp(field_name, shader->UniformBlocks[i].Name) == 0) {
- this->uniform_block = new(mem_ctx) ir_constant(i);
+
+ ir_constant *index = new(mem_ctx) ir_constant(i);
+
+ if (nonconst_block_index) {
+ if (nonconst_block_index->type != glsl_type::uint_type)
+ nonconst_block_index = i2u(nonconst_block_index);
+ this->uniform_block = add(nonconst_block_index, index);
+ } else {
+ this->uniform_block = index;
+ }
struct gl_uniform_block *block = &shader->UniformBlocks[i];