Browse Source

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.
tags/android-x86-2.2-r2
Chad Versace 14 years ago
parent
commit
08a286c9cc
4 changed files with 67 additions and 9 deletions
  1. 6
    2
      src/glsl/ast.h
  2. 52
    0
      src/glsl/ast_to_hir.cpp
  3. 2
    1
      src/glsl/ast_type.cpp
  4. 7
    6
      src/glsl/glsl_parser.ypp

+ 6
- 2
src/glsl/ast.h View File

@@ -462,7 +462,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 */
}
@@ -470,7 +471,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 */
}
@@ -492,6 +494,8 @@ public:
ast_expression *array_size;

unsigned precision:2;

bool is_precision_statement;
};



+ 52
- 0
src/glsl/ast_to_hir.cpp View File

@@ -3239,6 +3239,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);


+ 2
- 1
src/glsl/ast_type.cpp View File

@@ -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",

+ 7
- 6
src/glsl/glsl_parser.ypp View File

@@ -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…
Cancel
Save