summaryrefslogtreecommitdiffstats
path: root/src/compiler
diff options
context:
space:
mode:
authorNeil Roberts <[email protected]>2019-08-23 14:24:27 +0200
committerNeil Roberts <[email protected]>2019-09-04 12:41:20 +0200
commit95927c414fffaba64536f3b9389a4387007e9b32 (patch)
treed8da632beb381a6e0a1b7a2721c25b6a1950dfad /src/compiler
parent3a7e92dac538e1ad76b42590beeaada28e79bb07 (diff)
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 <[email protected]>
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/glsl/ast_to_hir.cpp21
-rw-r--r--src/compiler/glsl/ir.cpp1
-rw-r--r--src/compiler/glsl/ir.h9
3 files changed, 30 insertions, 1 deletions
diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp
index 37afb8bd0b0..194d3099060 100644
--- a/src/compiler/glsl/ast_to_hir.cpp
+++ b/src/compiler/glsl/ast_to_hir.cpp
@@ -6015,6 +6015,19 @@ ast_function::hir(exec_list *instructions,
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. */
f = state->symbols->get_function(name);
@@ -6085,6 +6098,13 @@ ast_function::hir(exec_list *instructions,
"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 (is_definition) {
YYLTYPE loc = this->get_location();
@@ -6129,6 +6149,7 @@ ast_function::hir(exec_list *instructions,
*/
if (sig == NULL) {
sig = new(ctx) ir_function_signature(return_type);
+ sig->return_precision = return_precision;
f->add_signature(sig);
}
diff --git a/src/compiler/glsl/ir.cpp b/src/compiler/glsl/ir.cpp
index 4263f1fa911..f25ee3ee144 100644
--- a/src/compiler/glsl/ir.cpp
+++ b/src/compiler/glsl/ir.cpp
@@ -1804,6 +1804,7 @@ ir_function_signature::ir_function_signature(const glsl_type *return_type,
builtin_available_predicate b)
: ir_instruction(ir_type_function_signature),
return_type(return_type), is_defined(false),
+ return_precision(GLSL_PRECISION_NONE),
intrinsic_id(ir_intrinsic_invalid), builtin_avail(b), _function(NULL)
{
this->origin = NULL;
diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h
index 441500ec31e..ba831f2c1ed 100644
--- a/src/compiler/glsl/ir.h
+++ b/src/compiler/glsl/ir.h
@@ -1222,7 +1222,7 @@ public:
/**
* 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;
@@ -1237,6 +1237,13 @@ public:
/** Whether or not this function has a body (which may be empty). */
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. */
bool is_builtin() const;