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