From d6863acb9f40fd36eb18e873def31a3b72e0d68a Mon Sep 17 00:00:00 2001 From: Jordan Justen Date: Sun, 17 Mar 2013 02:04:56 -0700 Subject: [PATCH] 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 Reviewed-by: Kenneth Graunke --- src/glsl/lower_named_interface_blocks.cpp | 61 +++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/src/glsl/lower_named_interface_blocks.cpp b/src/glsl/lower_named_interface_blocks.cpp index f3a2ad5..eba667a 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; + } } } -- 2.7.4