summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2018-05-24 17:28:54 -0500
committerGravatar Subv2018-05-24 17:39:59 -0500
commite2cdf541772366fea6e94ec6309a4798ce06354b (patch)
tree4795f8b2462c8adf908afe5babffbb5481c60135 /src
parentShader: Implemented compound predicates in fsetp. (diff)
downloadyuzu-e2cdf541772366fea6e94ec6309a4798ce06354b.tar.gz
yuzu-e2cdf541772366fea6e94ec6309a4798ce06354b.tar.xz
yuzu-e2cdf541772366fea6e94ec6309a4798ce06354b.zip
Shader: Implemented compound predicates in fset.
You can specify a predicate in the fset instruction: Result = ((Value1 Comp Value2) OP P0) ? 1.0 : 0.0;
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp40
1 files changed, 12 insertions, 28 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 434bbade6..d24b1ab44 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -609,6 +609,7 @@ private:
609 {PredCondition::LessThan, "<"}, 609 {PredCondition::LessThan, "<"},
610 {PredCondition::Equal, "=="}, 610 {PredCondition::Equal, "=="},
611 {PredCondition::LessEqual, "<="}, 611 {PredCondition::LessEqual, "<="},
612 {PredCondition::GreaterThan, ">"},
612 }; 613 };
613 614
614 auto comparison = PredicateComparisonStrings.find(condition); 615 auto comparison = PredicateComparisonStrings.find(condition);
@@ -628,7 +629,7 @@ private:
628 static const std::unordered_map<PredOperation, const char*> PredicateOperationStrings = { 629 static const std::unordered_map<PredOperation, const char*> PredicateOperationStrings = {
629 {PredOperation::And, "&&"}, 630 {PredOperation::And, "&&"},
630 {PredOperation::Or, "||"}, 631 {PredOperation::Or, "||"},
631 {PredOperation::Xor, "^"}, 632 {PredOperation::Xor, "^^"},
632 }; 633 };
633 634
634 auto op = PredicateOperationStrings.find(operation); 635 auto op = PredicateOperationStrings.find(operation);
@@ -977,35 +978,18 @@ private:
977 op_b = "abs(" + op_b + ')'; 978 op_b = "abs(" + op_b + ')';
978 } 979 }
979 980
980 using Tegra::Shader::Pred;
981 ASSERT_MSG(instr.fset.pred39 == static_cast<u64>(Pred::UnusedIndex),
982 "Compound predicates are not implemented");
983
984 // The fset instruction sets a register to 1.0 if the condition is true, and to 0 981 // The fset instruction sets a register to 1.0 if the condition is true, and to 0
985 // otherwise. 982 // otherwise.
986 using Tegra::Shader::PredCondition; 983 std::string second_pred =
987 switch (instr.fset.cond) { 984 GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0);
988 case PredCondition::LessThan: 985
989 regs.SetRegisterToFloat(instr.gpr0, 0, 986 std::string comparator = GetPredicateComparison(instr.fset.cond);
990 "((" + op_a + ") < (" + op_b + ")) ? 1.0 : 0", 1, 1); 987 std::string combiner = GetPredicateCombiner(instr.fset.op);
991 break; 988
992 case PredCondition::Equal: 989 std::string predicate = "(((" + op_a + ") " + comparator + " (" + op_b + ")) " +
993 regs.SetRegisterToFloat(instr.gpr0, 0, 990 combiner + " (" + second_pred + "))";
994 "((" + op_a + ") == (" + op_b + ")) ? 1.0 : 0", 1, 1); 991
995 break; 992 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1);
996 case PredCondition::LessEqual:
997 regs.SetRegisterToFloat(instr.gpr0, 0,
998 "((" + op_a + ") <= (" + op_b + ")) ? 1.0 : 0", 1, 1);
999 break;
1000 case PredCondition::GreaterThan:
1001 regs.SetRegisterToFloat(instr.gpr0, 0,
1002 "((" + op_a + ") > (" + op_b + ")) ? 1.0 : 0", 1, 1);
1003 break;
1004 default:
1005 NGLOG_CRITICAL(HW_GPU, "Unhandled predicate condition: {} (a: {}, b: {})",
1006 static_cast<unsigned>(instr.fset.cond.Value()), op_a, op_b);
1007 UNREACHABLE();
1008 }
1009 break; 993 break;
1010 } 994 }
1011 default: { 995 default: {