unsigned i;
} flags;
+ /** Precision of the type (highp/medium/lowp). */
+ unsigned precision:2;
+
/**
* Location specified via GL_ARB_explicit_attrib_location layout
*
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 */
/** 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 */
/** 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 */
bool is_array;
ast_expression *array_size;
- unsigned precision:2;
-
/** For precision statements, this is the given precision; otherwise none. */
unsigned default_precision:2;
};
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) {
/* 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);
}
* 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()
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.
*
* 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 "
%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
{
$$ = $1;
}
- | PRECISION precision_qualifier type_specifier_no_prec ';'
+ | PRECISION precision_qualifier type_specifier ';'
{
- $3->precision = $2;
$3->default_precision = $2;
$$ = $3;
}
$$ = $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
| 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,
$$ = $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:
;
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 '[' ']'
{