mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-12 18:18:36 +02:00
zink: Fix incorrect emission of SPIR-V shift ops
SPIR-V shift ops unlike NIR have undefined behavior if shift count
larger than or equalt to bitwidth.
This means that true translation of NIR ishl/ishr/ushr to SPIR-V requires
masking like that done in gallivm.
This was seen in the case of soft fp64 in cts case
KHR-GL46.gpu_shader_fp64.builtin.ceil_double.
Cc: mesa-stable
Reviewed-by: Georg Lehmann <dadschoorse@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18074>
(cherry picked from commit b386df918f)
This commit is contained in:
parent
7e7a085317
commit
1a57c75620
2 changed files with 18 additions and 4 deletions
|
|
@ -130,7 +130,7 @@
|
|||
"description": "zink: Fix incorrect emission of SPIR-V shift ops",
|
||||
"nominated": true,
|
||||
"nomination_type": 0,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": null
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2124,9 +2124,6 @@ emit_alu(struct ntv_context *ctx, nir_alu_instr *alu)
|
|||
BINOP(nir_op_fge, SpvOpFOrdGreaterThanEqual)
|
||||
BINOP(nir_op_feq, SpvOpFOrdEqual)
|
||||
BINOP(nir_op_fneu, SpvOpFUnordNotEqual)
|
||||
BINOP(nir_op_ishl, SpvOpShiftLeftLogical)
|
||||
BINOP(nir_op_ishr, SpvOpShiftRightArithmetic)
|
||||
BINOP(nir_op_ushr, SpvOpShiftRightLogical)
|
||||
BINOP(nir_op_frem, SpvOpFRem)
|
||||
#undef BINOP
|
||||
|
||||
|
|
@ -2146,6 +2143,23 @@ emit_alu(struct ntv_context *ctx, nir_alu_instr *alu)
|
|||
BINOP_LOG(nir_op_ixor, SpvOpBitwiseXor, SpvOpLogicalNotEqual)
|
||||
#undef BINOP_LOG
|
||||
|
||||
#define BINOP_SHIFT(nir_op, spirv_op) \
|
||||
case nir_op: { \
|
||||
assert(nir_op_infos[alu->op].num_inputs == 2); \
|
||||
int shift_bit_size = nir_src_bit_size(alu->src[1].src); \
|
||||
nir_alu_type shift_nir_type = nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[1]); \
|
||||
SpvId shift_type = get_alu_type(ctx, shift_nir_type, num_components, shift_bit_size); \
|
||||
SpvId shift_mask = get_ivec_constant(ctx, shift_bit_size, num_components, bit_size - 1); \
|
||||
SpvId shift_count = emit_binop(ctx, SpvOpBitwiseAnd, shift_type, src[1], shift_mask); \
|
||||
result = emit_binop(ctx, spirv_op, dest_type, src[0], shift_count); \
|
||||
break; \
|
||||
}
|
||||
|
||||
BINOP_SHIFT(nir_op_ishl, SpvOpShiftLeftLogical)
|
||||
BINOP_SHIFT(nir_op_ishr, SpvOpShiftRightArithmetic)
|
||||
BINOP_SHIFT(nir_op_ushr, SpvOpShiftRightLogical)
|
||||
#undef BINOP_SHIFT
|
||||
|
||||
#define BUILTIN_BINOP(nir_op, spirv_op) \
|
||||
case nir_op: \
|
||||
assert(nir_op_infos[alu->op].num_inputs == 2); \
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue