From ad6e95afb45c090a037135451a98ee5b66d5a8c2 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sat, 25 Feb 2023 16:11:09 -0800 Subject: [PATCH] D3D: Restore workaround for erroneous NaN optimization The HLSL compiler incorrectly decides isnan can't be true, so this workaround was originally added in 52c82733 but lost during the conversion to SPIR-V. --- Source/Core/VideoCommon/ShaderGenCommon.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/ShaderGenCommon.cpp b/Source/Core/VideoCommon/ShaderGenCommon.cpp index 44037d01dc..234703d7d5 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.cpp +++ b/Source/Core/VideoCommon/ShaderGenCommon.cpp @@ -100,7 +100,20 @@ std::string GetDiskShaderCacheFileName(APIType api_type, const char* type, bool void WriteIsNanHeader(ShaderCode& out, APIType api_type) { - out.Write("#define dolphin_isnan(f) isnan(f)\n"); + if (api_type == APIType::D3D) + { + out.Write("bool dolphin_isnan(float f) {{\n" + " // Workaround for the HLSL compiler deciding that isnan can never be true and\n" + " // optimising away the call, even though the value can actually be NaN\n" + " // Just look for the bit pattern that indicates NaN instead\n" + " return (floatBitsToInt(f) & 0x7FFFFFFF) > 0x7F800000;\n" + "}}\n\n"); + // If isfinite is needed, (floatBitsToInt(f) & 0x7F800000) != 0x7F800000 can be used + } + else + { + out.Write("#define dolphin_isnan(f) isnan(f)\n"); + } } void WriteBitfieldExtractHeader(ShaderCode& out, APIType api_type,