summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/glsl/ast.h11
-rw-r--r--src/glsl/ast_to_hir.cpp34
-rw-r--r--src/glsl/glsl_parser.yy43
3 files changed, 52 insertions, 36 deletions
diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index 1208704ff6d..6aede009c8c 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -437,6 +437,9 @@ struct ast_type_qualifier {
unsigned i;
} flags;
+ /** Precision of the type (highp/medium/lowp). */
+ unsigned precision:2;
+
/**
* Location specified via GL_ARB_explicit_attrib_location layout
*
@@ -533,7 +536,7 @@ public:
ast_type_specifier(const ast_type_specifier *that, bool is_array,
ast_expression *array_size)
: ast_node(), type_name(that->type_name), structure(that->structure),
- is_array(is_array), array_size(array_size), precision(that->precision),
+ is_array(is_array), array_size(array_size),
default_precision(that->default_precision)
{
/* empty */
@@ -542,7 +545,7 @@ public:
/** Construct a type specifier from a type name */
ast_type_specifier(const char *name)
: type_name(name), structure(NULL),
- is_array(false), array_size(NULL), precision(ast_precision_none),
+ is_array(false), array_size(NULL),
default_precision(ast_precision_none)
{
/* empty */
@@ -551,7 +554,7 @@ public:
/** Construct a type specifier from a structure definition */
ast_type_specifier(ast_struct_specifier *s)
: type_name(s->name), structure(s),
- is_array(false), array_size(NULL), precision(ast_precision_none),
+ is_array(false), array_size(NULL),
default_precision(ast_precision_none)
{
/* empty */
@@ -571,8 +574,6 @@ public:
bool is_array;
ast_expression *array_size;
- unsigned precision:2;
-
/** For precision statements, this is the given precision; otherwise none. */
unsigned default_precision:2;
};
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index c1a2af30aea..3ed6f017503 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2544,6 +2544,12 @@ ast_declarator_list::hir(exec_list *instructions,
type_name);
}
}
+
+ if (this->type->qualifier.precision != ast_precision_none &&
+ this->type->specifier->structure != NULL) {
+ _mesa_glsl_error(&loc, state, "Precision qualifiers can't be applied "
+ "to structures.\n");
+ }
}
foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
@@ -2846,7 +2852,7 @@ ast_declarator_list::hir(exec_list *instructions,
/* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
*/
- if (this->type->specifier->precision != ast_precision_none) {
+ if (this->type->qualifier.precision != ast_precision_none) {
state->check_precision_qualifiers_allowed(&loc);
}
@@ -2864,9 +2870,10 @@ ast_declarator_list::hir(exec_list *instructions,
* From page 87 of the GLSL ES spec:
* "RESOLUTION: Allow sampler types to take a precision qualifier."
*/
- if (this->type->specifier->precision != ast_precision_none
+ if (this->type->qualifier.precision != ast_precision_none
&& !var->type->is_float()
&& !var->type->is_integer()
+ && !var->type->is_record()
&& !(var->type->is_sampler() && state->es_shader)
&& !(var->type->is_array()
&& (var->type->fields.array->is_float()
@@ -3963,17 +3970,6 @@ ast_type_specifier::hir(exec_list *instructions,
YYLTYPE loc = this->get_location();
- if (this->precision != ast_precision_none
- && !state->check_precision_qualifiers_allowed(&loc)) {
- 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.
*
@@ -3985,9 +3981,15 @@ ast_type_specifier::hir(exec_list *instructions,
* qualifiers will result in an error.
*/
if (this->default_precision != ast_precision_none) {
- assert(this->precision != ast_precision_none);
- assert(this->structure == NULL); /* The check for structures was
- * performed above. */
+ if (!state->check_precision_qualifiers_allowed(&loc))
+ return NULL;
+
+ if (this->structure != NULL) {
+ _mesa_glsl_error(&loc, state,
+ "precision qualifiers do not apply to structures");
+ return NULL;
+ }
+
if (this->is_array) {
_mesa_glsl_error(&loc, state,
"default precision statements do not apply to "
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index 1a13f485503..08806a32bcf 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -169,7 +169,6 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg)
%type <type_qualifier> interface_block_layout_qualifier
%type <type_qualifier> interface_qualifier
%type <type_specifier> type_specifier
-%type <type_specifier> type_specifier_no_prec
%type <type_specifier> type_specifier_nonarray
%type <identifier> basic_type_specifier_nonarray
%type <fully_specified_type> fully_specified_type
@@ -790,9 +789,8 @@ declaration:
{
$$ = $1;
}
- | PRECISION precision_qualifier type_specifier_no_prec ';'
+ | PRECISION precision_qualifier type_specifier ';'
{
- $3->precision = $2;
$3->default_precision = $2;
$$ = $3;
}
@@ -905,6 +903,17 @@ parameter_qualifier:
$$ = $1;
$$.merge_qualifier(&@1, state, $2);
}
+ | precision_qualifier parameter_qualifier
+ {
+ if ($2.precision != ast_precision_none)
+ _mesa_glsl_error(&@1, state, "Duplicate precision qualifier.\n");
+
+ if ($2.flags.i != 0)
+ _mesa_glsl_error(&@1, state, "Precision qualifiers must come last.\n");
+
+ $$ = $2;
+ $$.precision = $1;
+ }
parameter_direction_qualifier:
IN_TOK
@@ -1319,6 +1328,11 @@ type_qualifier:
| storage_qualifier
| interpolation_qualifier
| layout_qualifier
+ | precision_qualifier
+ {
+ memset(&$$, 0, sizeof($$));
+ $$.precision = $1;
+ }
/* Multiple qualifiers:
* In GLSL 4.20, these can be specified in any order. In earlier versions,
@@ -1414,6 +1428,17 @@ type_qualifier:
$$ = $1;
$$.merge_qualifier(&@1, state, $2);
}
+ | precision_qualifier type_qualifier
+ {
+ if ($2.precision != ast_precision_none)
+ _mesa_glsl_error(&@1, state, "Duplicate precision qualifier.\n");
+
+ if ($2.flags.i != 0)
+ _mesa_glsl_error(&@1, state, "Precision qualifiers must come last.\n");
+
+ $$ = $2;
+ $$.precision = $1;
+ }
;
storage_qualifier:
@@ -1466,18 +1491,6 @@ storage_qualifier:
;
type_specifier:
- type_specifier_no_prec
- {
- $$ = $1;
- }
- | precision_qualifier type_specifier_no_prec
- {
- $$ = $2;
- $$->precision = $1;
- }
- ;
-
-type_specifier_no_prec:
type_specifier_nonarray
| type_specifier_nonarray '[' ']'
{