summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/glsl/ast_array_index.cpp10
-rw-r--r--src/glsl/ir.h37
-rw-r--r--src/glsl/ir_validate.cpp9
-rw-r--r--src/glsl/link_functions.cpp14
-rw-r--r--src/glsl/linker.cpp5
5 files changed, 53 insertions, 22 deletions
diff --git a/src/glsl/ast_array_index.cpp b/src/glsl/ast_array_index.cpp
index 5ca85f6ab3f..49a8574f2b8 100644
--- a/src/glsl/ast_array_index.cpp
+++ b/src/glsl/ast_array_index.cpp
@@ -88,8 +88,14 @@ update_max_array_access(ir_rvalue *ir, unsigned idx, YYLTYPE *loc,
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;
+
+ unsigned *const max_ifc_array_access =
+ deref_var->var->get_max_ifc_array_access();
+
+ assert(max_ifc_array_access != NULL);
+
+ if (idx > max_ifc_array_access[field_index]) {
+ 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.
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index d96f44029c9..6b953ee0563 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -527,6 +527,17 @@ public:
}
/**
+ * Get the max_ifc_array_access pointer
+ *
+ * A "set" function is not needed because the array is dynmically allocated
+ * as necessary.
+ */
+ inline unsigned *get_max_ifc_array_access()
+ {
+ return this->max_ifc_array_access;
+ }
+
+ /**
* Enable emitting extension warnings for this variable
*/
void enable_extension_warning(const char *extension);
@@ -548,19 +559,6 @@ public:
*/
const char *name;
- /**
- * For variables which satisfy the is_interface_instance() predicate, this
- * points to an array of integers such that if the ith member of the
- * interface block is an array, max_ifc_array_access[i] is the maximum
- * array element of that member that has been accessed. If the ith member
- * of the interface block is not an array, max_ifc_array_access[i] is
- * unused.
- *
- * For variables whose type is not an interface block, this pointer is
- * NULL.
- */
- unsigned *max_ifc_array_access;
-
struct ir_variable_data {
/**
@@ -823,6 +821,19 @@ private:
static const char *const warn_extension_table[];
/**
+ * For variables which satisfy the is_interface_instance() predicate, this
+ * points to an array of integers such that if the ith member of the
+ * interface block is an array, max_ifc_array_access[i] is the maximum
+ * array element of that member that has been accessed. If the ith member
+ * of the interface block is not an array, max_ifc_array_access[i] is
+ * unused.
+ *
+ * For variables whose type is not an interface block, this pointer is
+ * NULL.
+ */
+ unsigned *max_ifc_array_access;
+
+ /**
* For variables that are in an interface block or are an instance of an
* interface block, this is the \c GLSL_TYPE_INTERFACE type for that block.
*
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
index 5ed8abba0b4..96dd7bd9599 100644
--- a/src/glsl/ir_validate.cpp
+++ b/src/glsl/ir_validate.cpp
@@ -682,10 +682,15 @@ ir_validate::visit(ir_variable *ir)
ir->get_interface_type()->fields.structure;
for (unsigned i = 0; i < ir->get_interface_type()->length; i++) {
if (fields[i].type->array_size() > 0) {
- if (ir->max_ifc_array_access[i] >= fields[i].type->length) {
+ const unsigned *const max_ifc_array_access =
+ ir->get_max_ifc_array_access();
+
+ assert(max_ifc_array_access != NULL);
+
+ if (max_ifc_array_access[i] >= fields[i].type->length) {
printf("ir_variable has maximum access out of bounds for "
"field %s (%d vs %d)\n", fields[i].name,
- ir->max_ifc_array_access[i], fields[i].type->length);
+ max_ifc_array_access[i], fields[i].type->length);
ir->print();
abort();
}
diff --git a/src/glsl/link_functions.cpp b/src/glsl/link_functions.cpp
index d62c16853bc..537f4dc77ac 100644
--- a/src/glsl/link_functions.cpp
+++ b/src/glsl/link_functions.cpp
@@ -245,11 +245,19 @@ public:
/* Similarly, we need implicit sizes of arrays within interface
* blocks to be sized by the maximal access in *any* shader.
*/
+ unsigned *const linked_max_ifc_array_access =
+ var->get_max_ifc_array_access();
+ unsigned *const ir_max_ifc_array_access =
+ ir->var->get_max_ifc_array_access();
+
+ assert(linked_max_ifc_array_access != NULL);
+ assert(ir_max_ifc_array_access != NULL);
+
for (unsigned i = 0; i < var->get_interface_type()->length;
i++) {
- var->max_ifc_array_access[i] =
- MAX2(var->max_ifc_array_access[i],
- ir->var->max_ifc_array_access[i]);
+ linked_max_ifc_array_access[i] =
+ MAX2(linked_max_ifc_array_access[i],
+ ir_max_ifc_array_access[i]);
}
}
}
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 75e8b1696c5..2fece74d552 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1173,7 +1173,8 @@ public:
if (var->type->is_interface()) {
if (interface_contains_unsized_arrays(var->type)) {
const glsl_type *new_type =
- resize_interface_members(var->type, var->max_ifc_array_access);
+ resize_interface_members(var->type,
+ var->get_max_ifc_array_access());
var->type = new_type;
var->change_interface_type(new_type);
}
@@ -1182,7 +1183,7 @@ public:
if (interface_contains_unsized_arrays(var->type->fields.array)) {
const glsl_type *new_type =
resize_interface_members(var->type->fields.array,
- var->max_ifc_array_access);
+ var->get_max_ifc_array_access());
var->change_interface_type(new_type);
var->type =
glsl_type::get_array_instance(new_type, var->type->length);