glsl: don't lower builtins to mediump that don't allow it
authorMarek Olšák <marek.olsak@amd.com>
Wed, 1 Jul 2020 00:24:44 +0000 (20:24 -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/ir_validate.cpp
src/compiler/glsl/lower_precision.cpp
src/compiler/glsl/tests/lower_precision_test.py
src/compiler/glsl_types.h

index 4f96ef0031b5fbba602cff37cf3b2032afb40143..426862c039cfbfcc80cd9a6e7c388349796b315b 100644 (file)
@@ -388,20 +388,20 @@ ir_validate::visit_leave(ir_expression *ir)
       assert(ir->type->is_int_16_32());
       break;
    case ir_unop_bitcast_i2f:
-      assert(ir->operands[0]->type->is_int_16_32());
-      assert(ir->type->is_float_16_32());
+      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
+      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
       break;
    case ir_unop_bitcast_f2i:
-      assert(ir->operands[0]->type->is_float_16_32());
-      assert(ir->type->is_int_16_32());
+      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
+      assert(ir->type->base_type == GLSL_TYPE_INT);
       break;
    case ir_unop_bitcast_u2f:
-      assert(ir->operands[0]->type->is_uint_16_32());
-      assert(ir->type->is_float_16_32());
+      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
       break;
    case ir_unop_bitcast_f2u:
-      assert(ir->operands[0]->type->is_float_16_32());
-      assert(ir->type->is_uint_16_32());
+      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
+      assert(ir->type->base_type == GLSL_TYPE_UINT);
       break;
 
    case ir_unop_bitcast_u642d:
@@ -598,7 +598,7 @@ ir_validate::visit_leave(ir_expression *ir)
 
    case ir_unop_bitfield_reverse:
       assert(ir->operands[0]->type == ir->type);
-      assert(ir->type->is_integer_16_32());
+      assert(ir->type->is_integer_32());
       break;
 
    case ir_unop_bit_count:
@@ -687,12 +687,12 @@ ir_validate::visit_leave(ir_expression *ir)
       break;
 
    case ir_unop_frexp_sig:
-      assert(ir->operands[0]->type->is_float_16_32_64());
+      assert(ir->operands[0]->type->is_float_32_64());
       assert(ir->type->is_double());
       break;
    case ir_unop_frexp_exp:
-      assert(ir->operands[0]->type->is_float_16_32_64());
-      assert(ir->type->is_int_16_32());
+      assert(ir->operands[0]->type->is_float_32_64());
+      assert(ir->type->base_type == GLSL_TYPE_INT);
       break;
    case ir_unop_subroutine_to_int:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_SUBROUTINE);
@@ -847,8 +847,8 @@ ir_validate::visit_leave(ir_expression *ir)
 
    case ir_binop_ldexp:
       assert(ir->operands[0]->type == ir->type);
-      assert(ir->operands[0]->type->is_float_16_32_64());
-      assert(ir->operands[1]->type->is_int_16_32());
+      assert(ir->operands[0]->type->is_float_32_64());
+      assert(ir->operands[1]->type->base_type == GLSL_TYPE_INT);
       assert(ir->operands[0]->type->components() ==
              ir->operands[1]->type->components());
       break;
index 2529a35b4ddb5d27b46a4c98cd60e5534b7f214e..e9975322e84f1daa9f923cdfba6eccd98363b341 100644 (file)
@@ -466,7 +466,35 @@ is_lowerable_builtin(ir_call *ir,
       }
    }
 
-   if (!ir->callee->is_builtin())
+   if (!ir->callee->is_builtin() ||
+       /* Parameters are always highp: */
+       !strcmp(ir->callee_name(), "floatBitsToInt") ||
+       !strcmp(ir->callee_name(), "floatBitsToUint") ||
+       !strcmp(ir->callee_name(), "intBitsToFloat") ||
+       !strcmp(ir->callee_name(), "uintBitsToFloat") ||
+       !strcmp(ir->callee_name(), "bitfieldReverse") ||
+       !strcmp(ir->callee_name(), "frexp") ||
+       !strcmp(ir->callee_name(), "ldexp") ||
+       /* Parameters and outputs are always highp: */
+       /* TODO: The operations are highp, but carry and borrow outputs are lowp. */
+       !strcmp(ir->callee_name(), "uaddCarry") ||
+       !strcmp(ir->callee_name(), "usubBorrow") ||
+       !strcmp(ir->callee_name(), "imulExtended") ||
+       !strcmp(ir->callee_name(), "umulExtended") ||
+       !strcmp(ir->callee_name(), "unpackUnorm2x16") ||
+       !strcmp(ir->callee_name(), "unpackSnorm2x16") ||
+       /* Outputs are highp: */
+       !strcmp(ir->callee_name(), "packUnorm2x16") ||
+       !strcmp(ir->callee_name(), "packSnorm2x16") ||
+       /* Parameters are mediump and outputs are highp. The parameters should
+        * be optimized in NIR, not here, e.g:
+        * - packHalf2x16 can just be a bitcast from f16vec2 to uint32
+        * - Other opcodes don't have to convert parameters to highp if the hw
+        *   has f16 versions. Optimize in NIR accordingly.
+        */
+       !strcmp(ir->callee_name(), "packHalf2x16") ||
+       !strcmp(ir->callee_name(), "packUnorm4x8") ||
+       !strcmp(ir->callee_name(), "packSnorm4x8"))
       return false;
 
    assert(ir->callee->return_precision == GLSL_PRECISION_NONE);
index 9651a066ed6d87567744069a3c32d3dae203e2fd..3fa74050ed8e27f40c0fc67120ff2f9c13b6f636 100644 (file)
@@ -1176,6 +1176,289 @@ TESTS = [
          }
          """,
          r'expression ivec2 \* \(txs ivec2 \(var_ref tex'),
+    Test("floatBitsToInt",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform float val;
+         out int color;
+
+         void main()
+         {
+                 color = floatBitsToInt(val + 1.0) + 1;
+         }
+         """,
+         r'expression int bitcast_f2i \(expression float'),
+    Test("floatBitsToUint",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform float val;
+         out uint color;
+
+         void main()
+         {
+                 color = floatBitsToUint(val + 1.0) + 1u;
+         }
+         """,
+         r'expression uint bitcast_f2u \(expression float'),
+    Test("intBitsToFloat",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int val;
+         out float color;
+
+         void main()
+         {
+                 color = intBitsToFloat(val + 1) + 1.0;
+         }
+         """,
+         r'expression float bitcast_i2f \(expression int'),
+    Test("uintBitsToFloat",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint val;
+         out float color;
+
+         void main()
+         {
+                 color = uintBitsToFloat(val + 1u) + 1.0;
+         }
+         """,
+         r'expression float bitcast_u2f \(expression uint'),
+    Test("bitfieldReverse",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int val;
+         out int color;
+
+         void main()
+         {
+                 color = bitfieldReverse(val + 1) + 1;
+         }
+         """,
+         r'expression int bitfield_reverse \(expression int'),
+    Test("frexp",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform float val;
+         out float color;
+         out int color2;
+
+         void main()
+         {
+                 int y;
+                 float x = frexp(val + 1.0, y);
+                 color = x + 1.0;
+                 color2 = y + 1;
+         }
+         """,
+         r'assign  \(x\) \(var_ref x\)  \(expression float f162f'),
+    Test("ldexp",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform float val;
+         uniform int exp;
+         out float color;
+
+         void main()
+         {
+                 color = ldexp(val + 1.0, exp + 1) + 1.0;
+         }
+         """,
+         r'expression float ldexp \(expression float'),
+    Test("uaddCarry",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint x, y;
+         out uint color;
+
+         void main()
+         {
+                 lowp uint carry;
+                 color = uaddCarry(x * 2u, y * 2u, carry) * 2u;
+                 color *= carry;
+         }
+         """,
+         r'expression uint \+ \(var_ref x\) \(var_ref y'),
+    Test("usubBorrow",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint x, y;
+         out uint color;
+
+         void main()
+         {
+                 lowp uint borrow;
+                 color = usubBorrow(x * 2u, y * 2u, borrow) * 2u;
+                 color *= borrow;
+         }
+         """,
+         r'expression uint \+ \(var_ref x\) \(expression uint neg'),
+    Test("imulExtended",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int x, y;
+         out int color;
+
+         void main()
+         {
+                 int msb, lsb;
+                 imulExtended(x + 2, y + 2, msb, lsb);
+                 color = msb + lsb;
+         }
+         """,
+         r'expression int64_t \* \(expression int'),
+    Test("umulExtended",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint x, y;
+         out uint color;
+
+         void main()
+         {
+                 uint msb, lsb;
+                 umulExtended(x + 2u, y + 2u, msb, lsb);
+                 color = msb + lsb;
+         }
+         """,
+         r'expression uint64_t \* \(expression uint'),
+    Test("unpackUnorm2x16",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint val;
+         out vec2 color;
+
+         void main()
+         {
+                 color = unpackUnorm2x16(val + 1u) + vec2(1.0);
+         }
+         """,
+         r'expression vec2 unpackUnorm2x16 \(expression uint'),
+    Test("unpackSnorm2x16",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint val;
+         out vec2 color;
+
+         void main()
+         {
+                 color = unpackSnorm2x16(val + 1u) + vec2(1.0);
+         }
+         """,
+         r'expression vec2 unpackSnorm2x16 \(expression uint'),
+    Test("packUnorm2x16",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform vec2 val;
+         out uint color;
+
+         void main()
+         {
+                 color = packUnorm2x16(val + vec2(1.0)) + 1u;
+         }
+         """,
+         r'expression uint packUnorm2x16 \(expression vec2'),
+    Test("packSnorm2x16",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform vec2 val;
+         out uint color;
+
+         void main()
+         {
+                 color = packSnorm2x16(val + vec2(1.0)) + 1u;
+         }
+         """,
+         r'expression uint packSnorm2x16 \(expression vec2'),
+    Test("packHalf2x16",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform vec2 val;
+         out uint color;
+
+         void main()
+         {
+                 color = packHalf2x16(val + vec2(1.0)) + 1u;
+         }
+         """,
+         r'expression uint packHalf2x16 \(expression vec2'),
+    Test("packUnorm4x8",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform vec4 val;
+         out uint color;
+
+         void main()
+         {
+                 color = packUnorm4x8(val + vec4(1.0)) + 1u;
+         }
+         """,
+         r'expression uint packUnorm4x8 \(expression vec4'),
+    Test("packSnorm4x8",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform vec4 val;
+         out uint color;
+
+         void main()
+         {
+                 color = packSnorm4x8(val + vec4(1.0)) + 1u;
+         }
+         """,
+         r'expression uint packSnorm4x8 \(expression vec4'),
 ]
 
 
index 4654ad7cf573371c719c185b6b016d1142bf8fa9..df5ca4629e5b1c266f97430c9f19036bc90e330e 100644 (file)
@@ -811,6 +811,14 @@ public:
       return base_type == GLSL_TYPE_FLOAT16 || is_float() || is_double();
    }
 
+   /**
+    * Query whether or not a type is a float or double
+    */
+   bool is_float_32_64() const
+   {
+      return is_float() || is_double();
+   }
+
    bool is_int_16_32_64() const
    {
       return base_type == GLSL_TYPE_INT16 ||