소스 검색

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).
ReinUsesLisp 6 년 전
부모
커밋
8b329ddcc9
1개의 변경된 파일9개의 추가작업 그리고 0개의 파일을 삭제
  1. 9 0
      src/video_core/renderer_opengl/gl_shader_decompiler.cpp

+ 9 - 0
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;
         }