summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/glsl/ast.h26
-rw-r--r--src/glsl/ast_function.cpp30
-rw-r--r--src/glsl/ast_to_hir.cpp4
-rw-r--r--src/glsl/glsl_parser_extras.cpp13
4 files changed, 72 insertions, 1 deletions
diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index 8abea5225f0..44e9f1874b5 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -189,7 +189,8 @@ enum ast_operators {
ast_float_constant,
ast_bool_constant,
- ast_sequence
+ ast_sequence,
+ ast_aggregate
};
/**
@@ -292,6 +293,29 @@ private:
bool cons;
};
+/**
+ * C-style aggregate initialization class
+ *
+ * Represents C-style initializers of vectors, matrices, arrays, and
+ * structures. E.g., vec3 pos = {1.0, 0.0, -1.0} is equivalent to
+ * vec3 pos = vec3(1.0, 0.0, -1.0).
+ *
+ * Specified in GLSL 4.20 and GL_ARB_shading_language_420pack.
+ *
+ * \sa _mesa_ast_set_aggregate_type
+ */
+class ast_aggregate_initializer : public ast_expression {
+public:
+ ast_aggregate_initializer()
+ : ast_expression(ast_aggregate, NULL, NULL, NULL)
+ {
+ /* empty */
+ }
+
+ ast_type_specifier *constructor_type;
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+};
/**
* Number of possible operators for an ast_expression
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
index 459a17a3dca..39182639f33 100644
--- a/src/glsl/ast_function.cpp
+++ b/src/glsl/ast_function.cpp
@@ -1699,3 +1699,33 @@ ast_function_expression::hir(exec_list *instructions,
return ir_rvalue::error_value(ctx);
}
+
+ir_rvalue *
+ast_aggregate_initializer::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+ YYLTYPE loc = this->get_location();
+ const char *name;
+ const glsl_type *const constructor_type =
+ this->constructor_type->glsl_type(&name, state);
+
+ if (!state->ARB_shading_language_420pack_enable) {
+ _mesa_glsl_error(&loc, state, "C-style initialization requires the "
+ "GL_ARB_shading_language_420pack extension");
+ return ir_rvalue::error_value(ctx);
+ }
+
+ if (this->constructor_type->is_array) {
+ return process_array_constructor(instructions, constructor_type, &loc,
+ &this->expressions, state);
+ }
+
+ if (this->constructor_type->structure) {
+ return process_record_constructor(instructions, constructor_type, &loc,
+ &this->expressions, state);
+ }
+
+ return process_vec_mat_constructor(instructions, constructor_type, &loc,
+ &this->expressions, state);
+}
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 611a85dd8e1..c316127ff89 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -1068,6 +1068,10 @@ ast_expression::hir(exec_list *instructions,
loc = this->get_location();
switch (this->oper) {
+ case ast_aggregate:
+ assert(!"ast_aggregate: Should never get here.");
+ break;
+
case ast_assign: {
op[0] = this->subexpressions[0]->hir(instructions, state);
op[1] = this->subexpressions[1]->hir(instructions, state);
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index aa5a435fa95..602ec08328b 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -862,6 +862,19 @@ ast_expression::print(void) const
break;
}
+ case ast_aggregate: {
+ printf("{ ");
+ foreach_list_const(n, & this->expressions) {
+ if (n != this->expressions.get_head())
+ printf(", ");
+
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
+ }
+ printf("} ");
+ break;
+ }
+
default:
assert(0);
break;