From 4e57f9d5cfc32b37fe7b6a1563ca2101ec59887c Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 9 May 2020 04:55:15 -0300 Subject: shader_ir: Separate float-point comparisons in ordered and unordered This allows us to use native SPIR-V instructions without having to manually check for NAN. --- .../renderer_opengl/gl_shader_decompiler.cpp | 99 ++++++++++++---------- 1 file changed, 55 insertions(+), 44 deletions(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 99fd4ae2c..d071abd84 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1840,34 +1840,31 @@ private: Type::HalfFloat}; } - template - Expression LogicalLessThan(Operation operation) { - return GenerateBinaryInfix(operation, "<", Type::Bool, type, type); - } - - template - Expression LogicalEqual(Operation operation) { - return GenerateBinaryInfix(operation, "==", Type::Bool, type, type); - } + template + Expression Comparison(Operation operation) { + static_assert(!unordered || type == Type::Float); - template - Expression LogicalLessEqual(Operation operation) { - return GenerateBinaryInfix(operation, "<=", Type::Bool, type, type); - } - - template - Expression LogicalGreaterThan(Operation operation) { - return GenerateBinaryInfix(operation, ">", Type::Bool, type, type); + const Expression expr = GenerateBinaryInfix(operation, op, Type::Bool, type, type); + if constexpr (!unordered) { + return expr; + } + // Unordered comparisons are always true for NaN operands. + return {fmt::format("({} || isnan({}) || isnan({}))", expr.AsBool(), + VisitOperand(operation, 0).AsFloat(), + VisitOperand(operation, 1).AsFloat()), + Type::Bool}; } - template - Expression LogicalNotEqual(Operation operation) { - return GenerateBinaryInfix(operation, "!=", Type::Bool, type, type); + Expression FOrdered(Operation operation) { + return {fmt::format("(!isnan({}) && !isnan({}))", VisitOperand(operation, 0).AsFloat(), + VisitOperand(operation, 1).AsFloat()), + Type::Bool}; } - template - Expression LogicalGreaterEqual(Operation operation) { - return GenerateBinaryInfix(operation, ">=", Type::Bool, type, type); + Expression FUnordered(Operation operation) { + return {fmt::format("(isnan({}) || isnan({}))", VisitOperand(operation, 0).AsFloat(), + VisitOperand(operation, 1).AsFloat()), + Type::Bool}; } Expression LogicalAddCarry(Operation operation) { @@ -2324,6 +2321,13 @@ private: Func() = delete; ~Func() = delete; + static constexpr std::string_view LessThan = "<"; + static constexpr std::string_view Equal = "=="; + static constexpr std::string_view LessEqual = "<="; + static constexpr std::string_view GreaterThan = ">"; + static constexpr std::string_view NotEqual = "!="; + static constexpr std::string_view GreaterEqual = ">="; + static constexpr std::string_view Add = "Add"; static constexpr std::string_view Min = "Min"; static constexpr std::string_view Max = "Max"; @@ -2425,27 +2429,34 @@ private: &GLSLDecompiler::LogicalPick2, &GLSLDecompiler::LogicalAnd2, - &GLSLDecompiler::LogicalLessThan, - &GLSLDecompiler::LogicalEqual, - &GLSLDecompiler::LogicalLessEqual, - &GLSLDecompiler::LogicalGreaterThan, - &GLSLDecompiler::LogicalNotEqual, - &GLSLDecompiler::LogicalGreaterEqual, - &GLSLDecompiler::LogicalFIsNan, - - &GLSLDecompiler::LogicalLessThan, - &GLSLDecompiler::LogicalEqual, - &GLSLDecompiler::LogicalLessEqual, - &GLSLDecompiler::LogicalGreaterThan, - &GLSLDecompiler::LogicalNotEqual, - &GLSLDecompiler::LogicalGreaterEqual, - - &GLSLDecompiler::LogicalLessThan, - &GLSLDecompiler::LogicalEqual, - &GLSLDecompiler::LogicalLessEqual, - &GLSLDecompiler::LogicalGreaterThan, - &GLSLDecompiler::LogicalNotEqual, - &GLSLDecompiler::LogicalGreaterEqual, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::FOrdered, + &GLSLDecompiler::FUnordered, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, + &GLSLDecompiler::Comparison, &GLSLDecompiler::LogicalAddCarry, -- cgit v1.2.3