From acf618afbc834ccfd05a33205c035ecb9737b5db Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 9 Apr 2019 17:33:48 -0300 Subject: renderer_opengl: Implement half float NaN comparisons --- .../renderer_opengl/gl_shader_decompiler.cpp | 60 +++++++++++++++------- 1 file changed, 42 insertions(+), 18 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_shader_decompiler.cpp') diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 28e490b3c..cbaa4dceb 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1173,34 +1173,46 @@ private: return GenerateUnary(operation, "any", Type::Bool, Type::Bool2); } + template + std::string GenerateHalfComparison(Operation operation, std::string compare_op) { + std::string comparison{GenerateBinaryCall(operation, compare_op, Type::Bool2, + Type::HalfFloat, Type::HalfFloat)}; + if constexpr (!with_nan) { + return comparison; + } + return "halfFloatNanComparison(" + comparison + ", " + + VisitOperand(operation, 0, Type::HalfFloat) + ", " + + VisitOperand(operation, 1, Type::HalfFloat) + ')'; + } + + template std::string Logical2HLessThan(Operation operation) { - return GenerateBinaryCall(operation, "lessThan", Type::Bool2, Type::HalfFloat, - Type::HalfFloat); + return GenerateHalfComparison(operation, "lessThan"); } + template std::string Logical2HEqual(Operation operation) { - return GenerateBinaryCall(operation, "equal", Type::Bool2, Type::HalfFloat, - Type::HalfFloat); + return GenerateHalfComparison(operation, "equal"); } + template std::string Logical2HLessEqual(Operation operation) { - return GenerateBinaryCall(operation, "lessThanEqual", Type::Bool2, Type::HalfFloat, - Type::HalfFloat); + return GenerateHalfComparison(operation, "lessThanEqual"); } + template std::string Logical2HGreaterThan(Operation operation) { - return GenerateBinaryCall(operation, "greaterThan", Type::Bool2, Type::HalfFloat, - Type::HalfFloat); + return GenerateHalfComparison(operation, "greaterThan"); } + template std::string Logical2HNotEqual(Operation operation) { - return GenerateBinaryCall(operation, "notEqual", Type::Bool2, Type::HalfFloat, - Type::HalfFloat); + return GenerateHalfComparison(operation, "notEqual"); } + template std::string Logical2HGreaterEqual(Operation operation) { - return GenerateBinaryCall(operation, "greaterThanEqual", Type::Bool2, Type::HalfFloat, - Type::HalfFloat); + return GenerateHalfComparison(operation, "greaterThanEqual"); } std::string Texture(Operation operation) { @@ -1525,12 +1537,18 @@ private: &GLSLDecompiler::LogicalNotEqual, &GLSLDecompiler::LogicalGreaterEqual, - &GLSLDecompiler::Logical2HLessThan, - &GLSLDecompiler::Logical2HEqual, - &GLSLDecompiler::Logical2HLessEqual, - &GLSLDecompiler::Logical2HGreaterThan, - &GLSLDecompiler::Logical2HNotEqual, - &GLSLDecompiler::Logical2HGreaterEqual, + &GLSLDecompiler::Logical2HLessThan, + &GLSLDecompiler::Logical2HEqual, + &GLSLDecompiler::Logical2HLessEqual, + &GLSLDecompiler::Logical2HGreaterThan, + &GLSLDecompiler::Logical2HNotEqual, + &GLSLDecompiler::Logical2HGreaterEqual, + &GLSLDecompiler::Logical2HLessThan, + &GLSLDecompiler::Logical2HEqual, + &GLSLDecompiler::Logical2HLessEqual, + &GLSLDecompiler::Logical2HGreaterThan, + &GLSLDecompiler::Logical2HNotEqual, + &GLSLDecompiler::Logical2HGreaterEqual, &GLSLDecompiler::Texture, &GLSLDecompiler::TextureLod, @@ -1633,6 +1651,12 @@ std::string GetCommonDeclarations() { "}\n\n" "vec2 toHalf2(float value) {\n" " return unpackHalf2x16(ftou(value));\n" + "}\n\n" + "bvec2 halfFloatNanComparison(bvec2 comparison, vec2 pair1, vec2 pair2) {\n" + " bvec2 is_nan1 = isnan(pair1);\n" + " bvec2 is_nan2 = isnan(pair2);\n" + " return bvec2(comparison.x || is_nan1.x || is_nan2.x, comparison.y || is_nan1.y || " + "is_nan2.y);\n" "}\n"; } -- cgit v1.2.3