summaryrefslogtreecommitdiffstats
path: root/src/glsl/ast_to_hir.cpp
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2015-10-15 14:32:41 +1100
committerTimothy Arceri <[email protected]>2015-10-15 20:35:45 +1100
commit3129359ed7461b90fe6ea70641ec7a858dd656de (patch)
treeaee6cb5dcc219bd053324c205f156b7667ad9fae /src/glsl/ast_to_hir.cpp
parent296a7ea471fd327ab60d9723bd395e6b34dc9334 (diff)
glsl: allow AoA to be sized by initializer or constructor
V2: Split out unsized array validation to its own patch as suggested by Samuel. Reviewed-by: Samuel Iglesias Gonsálvez <[email protected]>
Diffstat (limited to 'src/glsl/ast_to_hir.cpp')
-rw-r--r--src/glsl/ast_to_hir.cpp57
1 files changed, 40 insertions, 17 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index c04db3505c1..fb2c0f7026c 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -782,8 +782,30 @@ validate_assignment(struct _mesa_glsl_parse_state *state,
* Note: Whole-array assignments are not permitted in GLSL 1.10, but this
* is handled by ir_dereference::is_lvalue.
*/
- if (lhs->type->is_unsized_array() && rhs->type->is_array()
- && (lhs->type->fields.array == rhs->type->fields.array)) {
+ const glsl_type *lhs_t = lhs->type;
+ const glsl_type *rhs_t = rhs->type;
+ bool unsized_array = false;
+ while(lhs_t->is_array()) {
+ if (rhs_t == lhs_t)
+ break; /* the rest of the inner arrays match so break out early */
+ if (!rhs_t->is_array()) {
+ unsized_array = false;
+ break; /* number of dimensions mismatch */
+ }
+ if (lhs_t->length == rhs_t->length) {
+ lhs_t = lhs_t->fields.array;
+ rhs_t = rhs_t->fields.array;
+ continue;
+ } else if (lhs_t->is_unsized_array()) {
+ unsized_array = true;
+ } else {
+ unsized_array = false;
+ break; /* sized array mismatch */
+ }
+ lhs_t = lhs_t->fields.array;
+ rhs_t = rhs_t->fields.array;
+ }
+ if (unsized_array) {
if (is_initializer) {
return rhs;
} else {
@@ -1810,6 +1832,10 @@ ast_expression::do_hir(exec_list *instructions,
break;
}
+ case ast_unsized_array_dim:
+ assert(!"ast_unsized_array_dim: Should never get here.");
+ break;
+
case ast_function_call:
/* Should *NEVER* get here. ast_function_call should always be handled
* by ast_function_expression::hir.
@@ -2047,6 +2073,14 @@ process_array_size(exec_node *node,
exec_list dummy_instructions;
ast_node *array_size = exec_node_data(ast_node, node, link);
+
+ /**
+ * Dimensions other than the outermost dimension can by unsized if they
+ * are immediately sized by a constructor or initializer.
+ */
+ if (((ast_expression*)array_size)->oper == ast_unsized_array_dim)
+ return 0;
+
ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
YYLTYPE loc = array_size->get_location();
@@ -2115,14 +2149,6 @@ process_array_type(YYLTYPE *loc, const glsl_type *base,
base->name);
return glsl_type::error_type;
}
-
- if (base->length == 0) {
- _mesa_glsl_error(loc, state,
- "only the outermost array dimension can "
- "be unsized",
- base->name);
- return glsl_type::error_type;
- }
}
for (exec_node *node = array_specifier->array_dimensions.tail_pred;
@@ -2130,9 +2156,6 @@ process_array_type(YYLTYPE *loc, const glsl_type *base,
unsigned array_size = process_array_size(node, state);
array_type = glsl_type::get_array_instance(array_type, array_size);
}
-
- if (array_specifier->is_unsized_array)
- array_type = glsl_type::get_array_instance(array_type, 0);
}
return array_type;
@@ -6453,6 +6476,9 @@ ast_interface_block::hir(exec_list *instructions,
ir_variable *var;
if (this->array_specifier != NULL) {
+ const glsl_type *block_array_type =
+ process_array_type(&loc, block_type, this->array_specifier, state);
+
/* Section 4.3.7 (Interface Blocks) of the GLSL 1.50 spec says:
*
* For uniform blocks declared an array, each individual array
@@ -6476,7 +6502,7 @@ ast_interface_block::hir(exec_list *instructions,
* tessellation control shader output, and tessellation evaluation
* shader input.
*/
- if (this->array_specifier->is_unsized_array) {
+ if (block_array_type->is_unsized_array()) {
bool allow_inputs = state->stage == MESA_SHADER_GEOMETRY ||
state->stage == MESA_SHADER_TESS_CTRL ||
state->stage == MESA_SHADER_TESS_EVAL;
@@ -6503,9 +6529,6 @@ ast_interface_block::hir(exec_list *instructions,
}
}
- const glsl_type *block_array_type =
- process_array_type(&loc, block_type, this->array_specifier, state);
-
/* From section 4.3.9 (Interface Blocks) of the GLSL ES 3.10 spec:
*
* * Arrays of arrays of blocks are not allowed