From 95927c414fffaba64536f3b9389a4387007e9b32 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Fri, 23 Aug 2019 14:24:27 +0200 Subject: [PATCH] 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 --- src/compiler/glsl/ast_to_hir.cpp | 21 +++++++++++++++++++++ src/compiler/glsl/ir.cpp | 1 + src/compiler/glsl/ir.h | 9 ++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) 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; -- 2.30.2