From c9aae5b5ebaff341c7a0bdca34191bf5845360eb Mon Sep 17 00:00:00 2001 From: MathiasDevelopes <25400788+MathiasDevelopes@users.noreply.github.com> Date: Fri, 9 Oct 2026 23:18:25 +0000 Subject: [PATCH] fix(recompiler): keep the f32 sign on natively converted f16 results AMD's Windows driver advertises shaderSignedZeroInfNanPreserveFloat16, yet OpFConvert from f32 to f16 returns +0 for -0 inputs and for negative values that round to zero, so six f16 execution tests fail there since the native conversion was added. Conversion never changes the sign, so the native path now takes the sign bit from the f32 source, as the emulated path already does. Fixes #2483 --- .../SpirvBackend/src/SpirvAlu/SpirvAluEmitterMath.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/shader/recompiler/SpirvBackend/src/SpirvAlu/SpirvAluEmitterMath.cpp b/core/shader/recompiler/SpirvBackend/src/SpirvAlu/SpirvAluEmitterMath.cpp index 51d68dbb0..42055c2e6 100644 --- a/core/shader/recompiler/SpirvBackend/src/SpirvAlu/SpirvAluEmitterMath.cpp +++ b/core/shader/recompiler/SpirvBackend/src/SpirvAlu/SpirvAluEmitterMath.cpp @@ -1223,8 +1223,9 @@ static std::uint32_t EmitNativeF32ToF16BitsRte(SpirvEmitterState& state, std::ui const auto magnitude = Binary(state, spv::OpBitwiseAnd, u32, source, ConstantU32(state, 0x7fffffffu)); const auto sign = Binary(state, spv::OpBitwiseAnd, u32, Binary(state, spv::OpShiftRightLogical, u32, source, ConstantU32(state, 16u)), ConstantU32(state, 0x8000u)); const auto payload = Binary(state, spv::OpShiftRightLogical, u32, Binary(state, spv::OpBitwiseAnd, u32, magnitude, ConstantU32(state, 0x7fffffu)), ConstantU32(state, 13u)); - const auto nan = Binary(state, spv::OpBitwiseOr, u32, sign, Binary(state, spv::OpBitwiseOr, u32, ConstantU32(state, 0x7e00u), payload)); - return Select(state, u32, Binary(state, spv::OpUGreaterThan, TypeBool(state), magnitude, ConstantU32(state, 0x7f800000u)), nan, bits); + const auto nan = Binary(state, spv::OpBitwiseOr, u32, ConstantU32(state, 0x7e00u), payload); + const auto result = Select(state, u32, Binary(state, spv::OpUGreaterThan, TypeBool(state), magnitude, ConstantU32(state, 0x7f800000u)), nan, Binary(state, spv::OpBitwiseAnd, u32, bits, ConstantU32(state, 0x7fffu))); + return Binary(state, spv::OpBitwiseOr, u32, sign, result); } std::uint32_t EmitF32ToF16BitsRte(SpirvEmitterState& state, std::uint32_t value) {