glsl: Store the precision for a function return type

The precision for a function return type is now stored in
ir_function_signature. This will later be useful to implement mediump
to float16 lowering. In the meantime it is also useful to catch errors
where a function is redeclared with a different precision.

Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
This commit is contained in:
Neil Roberts
2019-08-23 14:24:27 +02:00
parent 3a7e92dac5
commit 95927c414f
3 changed files with 30 additions and 1 deletions

View File

@@ -6015,6 +6015,19 @@ ast_function::hir(exec_list *instructions,
name); name);
} }
/* Get the precision for the return type */
unsigned return_precision;
if (state->es_shader) {
YYLTYPE loc = this->get_location();
return_precision =
select_gles_precision(this->return_type->qualifier.precision,
return_type,
state,
&loc);
} else {
return_precision = GLSL_PRECISION_NONE;
}
/* Create an ir_function if one doesn't already exist. */ /* Create an ir_function if one doesn't already exist. */
f = state->symbols->get_function(name); f = state->symbols->get_function(name);
@@ -6085,6 +6098,13 @@ ast_function::hir(exec_list *instructions,
"match prototype", name); "match prototype", name);
} }
if (sig->return_precision != return_precision) {
YYLTYPE loc = this->get_location();
_mesa_glsl_error(&loc, state, "function `%s' return type precision "
"doesn't match prototype", name);
}
if (sig->is_defined) { if (sig->is_defined) {
if (is_definition) { if (is_definition) {
YYLTYPE loc = this->get_location(); YYLTYPE loc = this->get_location();
@@ -6129,6 +6149,7 @@ ast_function::hir(exec_list *instructions,
*/ */
if (sig == NULL) { if (sig == NULL) {
sig = new(ctx) ir_function_signature(return_type); sig = new(ctx) ir_function_signature(return_type);
sig->return_precision = return_precision;
f->add_signature(sig); f->add_signature(sig);
} }

View File

@@ -1804,6 +1804,7 @@ ir_function_signature::ir_function_signature(const glsl_type *return_type,
builtin_available_predicate b) builtin_available_predicate b)
: ir_instruction(ir_type_function_signature), : ir_instruction(ir_type_function_signature),
return_type(return_type), is_defined(false), return_type(return_type), is_defined(false),
return_precision(GLSL_PRECISION_NONE),
intrinsic_id(ir_intrinsic_invalid), builtin_avail(b), _function(NULL) intrinsic_id(ir_intrinsic_invalid), builtin_avail(b), _function(NULL)
{ {
this->origin = NULL; this->origin = NULL;

View File

@@ -1222,7 +1222,7 @@ public:
/** /**
* Function return type. * Function return type.
* *
* \note This discards the optional precision qualifier. * \note The precision qualifier is stored separately in return_precision.
*/ */
const struct glsl_type *return_type; const struct glsl_type *return_type;
@@ -1237,6 +1237,13 @@ public:
/** Whether or not this function has a body (which may be empty). */ /** Whether or not this function has a body (which may be empty). */
unsigned is_defined:1; unsigned is_defined:1;
/*
* Precision qualifier for the return type.
*
* See the comment for ir_variable_data::precision for more details.
*/
unsigned return_precision:2;
/** Whether or not this function signature is a built-in. */ /** Whether or not this function signature is a built-in. */
bool is_builtin() const; bool is_builtin() const;