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:
@@ -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 */
|
||||
};
|
||||
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user