<div dir="ltr">On 21 January 2014 04:19, Timothy Arceri <span dir="ltr"><<a href="mailto:t_arceri@yahoo.com.au" target="_blank">t_arceri@yahoo.com.au</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Signed-off-by: Timothy Arceri <<a href="mailto:t_arceri@yahoo.com.au" target="_blank">t_arceri@yahoo.com.au</a>><br>
---<br>
src/glsl/ast.h | 19 +++++++++++-<br>
src/glsl/ast_function.cpp | 14 +++++++--<br>
src/glsl/ast_to_hir.cpp | 29 +++++++++++++-----<br>
src/glsl/glsl_parser.yy | 36 +++++++++++++++++++++-<br>
src/glsl/glsl_parser_extras.cpp | 68 +++++++++++++++++++++++++++++++----------<br>
5 files changed, 139 insertions(+), 27 deletions(-)<br></blockquote><div><br></div><div>I believe I've found an easier solution to this: please see "[PATCH] glsl: Simplify aggregate type inference to prepare for ARB_arrays_of_arrays.", which I believe makes this patch unnecessary.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
diff --git a/src/glsl/ast.h b/src/glsl/ast.h<br>
index 4dda32e..8bccca7 100644<br>
--- a/src/glsl/ast.h<br>
+++ b/src/glsl/ast.h<br>
@@ -308,10 +308,16 @@ public:<br>
: ast_expression(ast_aggregate, NULL, NULL, NULL),<br>
constructor_type(NULL)<br>
{<br>
- /* empty */<br>
+ array_dimension = 1;<br>
+ is_array = false;<br>
}<br>
<br>
ast_type_specifier *constructor_type;<br>
+ unsigned array_dimension;<br>
+<br>
+ ast_array_specifier *array_specifier;<br>
+ bool is_array;<br>
+<br>
virtual ir_rvalue *hir(exec_list *instructions,<br>
struct _mesa_glsl_parse_state *state);<br>
};<br>
@@ -588,6 +594,11 @@ public:<br>
struct _mesa_glsl_parse_state *state)<br>
const;<br>
<br>
+ const struct glsl_type *glsl_type(const char **name,<br>
+ struct _mesa_glsl_parse_state *state,<br>
+ bool skip_outer_dimension)<br>
+ const;<br>
+<br>
virtual void print(void) const;<br>
<br>
ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *);<br>
@@ -1005,4 +1016,10 @@ extern void<br>
check_builtin_array_max_size(const char *name, unsigned size,<br>
YYLTYPE loc, struct _mesa_glsl_parse_state *state);<br>
<br>
+extern const glsl_type *<br>
+process_array_type(YYLTYPE *loc, const glsl_type *base,<br>
+ ast_array_specifier *array_specifier,<br>
+ struct _mesa_glsl_parse_state *state,<br>
+ bool skip_first_dim);<br>
+<br>
#endif /* AST_H */<br>
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp<br>
index 2d05d07..3b38cb6 100644<br>
--- a/src/glsl/ast_function.cpp<br>
+++ b/src/glsl/ast_function.cpp<br>
@@ -1693,8 +1693,18 @@ ast_aggregate_initializer::hir(exec_list *instructions,<br>
_mesa_glsl_error(&loc, state, "type of C-style initializer unknown");<br>
return ir_rvalue::error_value(ctx);<br>
}<br>
- const glsl_type *const constructor_type =<br>
- this->constructor_type->glsl_type(&name, state);<br>
+ const glsl_type *constructor_type =<br>
+ this->constructor_type->glsl_type(&name, state,<br>
+ this->array_dimension > 1 && !this->is_array);<br>
+<br>
+ /* This only handles "vec4 foo[..]". The earlier constructor_type->glsl_type(...)<br>
+ * call already handled the "vec4[..] foo" case.<br>
+ */<br>
+ if (this->is_array) {<br>
+ constructor_type =<br>
+ process_array_type(&loc, constructor_type, this->array_specifier,<br>
+ state, this->array_dimension > 1);<br>
+ }<br>
<br>
if (!state->ARB_shading_language_420pack_enable) {<br>
_mesa_glsl_error(&loc, state, "C-style initialization requires the "<br>
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp<br>
index d02c9ff..226d128 100644<br>
--- a/src/glsl/ast_to_hir.cpp<br>
+++ b/src/glsl/ast_to_hir.cpp<br>
@@ -1817,10 +1817,11 @@ process_array_size(exec_node *node,<br>
return result;<br>
}<br>
<br>
-static const glsl_type *<br>
+const glsl_type *<br>
process_array_type(YYLTYPE *loc, const glsl_type *base,<br>
ast_array_specifier *array_specifier,<br>
- struct _mesa_glsl_parse_state *state)<br>
+ struct _mesa_glsl_parse_state *state,<br>
+ bool skip_first_dim)<br>
{<br>
const glsl_type *array_type = NULL;<br>
const glsl_type *element_type = base;<br>
@@ -1865,6 +1866,8 @@ process_array_type(YYLTYPE *loc, const glsl_type *base,<br>
<br>
unsigned array_size;<br>
for (/* nothing */; !node->is_head_sentinel(); node = node->prev) {<br>
+ if (skip_first_dim && node->prev->is_head_sentinel())<br>
+ break;<br>
array_size = process_array_size(node, state);<br>
array_type_temp = glsl_type::get_array_instance(array_type_temp,<br>
array_size);<br>
@@ -1891,6 +1894,14 @@ const glsl_type *<br>
ast_type_specifier::glsl_type(const char **name,<br>
struct _mesa_glsl_parse_state *state) const<br>
{<br>
+ return this->glsl_type(name, state, false);<br>
+}<br>
+<br>
+const glsl_type *<br>
+ast_type_specifier::glsl_type(const char **name,<br>
+ struct _mesa_glsl_parse_state *state,<br>
+ bool skip_outer_dim) const<br>
+{<br>
const struct glsl_type *type;<br>
<br>
type = state->symbols->get_type(this->type_name);<br>
@@ -1898,7 +1909,8 @@ ast_type_specifier::glsl_type(const char **name,<br>
<br>
if (this->is_array) {<br>
YYLTYPE loc = this->get_location();<br>
- type = process_array_type(&loc, type, this->array_specifier, state);<br>
+ type = process_array_type(&loc, type, this->array_specifier,<br>
+ state, skip_outer_dim);<br>
}<br>
<br>
return type;<br>
@@ -3016,7 +3028,7 @@ ast_declarator_list::hir(exec_list *instructions,<br>
<br>
if (decl->is_array) {<br>
var_type = process_array_type(&loc, decl_type, decl->array_specifier,<br>
- state);<br>
+ state, false);<br>
if (var_type->is_error())<br>
continue;<br>
} else {<br>
@@ -3579,7 +3591,8 @@ ast_parameter_declarator::hir(exec_list *instructions,<br>
* call already handled the "vec4[..] foo" case.<br>
*/<br>
if (this->is_array) {<br>
- type = process_array_type(&loc, type, this->array_specifier, state);<br>
+ type = process_array_type(&loc, type, this->array_specifier,<br>
+ state, false);<br>
}<br>
<br>
if (!type->is_error() && type->is_unsized_array()) {<br>
@@ -4710,7 +4723,8 @@ ast_process_structure_or_interface_block(exec_list *instructions,<br>
<br>
if (decl->is_array) {<br>
field_type = process_array_type(&loc, decl_type,<br>
- decl->array_specifier, state);<br>
+ decl->array_specifier,<br>
+ state, false);<br>
}<br>
fields[i].type = field_type;<br>
fields[i].name = decl->identifier;<br>
@@ -5076,7 +5090,8 @@ ast_interface_block::hir(exec_list *instructions,<br>
if (this->is_array) {<br>
<br>
const glsl_type *block_array_type =<br>
- process_array_type(&loc, block_type, this->array_specifier, state);<br>
+ process_array_type(&loc, block_type, this->array_specifier,<br>
+ state, false);<br>
<br>
/* Section 4.3.7 (Interface Blocks) of the GLSL 1.50 spec says:<br>
*<br>
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy<br>
index 6d63668..9461e73 100644<br>
--- a/src/glsl/glsl_parser.yy<br>
+++ b/src/glsl/glsl_parser.yy<br>
@@ -1007,6 +1007,23 @@ init_declarator_list:<br>
if ($6->oper == ast_aggregate) {<br>
ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$6;<br>
ast_type_specifier *type = new(ctx) ast_type_specifier($1->type->specifier, true, $4);<br>
+ if ($1->type->specifier->array_specifier != NULL) {<br>
+ ai->array_specifier = $4;<br>
+ ai->is_array = true;<br>
+<br>
+ type =<br>
+ new(ctx) ast_type_specifier($1->type->specifier,<br>
+ $1->type->specifier->is_array,<br>
+ $1->type->specifier->array_specifier);<br>
+ } else {<br>
+ ai->array_specifier = NULL;<br>
+ ai->is_array = false;<br>
+<br>
+ type =<br>
+ new(ctx) ast_type_specifier($1->type->specifier,<br>
+ true,<br>
+ $4);<br>
+ }<br>
_mesa_ast_set_aggregate_type(type, ai, state);<br>
}<br>
}<br>
@@ -1063,7 +1080,24 @@ single_declaration:<br>
$$->declarations.push_tail(&decl->link);<br>
if ($5->oper == ast_aggregate) {<br>
ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$5;<br>
- ast_type_specifier *type = new(ctx) ast_type_specifier($1->specifier, true, $3);<br>
+ ast_type_specifier *type;<br>
+ if ($1->specifier->array_specifier != NULL) {<br>
+ ai->array_specifier = $3;<br>
+ ai->is_array = true;<br>
+<br>
+ type =<br>
+ new(ctx) ast_type_specifier($1->specifier,<br>
+ $1->specifier->is_array,<br>
+ $1->specifier->array_specifier);<br>
+ } else {<br>
+ ai->array_specifier = NULL;<br>
+ ai->is_array = false;<br>
+<br>
+ type =<br>
+ new(ctx) ast_type_specifier($1->specifier,<br>
+ true,<br>
+ $3);<br>
+ }<br>
_mesa_ast_set_aggregate_type(type, ai, state);<br>
}<br>
}<br>
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp<br>
index 92076b5..43a23cc 100644<br>
--- a/src/glsl/glsl_parser_extras.cpp<br>
+++ b/src/glsl/glsl_parser_extras.cpp<br>
@@ -720,16 +720,26 @@ _mesa_ast_set_aggregate_type(const ast_type_specifier *type,<br>
<br>
/* If the aggregate is an array, recursively set its elements' types. */<br>
if (type->is_array) {<br>
- /* We want to set the element type which is not an array itself, so make<br>
- * a copy of the array type and set its is_array field to false.<br>
- *<br>
- * E.g., if <type> if struct S[2] we want to set each element's type to<br>
- * struct S.<br>
- *<br>
- * FINISHME: Update when ARB_array_of_arrays is supported.<br>
- */<br>
- const ast_type_specifier *non_array_type =<br>
- new(ctx) ast_type_specifier(type, false, NULL);<br>
+<br>
+ const ast_type_specifier *element_type;<br>
+ unsigned dimension_count = type->array_specifier->dimension_count;<br>
+<br>
+ if (ai->is_array)<br>
+ dimension_count += ai->array_specifier->dimension_count;<br>
+<br>
+ if (dimension_count == ai->array_dimension ||<br>
+ !state->ARB_arrays_of_arrays_enable) {<br>
+<br>
+ /* We want to set the element type which is not an array itself, so make<br>
+ * a copy of the array type and set its is_array field to false.<br>
+ *<br>
+ * E.g., if <type> if struct S[2] we want to set each element's type to<br>
+ * struct S.<br>
+ */<br>
+ element_type = new(ctx) ast_type_specifier(type, false, NULL);<br>
+ } else {<br>
+ element_type = type;<br>
+ }<br>
<br>
for (exec_node *expr_node = ai->expressions.head;<br>
!expr_node->is_tail_sentinel();<br>
@@ -737,8 +747,23 @@ _mesa_ast_set_aggregate_type(const ast_type_specifier *type,<br>
ast_expression *expr = exec_node_data(ast_expression, expr_node,<br>
link);<br>
<br>
- if (expr->oper == ast_aggregate)<br>
- _mesa_ast_set_aggregate_type(non_array_type, expr, state);<br>
+ if (expr->oper == ast_aggregate) {<br>
+ /* copy some values needed to process initialization of<br>
+ * arrays of arrays e.g<br>
+ * vec4[2] a[2] = {<br>
+ * { vec4(1.0), vec4(1.0) },<br>
+ * { vec4(1.0), vec4(1.0) }};<br>
+ */<br>
+ ast_aggregate_initializer *sub_ai = (ast_aggregate_initializer *)expr;<br>
+ if (ai->array_dimension != dimension_count) {<br>
+ sub_ai->array_dimension = ai->array_dimension + 1;<br>
+ if (ai->is_array) {<br>
+ sub_ai->is_array = ai->is_array;<br>
+ sub_ai->array_specifier = ai->array_specifier;<br>
+ }<br>
+ }<br>
+ _mesa_ast_set_aggregate_type(element_type, (ast_expression *)sub_ai, state);<br>
+ }<br>
}<br>
<br>
/* If the aggregate is a struct, recursively set its fields' types. */<br>
@@ -770,6 +795,7 @@ _mesa_ast_set_aggregate_type(const ast_type_specifier *type,<br>
link);<br>
<br>
bool is_array = decl_list->type->specifier->is_array;<br>
+ bool set_aggr_array = false;<br>
ast_array_specifier *array_specifier = decl_list->type->specifier->array_specifier;<br>
<br>
/* Recognize variable declarations with the bracketed size attached<br>
@@ -778,12 +804,16 @@ _mesa_ast_set_aggregate_type(const ast_type_specifier *type,<br>
* float a[2];<br>
* float[2] b;<br>
*<br>
- * are both arrays, but <a>'s array_specifier is decl->array_specifier, while<br>
- * <b>'s array_specifier is decl_list->type->specifier->array_specifier.<br>
+ * are both arrays, but <a>'s array_specifier is<br>
+ * decl->array_specifier, while <b>'s array_specifier is<br>
+ * decl_list->type->specifier->array_specifier.<br>
*/<br>
if (!is_array) {<br>
is_array = decl->is_array;<br>
array_specifier = decl->array_specifier;<br>
+ } else if (decl_list->type->specifier->is_array &&<br>
+ state->ARB_arrays_of_arrays_enable) {<br>
+ set_aggr_array = true;<br>
}<br>
<br>
/* Declaration shadows the <type> parameter. */<br>
@@ -791,8 +821,14 @@ _mesa_ast_set_aggregate_type(const ast_type_specifier *type,<br>
new(ctx) ast_type_specifier(decl_list->type->specifier,<br>
is_array, array_specifier);<br>
<br>
- if (expr->oper == ast_aggregate)<br>
- _mesa_ast_set_aggregate_type(type, expr, state);<br>
+ if (expr->oper == ast_aggregate) {<br>
+ ast_aggregate_initializer *sub_ai = (ast_aggregate_initializer *)expr;<br>
+ if (set_aggr_array) {<br>
+ sub_ai->is_array = decl->is_array;<br>
+ sub_ai->array_specifier = decl->array_specifier;<br>
+ }<br>
+ _mesa_ast_set_aggregate_type(type, (ast_expression *)sub_ai, state);<br>
+ }<br>
}<br>
}<br>
} else {<br>
<span><font color="#888888">--<br>
1.8.3.1<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>