[Mesa-dev] [PATCH 6/6] glsl: Allow instructions to be generated for array size declarations.
Eric Anholt
eric at anholt.net
Sat Apr 9 22:17:20 PDT 2011
The specs only say that they have to be a constant expression, which
would allow things like builtin function calls that generate
instructions as a side effect of their parsing.
Fixes the fixed array-size-constant-relational.vert.
---
src/glsl/ast.h | 2 +-
src/glsl/ast_function.cpp | 3 ++-
src/glsl/ast_to_hir.cpp | 34 ++++++++++++++++++----------------
3 files changed, 21 insertions(+), 18 deletions(-)
diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index 878f48b..b3f8f73 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -485,7 +485,7 @@ public:
/* empty */
}
- const struct glsl_type *glsl_type(const char **name,
+ const struct glsl_type *glsl_type(exec_list *instructions, const char **name,
struct _mesa_glsl_parse_state *state)
const;
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
index e5cb873..2b13859 100644
--- a/src/glsl/ast_function.cpp
+++ b/src/glsl/ast_function.cpp
@@ -1015,7 +1015,8 @@ ast_function_expression::hir(exec_list *instructions,
YYLTYPE loc = type->get_location();
const char *name;
- const glsl_type *const constructor_type = type->glsl_type(& name, state);
+ const glsl_type *const constructor_type = type->glsl_type(instructions,
+ &name, state);
/* constructor_type can be NULL if a variable with the same name as the
* structure has come into scope.
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index b4fa02c..4494522 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -1725,7 +1725,8 @@ ast_compound_statement::hir(exec_list *instructions,
static const glsl_type *
-process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
+process_array_type(exec_list *instructions,
+ YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
struct _mesa_glsl_parse_state *state)
{
unsigned length = 0;
@@ -1734,14 +1735,9 @@ process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
if (array_size != NULL) {
exec_list dummy_instructions;
- ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
+ ir_rvalue *const ir = array_size->hir(instructions, state);
YYLTYPE loc = array_size->get_location();
- /* FINISHME: Verify that the grammar forbids side-effects in array
- * FINISHME: sizes. i.e., 'vec4 [x = 12] data'
- */
- assert(dummy_instructions.is_empty());
-
if (ir != NULL) {
if (!ir->type->is_integer()) {
_mesa_glsl_error(& loc, state, "array size must be integer type");
@@ -1774,7 +1770,7 @@ process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
const glsl_type *
-ast_type_specifier::glsl_type(const char **name,
+ast_type_specifier::glsl_type(exec_list *instructions, const char **name,
struct _mesa_glsl_parse_state *state) const
{
const struct glsl_type *type;
@@ -1784,7 +1780,8 @@ ast_type_specifier::glsl_type(const char **name,
if (this->is_array) {
YYLTYPE loc = this->get_location();
- type = process_array_type(&loc, type, this->array_size, state);
+ type = process_array_type(instructions, &loc,
+ type, this->array_size, state);
}
return type;
@@ -2369,7 +2366,8 @@ ast_declarator_list::hir(exec_list *instructions,
*/
(void) this->type->specifier->hir(instructions, state);
- decl_type = this->type->specifier->glsl_type(& type_name, state);
+ decl_type = this->type->specifier->glsl_type(instructions,
+ &type_name, state);
if (this->declarations.is_empty()) {
/* The only valid case where the declaration list can be empty is when
* the declaration is setting the default precision of a built-in type
@@ -2404,7 +2402,8 @@ ast_declarator_list::hir(exec_list *instructions,
}
if (decl->is_array) {
- var_type = process_array_type(&loc, decl_type, decl->array_size,
+ var_type = process_array_type(instructions,
+ &loc, decl_type, decl->array_size,
state);
} else {
var_type = decl_type;
@@ -2775,7 +2774,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
const char *name = NULL;
YYLTYPE loc = this->get_location();
- type = this->type->specifier->glsl_type(& name, state);
+ type = this->type->specifier->glsl_type(instructions, &name, state);
if (type == NULL) {
if (name != NULL) {
@@ -2821,7 +2820,8 @@ ast_parameter_declarator::hir(exec_list *instructions,
* call already handled the "vec4[..] foo" case.
*/
if (this->is_array) {
- type = process_array_type(&loc, type, this->array_size, state);
+ type = process_array_type(instructions, &loc,
+ type, this->array_size, state);
}
if (type->array_size() == 0) {
@@ -2947,7 +2947,8 @@ ast_function::hir(exec_list *instructions,
const char *return_type_name;
const glsl_type *return_type =
- this->return_type->specifier->glsl_type(& return_type_name, state);
+ this->return_type->specifier->glsl_type(instructions,
+ &return_type_name, state);
if (!return_type) {
YYLTYPE loc = this->get_location();
@@ -3449,14 +3450,15 @@ ast_struct_specifier::hir(exec_list *instructions,
}
const glsl_type *decl_type =
- decl_list->type->specifier->glsl_type(& type_name, state);
+ decl_list->type->specifier->glsl_type(instructions, &type_name, state);
foreach_list_typed (ast_declaration, decl, link,
&decl_list->declarations) {
const struct glsl_type *field_type = decl_type;
if (decl->is_array) {
YYLTYPE loc = decl->get_location();
- field_type = process_array_type(&loc, decl_type, decl->array_size,
+ field_type = process_array_type(instructions,
+ &loc, decl_type, decl->array_size,
state);
}
fields[i].type = (field_type != NULL)
--
1.7.4.1
More information about the mesa-dev
mailing list