glsl: Add infrastructure for aggregate initializers.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
Matt Turner 2013-06-29 19:27:50 -07:00
parent 8d45caaeba
commit ae79e86d4c
4 changed files with 72 additions and 1 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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;