glsl: Store the precision for a function return type
authorNeil Roberts <nroberts@igalia.com>
Fri, 23 Aug 2019 12:24:27 +0000 (14:24 +0200)
committerNeil Roberts <nroberts@igalia.com>
Wed, 4 Sep 2019 10:41:20 +0000 (12:41 +0200)
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>
src/compiler/glsl/ast_to_hir.cpp
src/compiler/glsl/ir.cpp
src/compiler/glsl/ir.h

index 37afb8bd0b02870e9963bb665b8f96fbff227dd1..194d3099060d4e79b0d80b8b6c3ae239af29f6e9 100644 (file)
@@ -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);
    }
 
index 4263f1fa9115b421eb6ca351be7c6c298c1103f8..f25ee3ee14413bd17e903d2bff6949f3d346c17c 100644 (file)
@@ -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;
index 441500ec31ed03cab44031c338cdd19711e3b009..ba831f2c1ed1f1feeb07c1b4db235ebe9ddb9e8b 100644 (file)
@@ -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;