aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl/opt_array_splitting.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl/opt_array_splitting.cpp')
-rw-r--r--mesalib/src/glsl/opt_array_splitting.cpp53
1 files changed, 37 insertions, 16 deletions
diff --git a/mesalib/src/glsl/opt_array_splitting.cpp b/mesalib/src/glsl/opt_array_splitting.cpp
index f11b51631..67733ca6b 100644
--- a/mesalib/src/glsl/opt_array_splitting.cpp
+++ b/mesalib/src/glsl/opt_array_splitting.cpp
@@ -49,7 +49,7 @@ public:
variable_entry(ir_variable *var)
{
this->var = var;
- this->whole_array_access = 0;
+ this->split = true;
this->declaration = false;
this->components = NULL;
this->mem_ctx = NULL;
@@ -62,10 +62,14 @@ public:
ir_variable *var; /* The key: the variable's pointer. */
unsigned size; /* array length or matrix columns */
- /** Number of times the variable is referenced, including assignments. */
- unsigned whole_array_access;
+ /** Whether this array should be split or not. */
+ bool split;
- bool declaration; /* If the variable had a decl in the instruction stream */
+ /* If the variable had a decl we can work with in the instruction
+ * stream. We can't do splitting on function arguments, which
+ * don't get this variable set.
+ */
+ bool declaration;
ir_variable **components;
@@ -99,6 +103,7 @@ public:
virtual ir_visitor_status visit(ir_variable *);
virtual ir_visitor_status visit(ir_dereference_variable *);
virtual ir_visitor_status visit_enter(ir_dereference_array *);
+ virtual ir_visitor_status visit_enter(ir_function_signature *);
variable_entry *get_variable_entry(ir_variable *var);
@@ -154,12 +159,13 @@ ir_array_reference_visitor::visit(ir_dereference_variable *ir)
{
variable_entry *entry = this->get_variable_entry(ir->var);
- /* If we made it to here, then the dereference of this array didn't
- * have a constant index (see the visit_continue_with_parent
- * below), so we can't split the variable.
+ /* If we made it to here without seeing an ir_dereference_array,
+ * then the dereference of this array didn't have a constant index
+ * (see the visit_continue_with_parent below), so we can't split
+ * the variable.
*/
if (entry)
- entry->whole_array_access++;
+ entry->split = false;
return visit_continue;
}
@@ -173,12 +179,26 @@ ir_array_reference_visitor::visit_enter(ir_dereference_array *ir)
variable_entry *entry = this->get_variable_entry(deref->var);
+ /* If the access to the array has a variable index, we wouldn't
+ * know which split variable this dereference should go to.
+ */
if (entry && !ir->array_index->as_constant())
- entry->whole_array_access++;
+ entry->split = false;
return visit_continue_with_parent;
}
+ir_visitor_status
+ir_array_reference_visitor::visit_enter(ir_function_signature *ir)
+{
+ /* We don't have logic for array-splitting function arguments,
+ * so just look at the body instructions and not the parameter
+ * declarations.
+ */
+ visit_list_elements(this, &ir->body);
+ return visit_continue_with_parent;
+}
+
bool
ir_array_reference_visitor::get_split_list(exec_list *instructions,
bool linked)
@@ -204,12 +224,12 @@ ir_array_reference_visitor::get_split_list(exec_list *instructions,
variable_entry *entry = (variable_entry *)iter.get();
if (debug) {
- printf("array %s@%p: decl %d, whole_access %d\n",
+ printf("array %s@%p: decl %d, split %d\n",
entry->var->name, (void *) entry->var, entry->declaration,
- entry->whole_array_access);
+ entry->split);
}
- if (!entry->declaration || entry->whole_array_access) {
+ if (!(entry->declaration && entry->split)) {
entry->remove();
}
}
@@ -217,7 +237,10 @@ ir_array_reference_visitor::get_split_list(exec_list *instructions,
return !variable_list.is_empty();
}
-/** This is the class that does the actual work of splitting. */
+/**
+ * This class rewrites the dereferences of arrays that have been split
+ * to use the newly created ir_variables for each component.
+ */
class ir_array_splitting_visitor : public ir_rvalue_visitor {
public:
ir_array_splitting_visitor(exec_list *vars)
@@ -236,7 +259,6 @@ public:
variable_entry *get_splitting_entry(ir_variable *var);
exec_list *variable_list;
- void *mem_ctx;
};
variable_entry *
@@ -348,8 +370,7 @@ optimize_split_arrays(exec_list *instructions, bool linked)
const struct glsl_type *subtype;
if (type->is_matrix())
- subtype = glsl_type::get_instance(GLSL_TYPE_FLOAT,
- type->vector_elements, 1);
+ subtype = type->column_type();
else
subtype = type->fields.array;