[Mesa-dev] [PATCH 22/31] nir: Add 1-bit boolean opcodes

Jason Ekstrand jason at jlekstrand.net
Mon Oct 22 22:13:53 UTC 2018


---
 src/compiler/nir/nir_lower_alu_to_scalar.c |  4 +++
 src/compiler/nir/nir_opcodes.py            | 29 ++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/src/compiler/nir/nir_lower_alu_to_scalar.c b/src/compiler/nir/nir_lower_alu_to_scalar.c
index e424dff25c4..4f97472a87d 100644
--- a/src/compiler/nir/nir_lower_alu_to_scalar.c
+++ b/src/compiler/nir/nir_lower_alu_to_scalar.c
@@ -197,6 +197,10 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
       return false;
 
       LOWER_REDUCTION(nir_op_fdot, nir_op_fmul, nir_op_fadd);
+      LOWER_REDUCTION(nir_op_ball_fequal, nir_op_feq, nir_op_iand);
+      LOWER_REDUCTION(nir_op_ball_iequal, nir_op_ieq, nir_op_iand);
+      LOWER_REDUCTION(nir_op_bany_fnequal, nir_op_fne, nir_op_ior);
+      LOWER_REDUCTION(nir_op_bany_inequal, nir_op_ine, nir_op_ior);
       LOWER_REDUCTION(nir_op_b32all_fequal, nir_op_feq32, nir_op_iand);
       LOWER_REDUCTION(nir_op_b32all_iequal, nir_op_ieq32, nir_op_iand);
       LOWER_REDUCTION(nir_op_b32any_fnequal, nir_op_fne32, nir_op_ior);
diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py
index d349f74ed2a..aee505667b8 100644
--- a/src/compiler/nir/nir_opcodes.py
+++ b/src/compiler/nir/nir_opcodes.py
@@ -89,6 +89,7 @@ class Opcode(object):
 # helper variables for strings
 tfloat = "float"
 tint = "int"
+tbool = "bool1"
 tbool32 = "bool32"
 tuint = "uint"
 tuint16 = "uint16"
@@ -192,6 +193,10 @@ for src_t in [tint, tuint, tfloat]:
 
 # We'll hand-code the to/from bool conversion opcodes.  Because bool doesn't
 # have multiple bit-sizes, we can always infer the size from the other type.
+unop_convert("f2b", tbool, tfloat, "src0 != 0.0")
+unop_convert("i2b", tbool, tint, "src0 != 0")
+unop_convert("b2f", tfloat, tbool, "src0 ? 1.0 : 0.0")
+unop_convert("b2i", tint, tbool, "src0 ? 1 : 0")
 unop_convert("f2b32", tbool32, tfloat, "src0 != 0.0")
 unop_convert("i2b32", tbool32, tint, "src0 != 0")
 unop_convert("b322f", tfloat, tbool32, "src0 ? 1.0 : 0.0")
@@ -405,6 +410,9 @@ def binop_convert(name, out_type, in_type, alg_props, const_expr):
 def binop(name, ty, alg_props, const_expr):
    binop_convert(name, ty, ty, alg_props, const_expr)
 
+def binop_compare(name, ty, alg_props, const_expr):
+   binop_convert(name, tbool, ty, alg_props, const_expr)
+
 def binop_compare32(name, ty, alg_props, const_expr):
    binop_convert(name, tbool32, ty, alg_props, const_expr)
 
@@ -488,6 +496,16 @@ binop("frem", tfloat, "", "src0 - src1 * truncf(src0 / src1)")
 
 # these integer-aware comparisons return a boolean (0 or ~0)
 
+binop_compare("flt", tfloat, "", "src0 < src1")
+binop_compare("fge", tfloat, "", "src0 >= src1")
+binop_compare("feq", tfloat, commutative, "src0 == src1")
+binop_compare("fne", tfloat, commutative, "src0 != src1")
+binop_compare("ilt", tint, "", "src0 < src1")
+binop_compare("ige", tint, "", "src0 >= src1")
+binop_compare("ieq", tint, commutative, "src0 == src1")
+binop_compare("ine", tint, commutative, "src0 != src1")
+binop_compare("ult", tuint, "", "src0 < src1")
+binop_compare("uge", tuint, "", "src0 >= src1")
 binop_compare32("flt32", tfloat, "", "src0 < src1")
 binop_compare32("fge32", tfloat, "", "src0 >= src1")
 binop_compare32("feq32", tfloat, commutative, "src0 == src1")
@@ -501,6 +519,15 @@ binop_compare32("uge32", tuint, "", "src0 >= src1")
 
 # integer-aware GLSL-style comparisons that compare floats and ints
 
+binop_reduce("ball_fequal",  1, tbool, tfloat, "{src0} == {src1}",
+             "{src0} && {src1}", "{src}")
+binop_reduce("bany_fnequal", 1, tbool, tfloat, "{src0} != {src1}",
+             "{src0} || {src1}", "{src}")
+binop_reduce("ball_iequal",  1, tbool, tint, "{src0} == {src1}",
+             "{src0} && {src1}", "{src}")
+binop_reduce("bany_inequal", 1, tbool, tint, "{src0} != {src1}",
+             "{src0} || {src1}", "{src}")
+
 binop_reduce("b32all_fequal",  1, tbool32, tfloat, "{src0} == {src1}",
              "{src0} && {src1}", "{src}")
 binop_reduce("b32any_fnequal", 1, tbool32, tfloat, "{src0} != {src1}",
@@ -694,6 +721,8 @@ triop("fmed3", tfloat, "fmaxf(fminf(fmaxf(src0, src1), src2), fminf(src0, src1))
 triop("imed3", tint, "MAX2(MIN2(MAX2(src0, src1), src2), MIN2(src0, src1))")
 triop("umed3", tuint, "MAX2(MIN2(MAX2(src0, src1), src2), MIN2(src0, src1))")
 
+opcode("bcsel", 0, tuint, [0, 0, 0],
+      [tbool, tuint, tuint], "", "src0 ? src1 : src2")
 opcode("b32csel", 0, tuint, [0, 0, 0],
       [tbool32, tuint, tuint], "", "src0 ? src1 : src2")
 
-- 
2.19.1



More information about the mesa-dev mailing list