[Mesa-dev] [PATCH v3 15/17] glsl linker: support arrays of interface block instances
Jordan Justen
jordan.l.justen at intel.com
Mon Mar 25 17:41:40 PDT 2013
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 at intel.com>
---
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 2e0c322..699a345 100644
--- a/src/glsl/lower_named_interface_blocks.cpp
+++ b/src/glsl/lower_named_interface_blocks.cpp
@@ -107,22 +107,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);
@@ -187,9 +216,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;
+ }
}
}
--
1.7.10.4
More information about the mesa-dev
mailing list