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; exec_list declarations;
/** /**
* Special flag for vertex shader "invariant" declarations. * 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.
* 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.
*/ */
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; 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->type != NULL);
assert(!this->invariant); assert(!this->invariant);
assert(!this->precise); assert(!this->precise);

View File

@@ -1083,6 +1083,18 @@ single_declaration:
$$->declarations.push_tail(&decl->link); $$->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: fully_specified_type:

View File

@@ -1098,8 +1098,10 @@ ast_declarator_list::print(void) const
if (type) if (type)
type->print(); type->print();
else else if (invariant)
printf("invariant "); printf("invariant ");
else
printf("precise ");
foreach_list_const (ptr, & this->declarations) { foreach_list_const (ptr, & this->declarations) {
if (ptr != this->declarations.get_head()) 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->type = type;
this->invariant = false; this->invariant = false;
this->precise = false;
} }
void void