glsl: Move precision handling to be part of qualifier handling.
This is necessary for the parser to be able to accept precision qualifiers not immediately adjacent to the type, such as "const highp inout float foo". Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
@@ -437,6 +437,9 @@ struct ast_type_qualifier {
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
} flags;
|
} flags;
|
||||||
|
|
||||||
|
/** Precision of the type (highp/medium/lowp). */
|
||||||
|
unsigned precision:2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Location specified via GL_ARB_explicit_attrib_location layout
|
* 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_type_specifier(const ast_type_specifier *that, bool is_array,
|
||||||
ast_expression *array_size)
|
ast_expression *array_size)
|
||||||
: ast_node(), type_name(that->type_name), structure(that->structure),
|
: 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)
|
default_precision(that->default_precision)
|
||||||
{
|
{
|
||||||
/* empty */
|
/* empty */
|
||||||
@@ -542,7 +545,7 @@ public:
|
|||||||
/** Construct a type specifier from a type name */
|
/** Construct a type specifier from a type name */
|
||||||
ast_type_specifier(const char *name)
|
ast_type_specifier(const char *name)
|
||||||
: type_name(name), structure(NULL),
|
: 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)
|
default_precision(ast_precision_none)
|
||||||
{
|
{
|
||||||
/* empty */
|
/* empty */
|
||||||
@@ -551,7 +554,7 @@ public:
|
|||||||
/** Construct a type specifier from a structure definition */
|
/** Construct a type specifier from a structure definition */
|
||||||
ast_type_specifier(ast_struct_specifier *s)
|
ast_type_specifier(ast_struct_specifier *s)
|
||||||
: type_name(s->name), structure(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)
|
default_precision(ast_precision_none)
|
||||||
{
|
{
|
||||||
/* empty */
|
/* empty */
|
||||||
@@ -571,8 +574,6 @@ public:
|
|||||||
bool is_array;
|
bool is_array;
|
||||||
ast_expression *array_size;
|
ast_expression *array_size;
|
||||||
|
|
||||||
unsigned precision:2;
|
|
||||||
|
|
||||||
/** For precision statements, this is the given precision; otherwise none. */
|
/** For precision statements, this is the given precision; otherwise none. */
|
||||||
unsigned default_precision:2;
|
unsigned default_precision:2;
|
||||||
};
|
};
|
||||||
|
@@ -2544,6 +2544,12 @@ ast_declarator_list::hir(exec_list *instructions,
|
|||||||
type_name);
|
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) {
|
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.
|
/* 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);
|
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:
|
* From page 87 of the GLSL ES spec:
|
||||||
* "RESOLUTION: Allow sampler types to take a precision qualifier."
|
* "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_float()
|
||||||
&& !var->type->is_integer()
|
&& !var->type->is_integer()
|
||||||
|
&& !var->type->is_record()
|
||||||
&& !(var->type->is_sampler() && state->es_shader)
|
&& !(var->type->is_sampler() && state->es_shader)
|
||||||
&& !(var->type->is_array()
|
&& !(var->type->is_array()
|
||||||
&& (var->type->fields.array->is_float()
|
&& (var->type->fields.array->is_float()
|
||||||
@@ -3963,17 +3970,6 @@ ast_type_specifier::hir(exec_list *instructions,
|
|||||||
|
|
||||||
YYLTYPE loc = this->get_location();
|
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
|
/* If this is a precision statement, check that the type to which it is
|
||||||
* applied is either float or int.
|
* applied is either float or int.
|
||||||
*
|
*
|
||||||
@@ -3985,9 +3981,15 @@ ast_type_specifier::hir(exec_list *instructions,
|
|||||||
* qualifiers will result in an error.
|
* qualifiers will result in an error.
|
||||||
*/
|
*/
|
||||||
if (this->default_precision != ast_precision_none) {
|
if (this->default_precision != ast_precision_none) {
|
||||||
assert(this->precision != ast_precision_none);
|
if (!state->check_precision_qualifiers_allowed(&loc))
|
||||||
assert(this->structure == NULL); /* The check for structures was
|
return NULL;
|
||||||
* performed above. */
|
|
||||||
|
if (this->structure != NULL) {
|
||||||
|
_mesa_glsl_error(&loc, state,
|
||||||
|
"precision qualifiers do not apply to structures");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->is_array) {
|
if (this->is_array) {
|
||||||
_mesa_glsl_error(&loc, state,
|
_mesa_glsl_error(&loc, state,
|
||||||
"default precision statements do not apply to "
|
"default precision statements do not apply to "
|
||||||
|
@@ -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_block_layout_qualifier
|
||||||
%type <type_qualifier> interface_qualifier
|
%type <type_qualifier> interface_qualifier
|
||||||
%type <type_specifier> type_specifier
|
%type <type_specifier> type_specifier
|
||||||
%type <type_specifier> type_specifier_no_prec
|
|
||||||
%type <type_specifier> type_specifier_nonarray
|
%type <type_specifier> type_specifier_nonarray
|
||||||
%type <identifier> basic_type_specifier_nonarray
|
%type <identifier> basic_type_specifier_nonarray
|
||||||
%type <fully_specified_type> fully_specified_type
|
%type <fully_specified_type> fully_specified_type
|
||||||
@@ -790,9 +789,8 @@ declaration:
|
|||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| PRECISION precision_qualifier type_specifier_no_prec ';'
|
| PRECISION precision_qualifier type_specifier ';'
|
||||||
{
|
{
|
||||||
$3->precision = $2;
|
|
||||||
$3->default_precision = $2;
|
$3->default_precision = $2;
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
}
|
}
|
||||||
@@ -905,6 +903,17 @@ parameter_qualifier:
|
|||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$.merge_qualifier(&@1, state, $2);
|
$$.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:
|
parameter_direction_qualifier:
|
||||||
IN_TOK
|
IN_TOK
|
||||||
@@ -1319,6 +1328,11 @@ type_qualifier:
|
|||||||
| storage_qualifier
|
| storage_qualifier
|
||||||
| interpolation_qualifier
|
| interpolation_qualifier
|
||||||
| layout_qualifier
|
| layout_qualifier
|
||||||
|
| precision_qualifier
|
||||||
|
{
|
||||||
|
memset(&$$, 0, sizeof($$));
|
||||||
|
$$.precision = $1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Multiple qualifiers:
|
/* Multiple qualifiers:
|
||||||
* In GLSL 4.20, these can be specified in any order. In earlier versions,
|
* In GLSL 4.20, these can be specified in any order. In earlier versions,
|
||||||
@@ -1414,6 +1428,17 @@ type_qualifier:
|
|||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$.merge_qualifier(&@1, state, $2);
|
$$.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:
|
storage_qualifier:
|
||||||
@@ -1466,18 +1491,6 @@ storage_qualifier:
|
|||||||
;
|
;
|
||||||
|
|
||||||
type_specifier:
|
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
|
||||||
| type_specifier_nonarray '[' ']'
|
| type_specifier_nonarray '[' ']'
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user