summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorErik Faye-Lund <[email protected]>2020-03-03 19:37:37 +0100
committerErik Faye-Lund <[email protected]>2020-03-20 16:37:30 +0000
commitd4b0e28f62421d0fb5a5bcb19038b4f6fec622c5 (patch)
tree5ef5422b6797d188d6ce232766d06c686f7ffd3e /src/gallium
parent130c0ba1cc1b800641ed09fe7842c7ef4bce2dfb (diff)
zink/spirv: do not use bitwise operations on booleans
According to the SPIR-V specification, these operations require integer-types. When bit_size is 1, we use booleans, which makes us emit illegal code. So let's fix the emitting to check if the first source is one bit wide. For inot we can take a short-cut, and check the destination instead. This doesn't work for ieq and ine, so let's not bother to do this BINOP_LOG. Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4036> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4036>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
index 66fcbdcb9ce..aaf722ad394 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
+++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
@@ -961,9 +961,15 @@ emit_alu(struct ntv_context *ctx, nir_alu_instr *alu)
UNOP(nir_op_f2u32, SpvOpConvertFToU)
UNOP(nir_op_i2f32, SpvOpConvertSToF)
UNOP(nir_op_u2f32, SpvOpConvertUToF)
- UNOP(nir_op_inot, SpvOpNot)
#undef UNOP
+ case nir_op_inot:
+ if (bit_size == 1)
+ result = emit_unop(ctx, SpvOpLogicalNot, dest_type, src[0]);
+ else
+ result = emit_unop(ctx, SpvOpNot, dest_type, src[0]);
+ break;
+
case nir_op_b2i32:
assert(nir_op_infos[alu->op].num_inputs == 1);
result = emit_select(ctx, dest_type, src[0],
@@ -1035,8 +1041,6 @@ emit_alu(struct ntv_context *ctx, nir_alu_instr *alu)
BINOP(nir_op_fmod, SpvOpFMod)
BINOP(nir_op_ilt, SpvOpSLessThan)
BINOP(nir_op_ige, SpvOpSGreaterThanEqual)
- BINOP(nir_op_ieq, SpvOpIEqual)
- BINOP(nir_op_ine, SpvOpINotEqual)
BINOP(nir_op_uge, SpvOpUGreaterThanEqual)
BINOP(nir_op_flt, SpvOpFOrdLessThan)
BINOP(nir_op_fge, SpvOpFOrdGreaterThanEqual)
@@ -1045,10 +1049,23 @@ emit_alu(struct ntv_context *ctx, nir_alu_instr *alu)
BINOP(nir_op_ishl, SpvOpShiftLeftLogical)
BINOP(nir_op_ishr, SpvOpShiftRightArithmetic)
BINOP(nir_op_ushr, SpvOpShiftRightLogical)
- BINOP(nir_op_iand, SpvOpBitwiseAnd)
- BINOP(nir_op_ior, SpvOpBitwiseOr)
#undef BINOP
+#define BINOP_LOG(nir_op, spv_op, spv_log_op) \
+ case nir_op: \
+ assert(nir_op_infos[alu->op].num_inputs == 2); \
+ if (nir_src_bit_size(alu->src[0].src) == 1) \
+ result = emit_binop(ctx, spv_log_op, dest_type, src[0], src[1]); \
+ else \
+ result = emit_binop(ctx, spv_op, dest_type, src[0], src[1]); \
+ break;
+
+ BINOP_LOG(nir_op_iand, SpvOpBitwiseAnd, SpvOpLogicalAnd)
+ BINOP_LOG(nir_op_ior, SpvOpBitwiseOr, SpvOpLogicalOr)
+ BINOP_LOG(nir_op_ieq, SpvOpIEqual, SpvOpLogicalEqual)
+ BINOP_LOG(nir_op_ine, SpvOpINotEqual, SpvOpLogicalNotEqual)
+#undef BINOP_LOG
+
#define BUILTIN_BINOP(nir_op, spirv_op) \
case nir_op: \
assert(nir_op_infos[alu->op].num_inputs == 2); \