Mesa (7.9): glsl: Add support for default precision statements

Ian Romanick idr at kemper.freedesktop.org
Sat Feb 5 00:14:05 UTC 2011


Module: Mesa
Branch: 7.9
Commit: f5819379ed26abd1832f15b76609741178e90c64
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f5819379ed26abd1832f15b76609741178e90c64

Author: Chad Versace <chad.versace at intel.com>
Date:   Sun Jan 16 21:44:57 2011 -0800

glsl: Add support for default precision statements

* Add new field ast_type_specifier::is_precision_statement.
* Add semantic checks in ast_type_specifier::hir().
* Alter parser rules accordingly.
(cherry picked from commit 08a286c9cc8fecb081057e0f551c88a446c47b6f)

---

 src/glsl/ast.h           |    8 +++++-
 src/glsl/ast_to_hir.cpp  |   52 ++++++++++++++++++++++++++++++++++++++++++++++
 src/glsl/ast_type.cpp    |    3 +-
 src/glsl/glsl_parser.ypp |   13 ++++++-----
 4 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index 8ec1769..1d99e9a 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -422,7 +422,8 @@ public:
    /** Construct a type specifier from a type name */
    ast_type_specifier(const char *name) 
       : type_specifier(ast_type_name), type_name(name), structure(NULL),
-	is_array(false), array_size(NULL), precision(ast_precision_none)
+	is_array(false), array_size(NULL), precision(ast_precision_none),
+	is_precision_statement(false)
    {
       /* empty */
    }
@@ -430,7 +431,8 @@ public:
    /** Construct a type specifier from a structure definition */
    ast_type_specifier(ast_struct_specifier *s)
       : type_specifier(ast_struct), type_name(s->name), structure(s),
-	is_array(false), array_size(NULL), precision(ast_precision_none)
+	is_array(false), array_size(NULL), precision(ast_precision_none),
+	is_precision_statement(false)
    {
       /* empty */
    }
@@ -452,6 +454,8 @@ public:
    ast_expression *array_size;
 
    unsigned precision:2;
+
+   bool is_precision_statement;
 };
 
 
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index f761d1d..6118d1b 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2854,6 +2854,58 @@ ir_rvalue *
 ast_type_specifier::hir(exec_list *instructions,
 			  struct _mesa_glsl_parse_state *state)
 {
+   if (!this->is_precision_statement && this->structure == NULL)
+      return NULL;
+
+   YYLTYPE loc = this->get_location();
+
+   if (this->precision != ast_precision_none
+       && state->language_version != 100
+       && state->language_version < 130) {
+      _mesa_glsl_error(&loc, state,
+                       "precision qualifiers exist only in "
+                       "GLSL ES 1.00, and GLSL 1.30 and later");
+      return NULL;
+   }
+   if (this->precision != ast_precision_none
+       && this->structure != NULL) {
+      _mesa_glsl_error(&loc, state,
+                       "precision qualifiers do not apply to structures");
+      return NULL;
+   }
+
+   /* If this is a precision statement, check that the type to which it is
+    * applied is either float or int.
+    *
+    * From section 4.5.3 of the GLSL 1.30 spec:
+    *    "The precision statement
+    *       precision precision-qualifier type;
+    *    can be used to establish a default precision qualifier. The type
+    *    field can be either int or float [...].  Any other types or
+    *    qualifiers will result in an error.
+    */
+   if (this->is_precision_statement) {
+      assert(this->precision != ast_precision_none);
+      assert(this->structure == NULL); /* The check for structures was
+                                        * performed above. */
+      if (this->is_array) {
+         _mesa_glsl_error(&loc, state,
+                          "default precision statements do not apply to "
+                          "arrays");
+         return NULL;
+      }
+      if (this->type_specifier != ast_float
+          && this->type_specifier != ast_int) {
+         _mesa_glsl_error(&loc, state,
+                          "default precision statements apply only to types "
+                          "float and int");
+         return NULL;
+      }
+
+      /* FINISHME: Translate precision statements into IR. */
+      return NULL;
+   }
+
    if (this->structure != NULL)
       return this->structure->hir(instructions, state);
 
diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp
index a191baf..583f24b 100644
--- a/src/glsl/ast_type.cpp
+++ b/src/glsl/ast_type.cpp
@@ -49,7 +49,8 @@ ast_type_specifier::print(void) const
 
 ast_type_specifier::ast_type_specifier(int specifier)
       : type_specifier(ast_types(specifier)), type_name(NULL), structure(NULL),
-	is_array(false), array_size(NULL), precision(ast_precision_none)
+	is_array(false), array_size(NULL), precision(ast_precision_none),
+	is_precision_statement(false)
 {
    static const char *const names[] = {
       "void",
diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp
index 99f3851..ac4cdb6 100644
--- a/src/glsl/glsl_parser.ypp
+++ b/src/glsl/glsl_parser.ypp
@@ -278,16 +278,16 @@ extension_statement:
 external_declaration_list:
 	external_declaration
 	{
-	   /* FINISHME: The NULL test is only required because 'precision'
-	    * FINISHME: statements are not yet supported.
+	   /* FINISHME: The NULL test is required because pragmas are set to
+	    * FINISHME: NULL. (See production rule for external_declaration.)
 	    */
 	   if ($1 != NULL)
 	      state->translation_unit.push_tail(& $1->link);
 	}
 	| external_declaration_list external_declaration
 	{
-	   /* FINISHME: The NULL test is only required because 'precision'
-	    * FINISHME: statements are not yet supported.
+	   /* FINISHME: The NULL test is required because pragmas are set to
+	    * FINISHME: NULL. (See production rule for external_declaration.)
 	    */
 	   if ($2 != NULL)
 	      state->translation_unit.push_tail(& $2->link);
@@ -710,8 +710,9 @@ declaration:
 			       "only be applied to `int' or `float'\n");
 	      YYERROR;
 	   }
-
-	   $$ = NULL; /* FINISHME */
+	   $3->precision = $2;
+	   $3->is_precision_statement = true;
+	   $$ = $3;
 	}
 	;
 




More information about the mesa-commit mailing list