diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h index b74d68a605b..56ed13e7153 100644 --- a/src/compiler/glsl/ir.h +++ b/src/compiler/glsl/ir.h @@ -742,21 +742,9 @@ public: /** * Non-zero if this variable was created by lowering a named interface - * block which was not an array. - * - * Note that this variable and \c from_named_ifc_block_array will never - * both be non-zero. + * block. */ - unsigned from_named_ifc_block_nonarray:1; - - /** - * Non-zero if this variable was created by lowering a named interface - * block which was an array. - * - * Note that this variable and \c from_named_ifc_block_nonarray will never - * both be non-zero. - */ - unsigned from_named_ifc_block_array:1; + unsigned from_named_ifc_block:1; /** * Non-zero if the variable must be a shader input. This is useful for diff --git a/src/compiler/glsl/link_interface_blocks.cpp b/src/compiler/glsl/link_interface_blocks.cpp index 4c6fb56f891..26072591b0e 100644 --- a/src/compiler/glsl/link_interface_blocks.cpp +++ b/src/compiler/glsl/link_interface_blocks.cpp @@ -242,7 +242,8 @@ public: return entry ? (ir_variable *) entry->data : NULL; } else { const struct hash_entry *entry = - _mesa_hash_table_search(ht, var->get_interface_type()->name); + _mesa_hash_table_search(ht, + var->get_interface_type()->without_array()->name); return entry ? (ir_variable *) entry->data : NULL; } } @@ -263,7 +264,8 @@ public: snprintf(location_str, 11, "%d", var->data.location); _mesa_hash_table_insert(ht, ralloc_strdup(mem_ctx, location_str), var); } else { - _mesa_hash_table_insert(ht, var->get_interface_type()->name, var); + _mesa_hash_table_insert(ht, + var->get_interface_type()->without_array()->name, var); } } diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp index cd487ab6dd0..0a230cad034 100644 --- a/src/compiler/glsl/link_uniforms.cpp +++ b/src/compiler/glsl/link_uniforms.cpp @@ -68,7 +68,7 @@ program_resource_visitor::process(const glsl_type *type, const char *name) unsigned packing = type->interface_packing; recursion(type, &name_copy, strlen(name), false, NULL, packing, false, - record_array_count); + record_array_count, NULL); ralloc_free(name_copy); } @@ -76,8 +76,6 @@ void program_resource_visitor::process(ir_variable *var) { unsigned record_array_count = 1; - const glsl_type *t = var->type; - const glsl_type *t_without_array = var->type->without_array(); const bool row_major = var->data.matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR; @@ -85,80 +83,28 @@ program_resource_visitor::process(ir_variable *var) var->get_interface_type()->interface_packing : var->type->interface_packing; + const glsl_type *t = + var->data.from_named_ifc_block ? var->get_interface_type() : var->type; + const glsl_type *t_without_array = t->without_array(); + /* false is always passed for the row_major parameter to the other * processing functions because no information is available to do * otherwise. See the warning in linker.h. */ - - /* Only strdup the name if we actually will need to modify it. */ - if (var->data.from_named_ifc_block_array) { - /* lower_named_interface_blocks created this variable by lowering an - * interface block array to an array variable. For example if the - * original source code was: - * - * out Blk { vec4 bar } foo[3]; - * - * Then the variable is now: - * - * out vec4 bar[3]; - * - * We need to visit each array element using the names constructed like - * so: - * - * Blk[0].bar - * Blk[1].bar - * Blk[2].bar - */ - assert(t->is_array()); - const glsl_type *ifc_type = var->get_interface_type(); - char *name = ralloc_strdup(NULL, ifc_type->name); - size_t name_length = strlen(name); - for (unsigned i = 0; i < t->length; i++) { - size_t new_length = name_length; - ralloc_asprintf_rewrite_tail(&name, &new_length, "[%u].%s", i, - var->name); - /* Note: row_major is only meaningful for uniform blocks, and - * lowering is only applied to non-uniform interface blocks, so we - * can safely pass false for row_major. - */ - recursion(var->type, &name, new_length, row_major, NULL, packing, - false, record_array_count); - } - ralloc_free(name); - } else if (var->data.from_named_ifc_block_nonarray) { - /* lower_named_interface_blocks created this variable by lowering a - * named interface block (non-array) to an ordinary variable. For - * example if the original source code was: - * - * out Blk { vec4 bar } foo; - * - * Then the variable is now: - * - * out vec4 bar; - * - * We need to visit this variable using the name: - * - * Blk.bar - */ - const glsl_type *ifc_type = var->get_interface_type(); - char *name = ralloc_asprintf(NULL, "%s.%s", ifc_type->name, var->name); - /* Note: row_major is only meaningful for uniform blocks, and lowering - * is only applied to non-uniform interface blocks, so we can safely - * pass false for row_major. - */ - recursion(var->type, &name, strlen(name), row_major, NULL, packing, - false, record_array_count); - ralloc_free(name); - } else if (t_without_array->is_record() || + if (t_without_array->is_record() || (t->is_array() && t->fields.array->is_array())) { char *name = ralloc_strdup(NULL, var->name); recursion(var->type, &name, strlen(name), row_major, NULL, packing, - false, record_array_count); + false, record_array_count, NULL); ralloc_free(name); } else if (t_without_array->is_interface()) { char *name = ralloc_strdup(NULL, t_without_array->name); - recursion(var->type, &name, strlen(name), row_major, NULL, packing, - false, record_array_count); + const glsl_struct_field *ifc_member = var->data.from_named_ifc_block ? + &t_without_array-> + fields.structure[t_without_array->field_index(var->name)] : NULL; + + recursion(t, &name, strlen(name), row_major, NULL, packing, + false, record_array_count, ifc_member); ralloc_free(name); } else { this->set_record_array_count(record_array_count); @@ -172,7 +118,8 @@ program_resource_visitor::recursion(const glsl_type *t, char **name, const glsl_type *record_type, const unsigned packing, bool last_field, - unsigned record_array_count) + unsigned record_array_count, + const glsl_struct_field *named_ifc_member) { /* Records need to have each field processed individually. * @@ -180,7 +127,12 @@ program_resource_visitor::recursion(const glsl_type *t, char **name, * individually, then each field of the resulting array elements processed * individually. */ - if (t->is_record() || t->is_interface()) { + if (t->is_interface() && named_ifc_member) { + ralloc_asprintf_rewrite_tail(name, &name_length, ".%s", + named_ifc_member->name); + recursion(named_ifc_member->type, name, name_length, row_major, NULL, + packing, false, record_array_count, NULL); + } else if (t->is_record() || t->is_interface()) { if (record_type == NULL && t->is_record()) record_type = t; @@ -223,7 +175,7 @@ program_resource_visitor::recursion(const glsl_type *t, char **name, field_row_major, record_type, packing, - (i + 1) == t->length, record_array_count); + (i + 1) == t->length, record_array_count, NULL); /* Only the first leaf-field of the record gets called with the * record type pointer. @@ -258,7 +210,8 @@ program_resource_visitor::recursion(const glsl_type *t, char **name, recursion(t->fields.array, name, new_length, row_major, record_type, packing, - (i + 1) == t->length, record_array_count); + (i + 1) == t->length, record_array_count, + named_ifc_member); /* Only the first leaf-field of the record gets called with the * record type pointer. diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp index 44fc8f617f8..dadbf1e6859 100644 --- a/src/compiler/glsl/link_varyings.cpp +++ b/src/compiler/glsl/link_varyings.cpp @@ -1466,8 +1466,8 @@ populate_consumer_input_sets(void *mem_ctx, exec_list *ir, } else if (input_var->get_interface_type() != NULL) { char *const iface_field_name = ralloc_asprintf(mem_ctx, "%s.%s", - input_var->get_interface_type()->name, - input_var->name); + input_var->get_interface_type()->without_array()->name, + input_var->name); hash_table_insert(consumer_interface_inputs, input_var, iface_field_name); } else { @@ -1498,8 +1498,8 @@ get_matching_input(void *mem_ctx, } else if (output_var->get_interface_type() != NULL) { char *const iface_field_name = ralloc_asprintf(mem_ctx, "%s.%s", - output_var->get_interface_type()->name, - output_var->name); + output_var->get_interface_type()->without_array()->name, + output_var->name); input_var = (ir_variable *) hash_table_find(consumer_interface_inputs, iface_field_name); diff --git a/src/compiler/glsl/linker.h b/src/compiler/glsl/linker.h index 4311d1659ec..97144df8ff7 100644 --- a/src/compiler/glsl/linker.h +++ b/src/compiler/glsl/linker.h @@ -197,7 +197,8 @@ private: void recursion(const glsl_type *t, char **name, size_t name_length, bool row_major, const glsl_type *record_type, const unsigned packing, - bool last_field, unsigned record_array_count); + bool last_field, unsigned record_array_count, + const glsl_struct_field *named_ifc_member); }; void diff --git a/src/compiler/glsl/lower_named_interface_blocks.cpp b/src/compiler/glsl/lower_named_interface_blocks.cpp index f29eba4f75f..434cea90920 100644 --- a/src/compiler/glsl/lower_named_interface_blocks.cpp +++ b/src/compiler/glsl/lower_named_interface_blocks.cpp @@ -169,7 +169,6 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions) new(mem_ctx) ir_variable(iface_t->fields.structure[i].type, var_name, (ir_variable_mode) var->data.mode); - new_var->data.from_named_ifc_block_nonarray = 1; } else { const glsl_type *new_array_type = process_array_type(var->type, i); @@ -177,7 +176,6 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions) new(mem_ctx) ir_variable(new_array_type, var_name, (ir_variable_mode) var->data.mode); - new_var->data.from_named_ifc_block_array = 1; } new_var->data.location = iface_t->fields.structure[i].location; new_var->data.explicit_location = (new_var->data.location >= 0); @@ -188,8 +186,9 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions) new_var->data.patch = iface_t->fields.structure[i].patch; new_var->data.stream = var->data.stream; new_var->data.how_declared = var->data.how_declared; + new_var->data.from_named_ifc_block = 1; - new_var->init_interface_type(iface_t); + new_var->init_interface_type(var->type); hash_table_insert(interface_namespace, new_var, iface_field_name); insert_pos->insert_after(new_var);