Signed-off-by: Chris Forbes <chr...@ijw.co.nz> --- src/glsl/lower_ubo_reference.cpp | 50 ++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 20 deletions(-)
diff --git a/src/glsl/lower_ubo_reference.cpp b/src/glsl/lower_ubo_reference.cpp index c49ae34..80edd93 100644 --- a/src/glsl/lower_ubo_reference.cpp +++ b/src/glsl/lower_ubo_reference.cpp @@ -69,9 +69,10 @@ 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 **array_index) { - ir_constant *previous_index = NULL; + ir_rvalue *previous_index = NULL; + *array_index = NULL; while (d != NULL) { switch (d->ir_type) { @@ -79,13 +80,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) { + *array_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,16 +110,7 @@ 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(); - - if (!previous_index) { - /* The array index is not a constant, so let's find - * the first element of the array. Elsewhere we guarantee - * that the entire array is valid if used with a non-constant - * index. - */ - previous_index = new(mem_ctx) ir_constant(0u); - } + previous_index = a->array_index; break; } @@ -141,14 +141,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]; -- 2.0.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev