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