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
This commit is contained in:
MathiasDevelopes 2026-10-09 23:18:25 +00:00 committed by Dean Galvin
parent 2e197741c8
commit c9aae5b5eb
1 changed files with 3 additions and 2 deletions

View File

@ -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) {