diff options
Diffstat (limited to 'mesalib/src/glsl/lower_ubo_reference.cpp')
-rw-r--r-- | mesalib/src/glsl/lower_ubo_reference.cpp | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/mesalib/src/glsl/lower_ubo_reference.cpp b/mesalib/src/glsl/lower_ubo_reference.cpp index 90e65bd0e..67b752d3d 100644 --- a/mesalib/src/glsl/lower_ubo_reference.cpp +++ b/mesalib/src/glsl/lower_ubo_reference.cpp @@ -57,7 +57,7 @@ public: void *mem_ctx; struct gl_shader *shader; struct gl_uniform_buffer_variable *ubo_var; - unsigned uniform_block; + ir_rvalue *uniform_block; bool progress; }; @@ -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 = -1; + this->uniform_block = NULL; for (unsigned i = 0; i < shader->NumUniformBlocks; i++) { if (strcmp(field_name, shader->UniformBlocks[i].Name) == 0) { - this->uniform_block = 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]; @@ -149,7 +170,7 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue) } } - assert(this->uniform_block != (unsigned) -1); + assert(this->uniform_block); ir_rvalue *offset = new(mem_ctx) ir_constant(0u); unsigned const_offset = 0; @@ -267,11 +288,12 @@ ir_expression * lower_ubo_reference_visitor::ubo_load(const glsl_type *type, ir_rvalue *offset) { + ir_rvalue *block_ref = this->uniform_block->clone(mem_ctx, NULL); return new(mem_ctx) ir_expression(ir_binop_ubo_load, - type, - new(mem_ctx) ir_constant(this->uniform_block), - offset); + type, + block_ref, + offset); } |