diff options
author | Timothy Arceri <[email protected]> | 2015-10-15 14:32:41 +1100 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2015-10-15 20:35:45 +1100 |
commit | 3129359ed7461b90fe6ea70641ec7a858dd656de (patch) | |
tree | aee6cb5dcc219bd053324c205f156b7667ad9fae /src/glsl/ast_to_hir.cpp | |
parent | 296a7ea471fd327ab60d9723bd395e6b34dc9334 (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.cpp | 57 |
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 |