[Mesa-dev] [PATCH 5/6] glsl: Plumb through UBO array indexing expressions
Chris Forbes
chrisf at ijw.co.nz
Sat Jul 12 18:52:00 PDT 2014
Signed-off-by: Chris Forbes <chrisf at 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
More information about the mesa-dev
mailing list