glsl: Add infrastructure for aggregate initializers.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
parent
8d45caaeba
commit
ae79e86d4c
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue