glsl: Add support for precise redeclarations

This works like glsl-1.20+'s invariant redeclarations, but with fewer
restrictions, since `precise` is allowed on pretty much anything.

Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
Chris Forbes
2014-04-27 16:03:54 +12:00
parent 4b756b20c4
commit 5ecffe5a3a
4 changed files with 47 additions and 7 deletions

View File

@@ -746,13 +746,11 @@ public:
exec_list declarations;
/**
* Special flag for vertex shader "invariant" declarations.
*
* Vertex shaders can contain "invariant" variable redeclarations that do
* not include a type. For example, "invariant gl_Position;". This flag
* is used to note these cases when no type is specified.
* Flags for redeclarations. In these cases, no type is specified, to
* `type` is allowed to be NULL. In all other cases, this would be an error.
*/
int invariant;
int invariant; /** < `invariant` redeclaration */
int precise; /** < `precise` redeclaration */
};

View File

@@ -3174,6 +3174,33 @@ ast_declarator_list::hir(exec_list *instructions,
return NULL;
}
if (this->precise) {
assert(this->type == NULL);
foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
assert(decl->array_specifier == NULL);
assert(decl->initializer == NULL);
ir_variable *const earlier =
state->symbols->get_variable(decl->identifier);
if (earlier == NULL) {
_mesa_glsl_error(& loc, state,
"undeclared variable `%s' cannot be marked "
"precise", decl->identifier);
} else if (earlier->data.used) {
_mesa_glsl_error(& loc, state,
"variable `%s' may not be redeclared "
"`precise' after being used",
earlier->name);
} else {
earlier->data.precise = true;
}
}
/* Precise redeclarations do not have r-values either. */
return NULL;
}
assert(this->type != NULL);
assert(!this->invariant);
assert(!this->precise);

View File

@@ -1083,6 +1083,18 @@ single_declaration:
$$->declarations.push_tail(&decl->link);
}
| PRECISE variable_identifier
{
void *ctx = state;
ast_declaration *decl = new(ctx) ast_declaration($2, NULL, NULL);
decl->set_location(@2);
$$ = new(ctx) ast_declarator_list(NULL);
$$->set_location_range(@1, @2);
$$->precise = true;
$$->declarations.push_tail(&decl->link);
}
;
fully_specified_type:

View File

@@ -1098,8 +1098,10 @@ ast_declarator_list::print(void) const
if (type)
type->print();
else
else if (invariant)
printf("invariant ");
else
printf("precise ");
foreach_list_const (ptr, & this->declarations) {
if (ptr != this->declarations.get_head())
@@ -1117,6 +1119,7 @@ ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
{
this->type = type;
this->invariant = false;
this->precise = false;
}
void