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 <jordan.l.justen@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -106,22 +106,51 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
|
|||||||
if (var->mode == ir_var_uniform)
|
if (var->mode == ir_var_uniform)
|
||||||
continue;
|
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;
|
exec_node *insert_pos = var;
|
||||||
char *iface_field_name;
|
|
||||||
for (unsigned i = 0; i < t->length; i++) {
|
if (iface_t->is_array()) {
|
||||||
iface_field_name = ralloc_asprintf(mem_ctx, "%s.%s", t->name,
|
array_t = iface_t;
|
||||||
t->fields.structure[i].name);
|
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 *found_var =
|
||||||
(ir_variable *) hash_table_find(interface_namespace,
|
(ir_variable *) hash_table_find(interface_namespace,
|
||||||
iface_field_name);
|
iface_field_name);
|
||||||
if (!found_var) {
|
if (!found_var) {
|
||||||
ir_variable *new_var =
|
ir_variable *new_var;
|
||||||
new(mem_ctx) ir_variable(t->fields.structure[i].type,
|
if (array_t == NULL) {
|
||||||
ralloc_strdup(mem_ctx, t->fields.structure[i].name),
|
char *var_name =
|
||||||
(ir_variable_mode) var->mode);
|
ralloc_strdup(mem_ctx, iface_t->fields.structure[i].name);
|
||||||
new_var->interface_type = t;
|
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,
|
hash_table_insert(interface_namespace, new_var,
|
||||||
iface_field_name);
|
iface_field_name);
|
||||||
insert_pos->insert_after(new_var);
|
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,
|
(ir_variable *) hash_table_find(interface_namespace,
|
||||||
iface_field_name);
|
iface_field_name);
|
||||||
assert(found_var);
|
assert(found_var);
|
||||||
|
|
||||||
ir_dereference_variable *deref_var =
|
ir_dereference_variable *deref_var =
|
||||||
new(mem_ctx) ir_dereference_variable(found_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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user