summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2020-05-09 04:56:50 -0300
committerReinUsesLisp <reinuseslisp@airmail.cc>2020-05-10 02:59:33 -0300
commit8b329ddcc9b39353b9545289b3bd653a77db0103 (patch)
tree6789cbf1016daecc6bdc373b4d8b79b92463d538 /src
parent4e57f9d5cfc32b37fe7b6a1563ca2101ec59887c (diff)
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).
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index d071abd84..960ebf1a1 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;
}