mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-01 18:58:10 +02:00
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 08a286c9cc)
This commit is contained in:
parent
757a49cafd
commit
b2b1b1f596
4 changed files with 67 additions and 9 deletions
|
|
@ -441,7 +441,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 */
|
||||
}
|
||||
|
|
@ -449,7 +450,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 */
|
||||
}
|
||||
|
|
@ -471,6 +473,8 @@ public:
|
|||
ast_expression *array_size;
|
||||
|
||||
unsigned precision:2;
|
||||
|
||||
bool is_precision_statement;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3128,6 +3128,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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -276,16 +276,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);
|
||||
|
|
@ -708,8 +708,9 @@ declaration:
|
|||
"only be applied to `int' or `float'\n");
|
||||
YYERROR;
|
||||
}
|
||||
|
||||
$$ = NULL; /* FINISHME */
|
||||
$3->precision = $2;
|
||||
$3->is_precision_statement = true;
|
||||
$$ = $3;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue