From 8b329ddcc9b39353b9545289b3bd653a77db0103 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 9 May 2020 04:56:50 -0300 Subject: [PATCH] gl_shader_decompiler: Properly emulate NaN behaviour on NE "Not equal" operators on GLSL seem to behave as unordered when we expect an ordered comparison. Manually emulate this checking for LGE values (numbers, not-NaNs). --- src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index d071abd84c..960ebf1a12 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1845,6 +1845,15 @@ private: static_assert(!unordered || type == Type::Float); const Expression expr = GenerateBinaryInfix(operation, op, Type::Bool, type, type); + + if constexpr (op.compare("!=") == 0 && type == Type::Float && !unordered) { + // GLSL's operator!=(float, float) doesn't seem be ordered. This happens on both AMD's + // and Nvidia's proprietary stacks. Manually force an ordered comparison. + return {fmt::format("({} && !isnan({}) && !isnan({}))", expr.AsBool(), + VisitOperand(operation, 0).AsFloat(), + VisitOperand(operation, 1).AsFloat()), + Type::Bool}; + } if constexpr (!unordered) { return expr; }