diff options
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/ast.h | 26 | ||||
-rw-r--r-- | src/glsl/ast_function.cpp | 30 | ||||
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 4 | ||||
-rw-r--r-- | src/glsl/glsl_parser_extras.cpp | 13 |
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; |