Signed-off-by: Timothy Arceri <t_arc...@yahoo.com.au> --- src/glsl/ast.h | 19 +++++++++++- src/glsl/ast_function.cpp | 15 +++++++-- src/glsl/ast_to_hir.cpp | 31 +++++++++++++++--- src/glsl/glsl_parser.yy | 36 ++++++++++++++++++++- src/glsl/glsl_parser_extras.cpp | 69 +++++++++++++++++++++++++++++++---------- 5 files changed, 144 insertions(+), 26 deletions(-)
diff --git a/src/glsl/ast.h b/src/glsl/ast.h index bbae9cd..3ec8b75 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -308,10 +308,16 @@ public: : ast_expression(ast_aggregate, NULL, NULL, NULL), constructor_type(NULL) { - /* empty */ + array_dimension = 1; + is_array = false; } ast_type_specifier *constructor_type; + unsigned array_dimension; + + ast_array_specifier *array_specifier; + bool is_array; + virtual ir_rvalue *hir(exec_list *instructions, struct _mesa_glsl_parse_state *state); }; @@ -587,6 +593,11 @@ public: struct _mesa_glsl_parse_state *state) const; + const struct glsl_type *glsl_type(const char **name, + struct _mesa_glsl_parse_state *state, + bool skip_outer_dimension) + const; + virtual void print(void) const; ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *); @@ -1004,4 +1015,10 @@ extern void check_builtin_array_max_size(const char *name, unsigned size, YYLTYPE loc, struct _mesa_glsl_parse_state *state); +extern const glsl_type * +process_array_type_skip_dim(YYLTYPE *loc, const glsl_type *base, + ast_array_specifier *array_specifier, + struct _mesa_glsl_parse_state *state, + bool skip_first_dim); + #endif /* AST_H */ diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 57aa45f..f60cd19 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -1731,8 +1731,19 @@ ast_aggregate_initializer::hir(exec_list *instructions, _mesa_glsl_error(&loc, state, "type of C-style initializer unknown"); return ir_rvalue::error_value(ctx); } - const glsl_type *const constructor_type = - this->constructor_type->glsl_type(&name, state); + const glsl_type *constructor_type = + this->constructor_type->glsl_type(&name, state, + this->array_dimension > 1 && !this->is_array); + + /* This only handles "vec4 foo[..]". The earlier constructor_type->glsl_type(...) + * call already handled the "vec4[..] foo" case. + */ + if (this->is_array) { + constructor_type = + process_array_type_skip_dim(&loc, constructor_type, + this->array_specifier, state, + this->array_dimension > 1); + } if (!state->ARB_shading_language_420pack_enable) { _mesa_glsl_error(&loc, state, "C-style initialization requires the " diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 359a0b8..3054b9c 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1817,10 +1817,11 @@ process_array_size(exec_node *node, return result; } -static const glsl_type * -process_array_type(YYLTYPE *loc, const glsl_type *base, - ast_array_specifier *array_specifier, - struct _mesa_glsl_parse_state *state) +const glsl_type * +process_array_type_skip_dim(YYLTYPE *loc, const glsl_type *base, + ast_array_specifier *array_specifier, + struct _mesa_glsl_parse_state *state, + bool skip_first_dim) { const glsl_type *array_type = NULL; const glsl_type *element_type = base; @@ -1871,6 +1872,8 @@ process_array_type(YYLTYPE *loc, const glsl_type *base, unsigned array_size; for (/* nothing */; !node->is_head_sentinel(); node = node->prev) { + if (skip_first_dim && node->prev->is_head_sentinel()) + break; array_size = process_array_size(node, state); array_type_temp = glsl_type::get_array_instance(array_type_temp, array_size, @@ -1898,10 +1901,27 @@ process_array_type(YYLTYPE *loc, const glsl_type *base, return array_type != NULL ? array_type : glsl_type::error_type; } +static const glsl_type * +process_array_type(YYLTYPE *loc, const glsl_type *base, + ast_array_specifier *array_specifier, + struct _mesa_glsl_parse_state *state) +{ + return process_array_type_skip_dim(loc, base, array_specifier, + state, false); +} + const glsl_type * ast_type_specifier::glsl_type(const char **name, struct _mesa_glsl_parse_state *state) const { + return this->glsl_type(name, state, false); +} + +const glsl_type * +ast_type_specifier::glsl_type(const char **name, + struct _mesa_glsl_parse_state *state, + bool skip_outer_dim) const +{ const struct glsl_type *type; type = state->symbols->get_type(this->type_name); @@ -1909,7 +1929,8 @@ ast_type_specifier::glsl_type(const char **name, if (this->is_array) { YYLTYPE loc = this->get_location(); - type = process_array_type(&loc, type, this->array_specifier, state); + type = process_array_type_skip_dim(&loc, type, this->array_specifier, + state, skip_outer_dim); } return type; diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy index 6d63668..9461e73 100644 --- a/src/glsl/glsl_parser.yy +++ b/src/glsl/glsl_parser.yy @@ -1007,6 +1007,23 @@ init_declarator_list: if ($6->oper == ast_aggregate) { ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$6; ast_type_specifier *type = new(ctx) ast_type_specifier($1->type->specifier, true, $4); + if ($1->type->specifier->array_specifier != NULL) { + ai->array_specifier = $4; + ai->is_array = true; + + type = + new(ctx) ast_type_specifier($1->type->specifier, + $1->type->specifier->is_array, + $1->type->specifier->array_specifier); + } else { + ai->array_specifier = NULL; + ai->is_array = false; + + type = + new(ctx) ast_type_specifier($1->type->specifier, + true, + $4); + } _mesa_ast_set_aggregate_type(type, ai, state); } } @@ -1063,7 +1080,24 @@ single_declaration: $$->declarations.push_tail(&decl->link); if ($5->oper == ast_aggregate) { ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$5; - ast_type_specifier *type = new(ctx) ast_type_specifier($1->specifier, true, $3); + ast_type_specifier *type; + if ($1->specifier->array_specifier != NULL) { + ai->array_specifier = $3; + ai->is_array = true; + + type = + new(ctx) ast_type_specifier($1->specifier, + $1->specifier->is_array, + $1->specifier->array_specifier); + } else { + ai->array_specifier = NULL; + ai->is_array = false; + + type = + new(ctx) ast_type_specifier($1->specifier, + true, + $3); + } _mesa_ast_set_aggregate_type(type, ai, state); } } diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index 92076b5..0ea8f62 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -720,16 +720,26 @@ _mesa_ast_set_aggregate_type(const ast_type_specifier *type, /* If the aggregate is an array, recursively set its elements' types. */ if (type->is_array) { - /* We want to set the element type which is not an array itself, so make - * a copy of the array type and set its is_array field to false. - * - * E.g., if <type> if struct S[2] we want to set each element's type to - * struct S. - * - * FINISHME: Update when ARB_array_of_arrays is supported. - */ - const ast_type_specifier *non_array_type = - new(ctx) ast_type_specifier(type, false, NULL); + + const ast_type_specifier *element_type; + unsigned dimension_count = type->array_specifier->dimension_count; + + if (ai->is_array) + dimension_count += ai->array_specifier->dimension_count; + + if (dimension_count == ai->array_dimension || + !state->ARB_arrays_of_arrays_enable) { + + /* We want to set the element type which is not an array itself, so make + * a copy of the array type and set its is_array field to false. + * + * E.g., if <type> if struct S[2] we want to set each element's type to + * struct S. + */ + element_type = new(ctx) ast_type_specifier(type, false, NULL); + } else { + element_type = type; + } for (exec_node *expr_node = ai->expressions.head; !expr_node->is_tail_sentinel(); @@ -737,8 +747,23 @@ _mesa_ast_set_aggregate_type(const ast_type_specifier *type, ast_expression *expr = exec_node_data(ast_expression, expr_node, link); - if (expr->oper == ast_aggregate) - _mesa_ast_set_aggregate_type(non_array_type, expr, state); + if (expr->oper == ast_aggregate) { + /* copy some values needed to process initialization of + * arrays of arrays e.g + * vec4[2] a[2] = { + * { vec4(1.0), vec4(1.0) }, + * { vec4(1.0), vec4(1.0) }}; + */ + ast_aggregate_initializer *sub_ai = (ast_aggregate_initializer *)expr; + if (ai->array_dimension != dimension_count) { + sub_ai->array_dimension = ai->array_dimension + 1; + if (ai->is_array) { + sub_ai->is_array = ai->is_array; + sub_ai->array_specifier = ai->array_specifier; + } + } + _mesa_ast_set_aggregate_type(element_type, (ast_expression *)sub_ai, state); + } } /* If the aggregate is a struct, recursively set its fields' types. */ @@ -770,6 +795,7 @@ _mesa_ast_set_aggregate_type(const ast_type_specifier *type, link); bool is_array = decl_list->type->specifier->is_array; + bool set_aggr_array = false; ast_array_specifier *array_specifier = decl_list->type->specifier->array_specifier; /* Recognize variable declarations with the bracketed size attached @@ -778,12 +804,16 @@ _mesa_ast_set_aggregate_type(const ast_type_specifier *type, * float a[2]; * float[2] b; * - * are both arrays, but <a>'s array_specifier is decl->array_specifier, while - * <b>'s array_specifier is decl_list->type->specifier->array_specifier. + * are both arrays, but <a>'s array_specifier is + * decl->array_specifier, while <b>'s array_specifier is + * decl_list->type->specifier->array_specifier. */ if (!is_array) { is_array = decl->is_array; array_specifier = decl->array_specifier; + } else if (decl_list->type->specifier->is_array && + state->ARB_arrays_of_arrays_enable) { + set_aggr_array = true; } /* Declaration shadows the <type> parameter. */ @@ -791,8 +821,14 @@ _mesa_ast_set_aggregate_type(const ast_type_specifier *type, new(ctx) ast_type_specifier(decl_list->type->specifier, is_array, array_specifier); - if (expr->oper == ast_aggregate) - _mesa_ast_set_aggregate_type(type, expr, state); + if (expr->oper == ast_aggregate) { + ast_aggregate_initializer *sub_ai = (ast_aggregate_initializer *)expr; + if (set_aggr_array) { + sub_ai->is_array = decl->is_array; + sub_ai->array_specifier = decl->array_specifier; + } + _mesa_ast_set_aggregate_type(type, (ast_expression *)sub_ai, state); + } } } } else { @@ -819,7 +855,6 @@ _mesa_ast_set_aggregate_type(const ast_type_specifier *type, } } - void _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q) { -- 1.8.3.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev