summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/shader_bytecode.h1
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp40
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 {
142 GreaterThan = 4, 142 GreaterThan = 4,
143 NotEqual = 5, 143 NotEqual = 5,
144 GreaterEqual = 6, 144 GreaterEqual = 6,
145 NotEqualWithNan = 13,
145 // TODO(Subv): Other condition types 146 // TODO(Subv): Other condition types
146}; 147};
147 148
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:
719 /** 719 /**
720 * Returns the comparison string to use to compare two values in the 'set' family of 720 * Returns the comparison string to use to compare two values in the 'set' family of
721 * instructions. 721 * instructions.
722 * @params condition The condition used in the 'set'-family instruction. 722 * @param condition The condition used in the 'set'-family instruction.
723 * @param op_a First operand to use for the comparison.
724 * @param op_b Second operand to use for the comparison.
723 * @returns String corresponding to the GLSL operator that matches the desired comparison. 725 * @returns String corresponding to the GLSL operator that matches the desired comparison.
724 */ 726 */
725 std::string GetPredicateComparison(Tegra::Shader::PredCondition condition) const { 727 std::string GetPredicateComparison(Tegra::Shader::PredCondition condition,
728 const std::string& op_a, const std::string& op_b) const {
726 using Tegra::Shader::PredCondition; 729 using Tegra::Shader::PredCondition;
727 static const std::unordered_map<PredCondition, const char*> PredicateComparisonStrings = { 730 static const std::unordered_map<PredCondition, const char*> PredicateComparisonStrings = {
728 {PredCondition::LessThan, "<"}, {PredCondition::Equal, "=="}, 731 {PredCondition::LessThan, "<"}, {PredCondition::Equal, "=="},
729 {PredCondition::LessEqual, "<="}, {PredCondition::GreaterThan, ">"}, 732 {PredCondition::LessEqual, "<="}, {PredCondition::GreaterThan, ">"},
730 {PredCondition::NotEqual, "!="}, {PredCondition::GreaterEqual, ">="}, 733 {PredCondition::NotEqual, "!="}, {PredCondition::GreaterEqual, ">="},
734 {PredCondition::NotEqualWithNan, "!="},
731 }; 735 };
732 736
733 auto comparison = PredicateComparisonStrings.find(condition); 737 const auto& comparison{PredicateComparisonStrings.find(condition)};
734 ASSERT_MSG(comparison != PredicateComparisonStrings.end(), 738 ASSERT_MSG(comparison != PredicateComparisonStrings.end(),
735 "Unknown predicate comparison operation"); 739 "Unknown predicate comparison operation");
736 return comparison->second; 740
741 std::string predicate{'(' + op_a + ") " + comparison->second + " (" + op_b + ')'};
742 if (condition == PredCondition::NotEqualWithNan) {
743 predicate += " || isnan(" + op_a + ") || isnan(" + op_b + ')';
744 }
745
746 return predicate;
737 } 747 }
738 748
739 /** 749 /**
@@ -1415,10 +1425,9 @@ private:
1415 std::string second_pred = 1425 std::string second_pred =
1416 GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0); 1426 GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0);
1417 1427
1418 std::string comparator = GetPredicateComparison(instr.fsetp.cond);
1419 std::string combiner = GetPredicateCombiner(instr.fsetp.op); 1428 std::string combiner = GetPredicateCombiner(instr.fsetp.op);
1420 1429
1421 std::string predicate = '(' + op_a + ") " + comparator + " (" + op_b + ')'; 1430 std::string predicate = GetPredicateComparison(instr.fsetp.cond, op_a, op_b);
1422 // Set the primary predicate to the result of Predicate OP SecondPredicate 1431 // Set the primary predicate to the result of Predicate OP SecondPredicate
1423 SetPredicate(instr.fsetp.pred3, 1432 SetPredicate(instr.fsetp.pred3,
1424 '(' + predicate + ") " + combiner + " (" + second_pred + ')'); 1433 '(' + predicate + ") " + combiner + " (" + second_pred + ')');
@@ -1453,10 +1462,9 @@ private:
1453 std::string second_pred = 1462 std::string second_pred =
1454 GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0); 1463 GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0);
1455 1464
1456 std::string comparator = GetPredicateComparison(instr.isetp.cond);
1457 std::string combiner = GetPredicateCombiner(instr.isetp.op); 1465 std::string combiner = GetPredicateCombiner(instr.isetp.op);
1458 1466
1459 std::string predicate = '(' + op_a + ") " + comparator + " (" + op_b + ')'; 1467 std::string predicate = GetPredicateComparison(instr.isetp.cond, op_a, op_b);
1460 // Set the primary predicate to the result of Predicate OP SecondPredicate 1468 // Set the primary predicate to the result of Predicate OP SecondPredicate
1461 SetPredicate(instr.isetp.pred3, 1469 SetPredicate(instr.isetp.pred3,
1462 '(' + predicate + ") " + combiner + " (" + second_pred + ')'); 1470 '(' + predicate + ") " + combiner + " (" + second_pred + ')');
@@ -1503,11 +1511,10 @@ private:
1503 std::string second_pred = 1511 std::string second_pred =
1504 GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); 1512 GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0);
1505 1513
1506 std::string comparator = GetPredicateComparison(instr.fset.cond);
1507 std::string combiner = GetPredicateCombiner(instr.fset.op); 1514 std::string combiner = GetPredicateCombiner(instr.fset.op);
1508 1515
1509 std::string predicate = "(((" + op_a + ") " + comparator + " (" + op_b + ")) " + 1516 std::string predicate = "((" + GetPredicateComparison(instr.fset.cond, op_a, op_b) +
1510 combiner + " (" + second_pred + "))"; 1517 ") " + combiner + " (" + second_pred + "))";
1511 1518
1512 if (instr.fset.bf) { 1519 if (instr.fset.bf) {
1513 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); 1520 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1);
@@ -1538,11 +1545,10 @@ private:
1538 std::string second_pred = 1545 std::string second_pred =
1539 GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0); 1546 GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0);
1540 1547
1541 std::string comparator = GetPredicateComparison(instr.iset.cond);
1542 std::string combiner = GetPredicateCombiner(instr.iset.op); 1548 std::string combiner = GetPredicateCombiner(instr.iset.op);
1543 1549
1544 std::string predicate = "(((" + op_a + ") " + comparator + " (" + op_b + ")) " + 1550 std::string predicate = "((" + GetPredicateComparison(instr.iset.cond, op_a, op_b) +
1545 combiner + " (" + second_pred + "))"; 1551 ") " + combiner + " (" + second_pred + "))";
1546 1552
1547 if (instr.iset.bf) { 1553 if (instr.iset.bf) {
1548 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); 1554 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1);