glsl: lower builtins to mediump that always return mediump or lowp
authorMarek Olšák <marek.olsak@amd.com>
Wed, 1 Jul 2020 18:09:32 +0000 (14:09 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 8 Jul 2020 02:02:06 +0000 (22:02 -0400)
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5746>

src/compiler/glsl/lower_precision.cpp
src/compiler/glsl/tests/lower_precision_test.py

index f1ac00b2aaf4d2148b29dbf44f953c9c205d46ef..7fb7257f2ab08a25881fccb5353184d8dcfc7003 100644 (file)
@@ -408,6 +408,17 @@ find_lowerable_rvalues_visitor::visit_enter(ir_expression *ir)
    return visit_continue;
 }
 
+static bool
+function_always_returns_mediump_or_lowp(const char *name)
+{
+   return !strcmp(name, "bitCount") ||
+          !strcmp(name, "findLSB") ||
+          !strcmp(name, "findMSB") ||
+          !strcmp(name, "unpackHalf2x16") ||
+          !strcmp(name, "unpackUnorm4x8") ||
+          !strcmp(name, "unpackSnorm4x8");
+}
+
 static bool
 is_lowerable_builtin(ir_call *ir,
                      const struct set *lowerable_rvalues)
@@ -510,6 +521,11 @@ is_lowerable_builtin(ir_call *ir,
       check_parameters = 1;
    } else if (!strcmp(ir->callee_name(), "bitfieldInsert")) {
       check_parameters = 2;
+   } if (function_always_returns_mediump_or_lowp(ir->callee_name())) {
+      /* These only lower the return value. Parameters keep their precision,
+       * which is preserved in map_builtin.
+       */
+      check_parameters = 0;
    }
 
    foreach_in_list(ir_rvalue, param, &ir->actual_parameters) {
@@ -875,8 +891,14 @@ find_precision_visitor::map_builtin(ir_function_signature *sig)
    ir_function_signature *lowered_sig =
       sig->clone(lowered_builtin_mem_ctx, clone_ht);
 
-   foreach_in_list(ir_variable, param, &lowered_sig->parameters) {
-      param->data.precision = GLSL_PRECISION_MEDIUM;
+   /* Functions that always return mediump or lowp should keep their
+    * parameters intact, because they can be highp. NIR can lower
+    * the up-conversion for parameters if needed.
+    */
+   if (!function_always_returns_mediump_or_lowp(sig->function_name())) {
+      foreach_in_list(ir_variable, param, &lowered_sig->parameters) {
+         param->data.precision = GLSL_PRECISION_MEDIUM;
+      }
    }
 
    lower_precision(options, &lowered_sig->body);
index 2fc8f1922e7ce7067f12dc261132cc05971c534c..a6ad95031356a0b591bb051467d8e67afbe1f03c 100644 (file)
@@ -1538,6 +1538,96 @@ TESTS = [
          }
          """,
          r'expression int16_t bitfield_insert \(expression int16_t'),
+    Test("bitCount",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp int val;
+         out int color;
+
+         void main()
+         {
+                 color = bitCount(val) + 1;
+         }
+         """,
+         r'expression int16_t \+ \(expression int16_t i2imp \(expression int bit_count \(var_ref val'),
+    Test("findLSB",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp int val;
+         out int color;
+
+         void main()
+         {
+                 color = findLSB(val) + 1;
+         }
+         """,
+         r'expression int16_t \+ \(expression int16_t i2imp \(expression int find_lsb \(var_ref val'),
+    Test("findMSB",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp int val;
+         out int color;
+
+         void main()
+         {
+                 color = findMSB(val) + 1;
+         }
+         """,
+         r'expression int16_t \+ \(expression int16_t i2imp \(expression int find_msb \(var_ref val'),
+    Test("unpackHalf2x16",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp uint val;
+         out vec2 color;
+
+         void main()
+         {
+                 color = unpackHalf2x16(val) + vec2(1.0);
+         }
+         """,
+         r'expression f16vec2 \+ \(expression f16vec2 f2fmp \(expression vec2 unpackHalf2x16 \(var_ref val'),
+    Test("unpackUnorm4x8",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp uint val;
+         out vec4 color;
+
+         void main()
+         {
+                 color = unpackUnorm4x8(val) + vec4(1.0);
+         }
+         """,
+         r'expression f16vec4 \+ \(expression f16vec4 f2fmp \(expression vec4 unpackUnorm4x8 \(var_ref val'),
+    Test("unpackSnorm4x8",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp uint val;
+         out vec4 color;
+
+         void main()
+         {
+                 color = unpackSnorm4x8(val) + vec4(1.0);
+         }
+         """,
+         r'expression f16vec4 \+ \(expression f16vec4 f2fmp \(expression vec4 unpackSnorm4x8 \(var_ref val'),
 ]