summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJordan Justen <[email protected]>2013-03-17 02:04:56 -0700
committerJordan Justen <[email protected]>2013-05-23 09:37:12 -0700
commitd6863acb9f40fd36eb18e873def31a3b72e0d68a (patch)
treed71430c9d7ed60ac9bf3b5a5f504889a79f1e86d /src
parentc30ca431ba06456259435e63a11f0bf24802e8ae (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]>
Diffstat (limited to 'src')
-rw-r--r--src/glsl/lower_named_interface_blocks.cpp61
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;
+ }
}
}