From 191a1dce92803a99dae774b47264ff32da7b6689 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 19 Oct 2018 10:40:20 -0500 Subject: [PATCH] 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 Reviewed-by: Bas Nieuwenhuizen Tested-by: Bas Nieuwenhuizen --- src/compiler/nir/nir_lower_alu_to_scalar.c | 4 +++ src/compiler/nir/nir_opcodes.py | 29 ++++++++++++++++++++-- src/compiler/nir/nir_search.c | 4 ++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/compiler/nir/nir_lower_alu_to_scalar.c b/src/compiler/nir/nir_lower_alu_to_scalar.c index e406207c3cd..9b175878c15 100644 --- a/src/compiler/nir/nir_lower_alu_to_scalar.c +++ b/src/compiler/nir/nir_lower_alu_to_scalar.c @@ -198,6 +198,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 c89bdeb436a..d32005846a6 100644 --- a/src/compiler/nir/nir_opcodes.py +++ b/src/compiler/nir/nir_opcodes.py @@ -91,6 +91,7 @@ class Opcode(object): tfloat = "float" tint = "int" tbool = "bool" +tbool1 = "bool1" tbool32 = "bool32" tuint = "uint" tuint16 = "uint16" @@ -119,11 +120,11 @@ def type_sizes(type_): if type_has_size(type_): return [type_size(type_)] elif type_ == 'bool': - return [32] + return [1, 32] elif type_ == 'float': return [16, 32, 64] else: - return [8, 16, 32, 64] + return [1, 8, 16, 32, 64] def type_base_type(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): 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): 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) +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") @@ -563,6 +577,15 @@ binop_compare32("uge32", tuint, "", "src0 >= src1") # 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}", "{src0} && {src1}", "{src}") 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("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], [tbool32, tuint, tuint], "", "src0 ? src1 : src2") diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c index 50f5464cef8..8578ca53c87 100644 --- a/src/compiler/nir/nir_search.c +++ b/src/compiler/nir/nir_search.c @@ -110,7 +110,8 @@ nir_op_matches_search_op(nir_op nop, uint16_t sop) #define MATCH_BCONV_CASE(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) { MATCH_FCONV_CASE(i2f) @@ -160,6 +161,7 @@ nir_op_for_search_op(uint16_t sop, unsigned bit_size) #define RET_BCONV_CASE(op) \ case nir_search_op_##op: \ switch (bit_size) { \ + case 1: return nir_op_##op##1; \ case 32: return nir_op_##op##32; \ default: unreachable("Invalid bit size"); \ } -- 2.30.2