[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