diff options
author | bunnei <bunneidev@gmail.com> | 2018-07-01 09:22:11 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-01 09:22:11 +0200 |
commit | 85a60e204413c6855b68e94197be3bbc0c4a855d (patch) | |
tree | 225f6357ecdd01baefd85f0410e2cf5cf1a487b5 | |
parent | Merge pull request #595 from bunnei/raster-cache (diff) | |
parent | gl_shader_decompiler: Implement predicate NotEqualWithNan. (diff) | |
download | yuzu-85a60e204413c6855b68e94197be3bbc0c4a855d.tar yuzu-85a60e204413c6855b68e94197be3bbc0c4a855d.tar.gz yuzu-85a60e204413c6855b68e94197be3bbc0c4a855d.tar.bz2 yuzu-85a60e204413c6855b68e94197be3bbc0c4a855d.tar.lz yuzu-85a60e204413c6855b68e94197be3bbc0c4a855d.tar.xz yuzu-85a60e204413c6855b68e94197be3bbc0c4a855d.tar.zst yuzu-85a60e204413c6855b68e94197be3bbc0c4a855d.zip |
-rw-r--r-- | src/video_core/engines/shader_bytecode.h | 1 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 40 |
2 files changed, 24 insertions, 17 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index cb4db0679..0527fc376 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -142,6 +142,7 @@ enum class PredCondition : u64 { GreaterThan = 4, NotEqual = 5, GreaterEqual = 6, + NotEqualWithNan = 13, // TODO(Subv): Other condition types }; diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 46eaad021..3ef79a5e7 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -719,21 +719,31 @@ private: /** * Returns the comparison string to use to compare two values in the 'set' family of * instructions. - * @params condition The condition used in the 'set'-family instruction. + * @param condition The condition used in the 'set'-family instruction. + * @param op_a First operand to use for the comparison. + * @param op_b Second operand to use for the comparison. * @returns String corresponding to the GLSL operator that matches the desired comparison. */ - std::string GetPredicateComparison(Tegra::Shader::PredCondition condition) const { + std::string GetPredicateComparison(Tegra::Shader::PredCondition condition, + const std::string& op_a, const std::string& op_b) const { using Tegra::Shader::PredCondition; static const std::unordered_map<PredCondition, const char*> PredicateComparisonStrings = { - {PredCondition::LessThan, "<"}, {PredCondition::Equal, "=="}, - {PredCondition::LessEqual, "<="}, {PredCondition::GreaterThan, ">"}, - {PredCondition::NotEqual, "!="}, {PredCondition::GreaterEqual, ">="}, + {PredCondition::LessThan, "<"}, {PredCondition::Equal, "=="}, + {PredCondition::LessEqual, "<="}, {PredCondition::GreaterThan, ">"}, + {PredCondition::NotEqual, "!="}, {PredCondition::GreaterEqual, ">="}, + {PredCondition::NotEqualWithNan, "!="}, }; - auto comparison = PredicateComparisonStrings.find(condition); + const auto& comparison{PredicateComparisonStrings.find(condition)}; ASSERT_MSG(comparison != PredicateComparisonStrings.end(), "Unknown predicate comparison operation"); - return comparison->second; + + std::string predicate{'(' + op_a + ") " + comparison->second + " (" + op_b + ')'}; + if (condition == PredCondition::NotEqualWithNan) { + predicate += " || isnan(" + op_a + ") || isnan(" + op_b + ')'; + } + + return predicate; } /** @@ -1415,10 +1425,9 @@ private: std::string second_pred = GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0); - std::string comparator = GetPredicateComparison(instr.fsetp.cond); std::string combiner = GetPredicateCombiner(instr.fsetp.op); - std::string predicate = '(' + op_a + ") " + comparator + " (" + op_b + ')'; + std::string predicate = GetPredicateComparison(instr.fsetp.cond, op_a, op_b); // Set the primary predicate to the result of Predicate OP SecondPredicate SetPredicate(instr.fsetp.pred3, '(' + predicate + ") " + combiner + " (" + second_pred + ')'); @@ -1453,10 +1462,9 @@ private: std::string second_pred = GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0); - std::string comparator = GetPredicateComparison(instr.isetp.cond); std::string combiner = GetPredicateCombiner(instr.isetp.op); - std::string predicate = '(' + op_a + ") " + comparator + " (" + op_b + ')'; + std::string predicate = GetPredicateComparison(instr.isetp.cond, op_a, op_b); // Set the primary predicate to the result of Predicate OP SecondPredicate SetPredicate(instr.isetp.pred3, '(' + predicate + ") " + combiner + " (" + second_pred + ')'); @@ -1503,11 +1511,10 @@ private: std::string second_pred = GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); - std::string comparator = GetPredicateComparison(instr.fset.cond); std::string combiner = GetPredicateCombiner(instr.fset.op); - std::string predicate = "(((" + op_a + ") " + comparator + " (" + op_b + ")) " + - combiner + " (" + second_pred + "))"; + std::string predicate = "((" + GetPredicateComparison(instr.fset.cond, op_a, op_b) + + ") " + combiner + " (" + second_pred + "))"; if (instr.fset.bf) { regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); @@ -1538,11 +1545,10 @@ private: std::string second_pred = GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0); - std::string comparator = GetPredicateComparison(instr.iset.cond); std::string combiner = GetPredicateCombiner(instr.iset.op); - std::string predicate = "(((" + op_a + ") " + comparator + " (" + op_b + ")) " + - combiner + " (" + second_pred + "))"; + std::string predicate = "((" + GetPredicateComparison(instr.iset.cond, op_a, op_b) + + ") " + combiner + " (" + second_pred + "))"; if (instr.iset.bf) { regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); |