nir: Add 1-bit Boolean opcodes
We also have to add support for 1-bit integers while we're here so we get 1-bit variants of iand, ior, and inot. Reviewed-by: Eric Anholt <eric@anholt.net> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Tested-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:

committed by
Jason Ekstrand

parent
615cc26b97
commit
191a1dce92
@@ -198,6 +198,10 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
LOWER_REDUCTION(nir_op_fdot, nir_op_fmul, nir_op_fadd);
|
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_fequal, nir_op_feq32, nir_op_iand);
|
||||||
LOWER_REDUCTION(nir_op_b32all_iequal, nir_op_ieq32, 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);
|
LOWER_REDUCTION(nir_op_b32any_fnequal, nir_op_fne32, nir_op_ior);
|
||||||
|
@@ -91,6 +91,7 @@ class Opcode(object):
|
|||||||
tfloat = "float"
|
tfloat = "float"
|
||||||
tint = "int"
|
tint = "int"
|
||||||
tbool = "bool"
|
tbool = "bool"
|
||||||
|
tbool1 = "bool1"
|
||||||
tbool32 = "bool32"
|
tbool32 = "bool32"
|
||||||
tuint = "uint"
|
tuint = "uint"
|
||||||
tuint16 = "uint16"
|
tuint16 = "uint16"
|
||||||
@@ -119,11 +120,11 @@ def type_sizes(type_):
|
|||||||
if type_has_size(type_):
|
if type_has_size(type_):
|
||||||
return [type_size(type_)]
|
return [type_size(type_)]
|
||||||
elif type_ == 'bool':
|
elif type_ == 'bool':
|
||||||
return [32]
|
return [1, 32]
|
||||||
elif type_ == 'float':
|
elif type_ == 'float':
|
||||||
return [16, 32, 64]
|
return [16, 32, 64]
|
||||||
else:
|
else:
|
||||||
return [8, 16, 32, 64]
|
return [1, 8, 16, 32, 64]
|
||||||
|
|
||||||
def type_base_type(type_):
|
def type_base_type(type_):
|
||||||
m = _TYPE_SPLIT_RE.match(type_)
|
m = _TYPE_SPLIT_RE.match(type_)
|
||||||
@@ -430,6 +431,9 @@ def binop_convert(name, out_type, in_type, alg_props, const_expr):
|
|||||||
def binop(name, ty, alg_props, const_expr):
|
def binop(name, ty, alg_props, const_expr):
|
||||||
binop_convert(name, ty, 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, tbool1, ty, alg_props, const_expr)
|
||||||
|
|
||||||
def binop_compare32(name, ty, alg_props, const_expr):
|
def binop_compare32(name, ty, alg_props, const_expr):
|
||||||
binop_convert(name, tbool32, ty, alg_props, const_expr)
|
binop_convert(name, tbool32, ty, alg_props, const_expr)
|
||||||
|
|
||||||
@@ -550,6 +554,16 @@ binop("frem", tfloat, "", "src0 - src1 * truncf(src0 / src1)")
|
|||||||
|
|
||||||
# these integer-aware comparisons return a boolean (0 or ~0)
|
# 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("flt32", tfloat, "", "src0 < src1")
|
||||||
binop_compare32("fge32", tfloat, "", "src0 >= src1")
|
binop_compare32("fge32", tfloat, "", "src0 >= src1")
|
||||||
binop_compare32("feq32", tfloat, commutative, "src0 == src1")
|
binop_compare32("feq32", tfloat, commutative, "src0 == src1")
|
||||||
@@ -563,6 +577,15 @@ binop_compare32("uge32", tuint, "", "src0 >= src1")
|
|||||||
|
|
||||||
# integer-aware GLSL-style comparisons that compare floats and ints
|
# integer-aware GLSL-style comparisons that compare floats and ints
|
||||||
|
|
||||||
|
binop_reduce("ball_fequal", 1, tbool1, tfloat, "{src0} == {src1}",
|
||||||
|
"{src0} && {src1}", "{src}")
|
||||||
|
binop_reduce("bany_fnequal", 1, tbool1, tfloat, "{src0} != {src1}",
|
||||||
|
"{src0} || {src1}", "{src}")
|
||||||
|
binop_reduce("ball_iequal", 1, tbool1, tint, "{src0} == {src1}",
|
||||||
|
"{src0} && {src1}", "{src}")
|
||||||
|
binop_reduce("bany_inequal", 1, tbool1, tint, "{src0} != {src1}",
|
||||||
|
"{src0} || {src1}", "{src}")
|
||||||
|
|
||||||
binop_reduce("b32all_fequal", 1, tbool32, tfloat, "{src0} == {src1}",
|
binop_reduce("b32all_fequal", 1, tbool32, tfloat, "{src0} == {src1}",
|
||||||
"{src0} && {src1}", "{src}")
|
"{src0} && {src1}", "{src}")
|
||||||
binop_reduce("b32any_fnequal", 1, tbool32, tfloat, "{src0} != {src1}",
|
binop_reduce("b32any_fnequal", 1, tbool32, tfloat, "{src0} != {src1}",
|
||||||
@@ -756,6 +779,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("imed3", tint, "MAX2(MIN2(MAX2(src0, src1), src2), MIN2(src0, src1))")
|
||||||
triop("umed3", tuint, "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],
|
||||||
|
[tbool1, tuint, tuint], "", "src0 ? src1 : src2")
|
||||||
opcode("b32csel", 0, tuint, [0, 0, 0],
|
opcode("b32csel", 0, tuint, [0, 0, 0],
|
||||||
[tbool32, tuint, tuint], "", "src0 ? src1 : src2")
|
[tbool32, tuint, tuint], "", "src0 ? src1 : src2")
|
||||||
|
|
||||||
|
@@ -110,7 +110,8 @@ nir_op_matches_search_op(nir_op nop, uint16_t sop)
|
|||||||
|
|
||||||
#define MATCH_BCONV_CASE(op) \
|
#define MATCH_BCONV_CASE(op) \
|
||||||
case nir_search_op_##op: \
|
case nir_search_op_##op: \
|
||||||
return nop == nir_op_##op##32;
|
return nop == nir_op_##op##1 || \
|
||||||
|
nop == nir_op_##op##32;
|
||||||
|
|
||||||
switch (sop) {
|
switch (sop) {
|
||||||
MATCH_FCONV_CASE(i2f)
|
MATCH_FCONV_CASE(i2f)
|
||||||
@@ -160,6 +161,7 @@ nir_op_for_search_op(uint16_t sop, unsigned bit_size)
|
|||||||
#define RET_BCONV_CASE(op) \
|
#define RET_BCONV_CASE(op) \
|
||||||
case nir_search_op_##op: \
|
case nir_search_op_##op: \
|
||||||
switch (bit_size) { \
|
switch (bit_size) { \
|
||||||
|
case 1: return nir_op_##op##1; \
|
||||||
case 32: return nir_op_##op##32; \
|
case 32: return nir_op_##op##32; \
|
||||||
default: unreachable("Invalid bit size"); \
|
default: unreachable("Invalid bit size"); \
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user