aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2020-06-30 20:24:44 -0400
committerMarek Olšák <[email protected]>2020-07-07 22:02:06 -0400
commit3781697c23f5e75ab7a18cdec7140c779bb56ce7 (patch)
tree4d443c8dc884e1b188633c22b21d209613b9a081
parent69f7a3dac69bc91464e5cba3ebf859777fa5f742 (diff)
glsl: don't lower builtins to mediump that don't allow it
Reviewed-by: Alyssa Rosenzweig <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5746>
-rw-r--r--src/compiler/glsl/ir_validate.cpp28
-rw-r--r--src/compiler/glsl/lower_precision.cpp30
-rw-r--r--src/compiler/glsl/tests/lower_precision_test.py283
-rw-r--r--src/compiler/glsl_types.h8
4 files changed, 334 insertions, 15 deletions
diff --git a/src/compiler/glsl/ir_validate.cpp b/src/compiler/glsl/ir_validate.cpp
index 4f96ef0031b..426862c039c 100644
--- a/src/compiler/glsl/ir_validate.cpp
+++ b/src/compiler/glsl/ir_validate.cpp
@@ -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;
diff --git a/src/compiler/glsl/lower_precision.cpp b/src/compiler/glsl/lower_precision.cpp
index 2529a35b4dd..e9975322e84 100644
--- a/src/compiler/glsl/lower_precision.cpp
+++ b/src/compiler/glsl/lower_precision.cpp
@@ -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);
diff --git a/src/compiler/glsl/tests/lower_precision_test.py b/src/compiler/glsl/tests/lower_precision_test.py
index 9651a066ed6..3fa74050ed8 100644
--- a/src/compiler/glsl/tests/lower_precision_test.py
+++ b/src/compiler/glsl/tests/lower_precision_test.py
@@ -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'),
]
diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h
index 4654ad7cf57..df5ca4629e5 100644
--- a/src/compiler/glsl_types.h
+++ b/src/compiler/glsl_types.h
@@ -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 ||