diff options
author | Jordan Justen <[email protected]> | 2013-03-17 02:04:56 -0700 |
---|---|---|
committer | Jordan Justen <[email protected]> | 2013-05-23 09:37:12 -0700 |
commit | d6863acb9f40fd36eb18e873def31a3b72e0d68a (patch) | |
tree | d71430c9d7ed60ac9bf3b5a5f504889a79f1e86d | |
parent | c30ca431ba06456259435e63a11f0bf24802e8ae (diff) |
glsl linker: support arrays of interface block instances
With this change we now support interface block arrays.
For example, cases like this:
out block_name {
float f;
} block_instance[2];
This allows Mesa to pass the piglit glsl-1.50 test:
* execution/interface-blocks-complex-vs-fs.shader_test
Signed-off-by: Jordan Justen <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r-- | src/glsl/lower_named_interface_blocks.cpp | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/src/glsl/lower_named_interface_blocks.cpp b/src/glsl/lower_named_interface_blocks.cpp index f3a2ad5d7de..eba667a8bfe 100644 --- a/src/glsl/lower_named_interface_blocks.cpp +++ b/src/glsl/lower_named_interface_blocks.cpp @@ -106,22 +106,51 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions) if (var->mode == ir_var_uniform) continue; - const glsl_type *const t = var->type; + const glsl_type * iface_t = var->type; + const glsl_type * array_t = NULL; exec_node *insert_pos = var; - char *iface_field_name; - for (unsigned i = 0; i < t->length; i++) { - iface_field_name = ralloc_asprintf(mem_ctx, "%s.%s", t->name, - t->fields.structure[i].name); + + if (iface_t->is_array()) { + array_t = iface_t; + iface_t = array_t->fields.array; + } + + assert (iface_t->is_interface()); + + for (unsigned i = 0; i < iface_t->length; i++) { + const char * field_name = iface_t->fields.structure[i].name; + char *iface_field_name = + ralloc_asprintf(mem_ctx, "%s.%s", + iface_t->name, field_name); ir_variable *found_var = (ir_variable *) hash_table_find(interface_namespace, iface_field_name); if (!found_var) { - ir_variable *new_var = - new(mem_ctx) ir_variable(t->fields.structure[i].type, - ralloc_strdup(mem_ctx, t->fields.structure[i].name), - (ir_variable_mode) var->mode); - new_var->interface_type = t; + ir_variable *new_var; + if (array_t == NULL) { + char *var_name = + ralloc_strdup(mem_ctx, iface_t->fields.structure[i].name); + new_var = + new(mem_ctx) ir_variable(iface_t->fields.structure[i].type, + var_name, + (ir_variable_mode) var->mode); + } else { + const glsl_type *new_array_type = + glsl_type::get_array_instance( + iface_t->fields.structure[i].type, + array_t->length); + char *var_name = + ralloc_asprintf(mem_ctx, "%s[%d]", + iface_t->fields.structure[i].name, + array_t->length); + new_var = + new(mem_ctx) ir_variable(new_array_type, + var_name, + (ir_variable_mode) var->mode); + } + + new_var->interface_type = iface_t; hash_table_insert(interface_namespace, new_var, iface_field_name); insert_pos->insert_after(new_var); @@ -184,9 +213,19 @@ flatten_named_interface_blocks_declarations::handle_rvalue(ir_rvalue **rvalue) (ir_variable *) hash_table_find(interface_namespace, iface_field_name); assert(found_var); + ir_dereference_variable *deref_var = new(mem_ctx) ir_dereference_variable(found_var); - *rvalue = deref_var; + + ir_dereference_array *deref_array = + ir->record->as_dereference_array(); + if (deref_array != NULL) { + *rvalue = + new(mem_ctx) ir_dereference_array(deref_var, + deref_array->array_index); + } else { + *rvalue = deref_var; + } } } |