diff options
| author | 2018-05-24 17:28:54 -0500 | |
|---|---|---|
| committer | 2018-05-24 17:39:59 -0500 | |
| commit | e2cdf541772366fea6e94ec6309a4798ce06354b (patch) | |
| tree | 4795f8b2462c8adf908afe5babffbb5481c60135 /src | |
| parent | Shader: Implemented compound predicates in fsetp. (diff) | |
| download | yuzu-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.cpp | 40 |
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: { |