summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2013-09-19 09:36:41 -0700
committerPaul Berry <[email protected]>2013-10-09 16:49:38 -0700
commitf878d2060c196c8130af0912ffc4493c631b1c34 (patch)
treeee3fa5b545d46cbe487838e99929ae25741e88b6
parentca8a5ce9193b21b2e567f6dfc877412109d106ca (diff)
glsl: Update ir_variable::max_ifc_array_access properly.
This patch modifies update_max_array_access() so that it updates ir_variable::max_ifc_array_access to reflect the shader's use of arrays appearing within interface blocks. v2: Use an ordinary function in ast_array_index.cpp rather than a virtual function in ir_rvalue. Avoid dereferencing NULL when handling accesses to ordinary structs. Reviewed-by: Jordan Justen <[email protected]>
-rw-r--r--src/glsl/ast_array_index.cpp37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/glsl/ast_array_index.cpp b/src/glsl/ast_array_index.cpp
index 75f3755d9bf..da96cc10ea9 100644
--- a/src/glsl/ast_array_index.cpp
+++ b/src/glsl/ast_array_index.cpp
@@ -49,6 +49,43 @@ update_max_array_access(ir_rvalue *ir, unsigned idx, YYLTYPE *loc,
*/
check_builtin_array_max_size(var->name, idx+1, *loc, state);
}
+ } else if (ir_dereference_record *deref_record =
+ ir->as_dereference_record()) {
+ /* There are two possibilities we need to consider:
+ *
+ * - Accessing an element of an array that is a member of a named
+ * interface block (e.g. ifc.foo[i])
+ *
+ * - Accessing an element of an array that is a member of a named
+ * interface block array (e.g. ifc[j].foo[i]).
+ */
+ ir_dereference_variable *deref_var =
+ deref_record->record->as_dereference_variable();
+ if (deref_var == NULL) {
+ if (ir_dereference_array *deref_array =
+ deref_record->record->as_dereference_array()) {
+ deref_var = deref_array->array->as_dereference_variable();
+ }
+ }
+
+ if (deref_var != NULL) {
+ const glsl_type *interface_type =
+ deref_var->var->get_interface_type();
+ if (interface_type != NULL) {
+ unsigned field_index =
+ deref_record->record->type->field_index(deref_record->field);
+ assert(field_index < interface_type->length);
+ if (idx > deref_var->var->max_ifc_array_access[field_index]) {
+ deref_var->var->max_ifc_array_access[field_index] = idx;
+
+ /* Check whether this access will, as a side effect, implicitly
+ * cause the size of a built-in array to be too large.
+ */
+ check_builtin_array_max_size(deref_record->field, idx+1, *loc,
+ state);
+ }
+ }
+ }
}
}