diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 20 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 45 |
2 files changed, 65 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 23bfd8988..a6e764ea4 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -801,6 +801,23 @@ union Instruction { | |||
| 801 | } csetp; | 801 | } csetp; |
| 802 | 802 | ||
| 803 | union { | 803 | union { |
| 804 | BitField<35, 4, PredCondition> cond; | ||
| 805 | BitField<49, 1, u64> h_and; | ||
| 806 | BitField<6, 1, u64> ftz; | ||
| 807 | BitField<45, 2, PredOperation> op; | ||
| 808 | BitField<3, 3, u64> pred3; | ||
| 809 | BitField<0, 3, u64> pred0; | ||
| 810 | BitField<43, 1, u64> negate_a; | ||
| 811 | BitField<44, 1, u64> abs_a; | ||
| 812 | BitField<47, 2, HalfType> type_a; | ||
| 813 | BitField<31, 1, u64> negate_b; | ||
| 814 | BitField<30, 1, u64> abs_b; | ||
| 815 | BitField<28, 2, HalfType> type_b; | ||
| 816 | BitField<42, 1, u64> neg_pred; | ||
| 817 | BitField<39, 3, u64> pred39; | ||
| 818 | } hsetp2; | ||
| 819 | |||
| 820 | union { | ||
| 804 | BitField<39, 3, u64> pred39; | 821 | BitField<39, 3, u64> pred39; |
| 805 | BitField<42, 1, u64> neg_pred; | 822 | BitField<42, 1, u64> neg_pred; |
| 806 | BitField<43, 1, u64> neg_a; | 823 | BitField<43, 1, u64> neg_a; |
| @@ -1239,6 +1256,7 @@ public: | |||
| 1239 | HFMA2_RC, | 1256 | HFMA2_RC, |
| 1240 | HFMA2_RR, | 1257 | HFMA2_RR, |
| 1241 | HFMA2_IMM_R, | 1258 | HFMA2_IMM_R, |
| 1259 | HSETP2_R, | ||
| 1242 | POPC_C, | 1260 | POPC_C, |
| 1243 | POPC_R, | 1261 | POPC_R, |
| 1244 | POPC_IMM, | 1262 | POPC_IMM, |
| @@ -1325,6 +1343,7 @@ public: | |||
| 1325 | FloatSetPredicate, | 1343 | FloatSetPredicate, |
| 1326 | IntegerSet, | 1344 | IntegerSet, |
| 1327 | IntegerSetPredicate, | 1345 | IntegerSetPredicate, |
| 1346 | HalfSetPredicate, | ||
| 1328 | PredicateSetPredicate, | 1347 | PredicateSetPredicate, |
| 1329 | PredicateSetRegister, | 1348 | PredicateSetRegister, |
| 1330 | Conversion, | 1349 | Conversion, |
| @@ -1496,6 +1515,7 @@ private: | |||
| 1496 | INST("01100---1-------", Id::HFMA2_RC, Type::Hfma2, "HFMA2_RC"), | 1515 | INST("01100---1-------", Id::HFMA2_RC, Type::Hfma2, "HFMA2_RC"), |
| 1497 | INST("0101110100000---", Id::HFMA2_RR, Type::Hfma2, "HFMA2_RR"), | 1516 | INST("0101110100000---", Id::HFMA2_RR, Type::Hfma2, "HFMA2_RR"), |
| 1498 | INST("01110---0-------", Id::HFMA2_IMM_R, Type::Hfma2, "HFMA2_R_IMM"), | 1517 | INST("01110---0-------", Id::HFMA2_IMM_R, Type::Hfma2, "HFMA2_R_IMM"), |
| 1518 | INST("0101110100100---", Id::HSETP2_R, Type::HalfSetPredicate, "HSETP_R"), | ||
| 1499 | INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), | 1519 | INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), |
| 1500 | INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), | 1520 | INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), |
| 1501 | INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), | 1521 | INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index ca2030e97..06f85fad2 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -2791,6 +2791,51 @@ private: | |||
| 2791 | } | 2791 | } |
| 2792 | break; | 2792 | break; |
| 2793 | } | 2793 | } |
| 2794 | case OpCode::Type::HalfSetPredicate: { | ||
| 2795 | ASSERT_MSG(instr.hsetp2.ftz == 0, "Unimplemented"); | ||
| 2796 | |||
| 2797 | const std::string op_a = | ||
| 2798 | GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hsetp2.type_a, | ||
| 2799 | instr.hsetp2.abs_a, instr.hsetp2.negate_a); | ||
| 2800 | |||
| 2801 | const std::string op_b = [&]() { | ||
| 2802 | switch (opcode->GetId()) { | ||
| 2803 | case OpCode::Id::HSETP2_R: | ||
| 2804 | return GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false), | ||
| 2805 | instr.hsetp2.type_b, instr.hsetp2.abs_a, | ||
| 2806 | instr.hsetp2.negate_b); | ||
| 2807 | default: | ||
| 2808 | UNREACHABLE(); | ||
| 2809 | return std::string("vec2(0)"); | ||
| 2810 | } | ||
| 2811 | }(); | ||
| 2812 | |||
| 2813 | // We can't use the constant predicate as destination. | ||
| 2814 | ASSERT(instr.hsetp2.pred3 != static_cast<u64>(Pred::UnusedIndex)); | ||
| 2815 | |||
| 2816 | const std::string second_pred = | ||
| 2817 | GetPredicateCondition(instr.hsetp2.pred39, instr.hsetp2.neg_pred != 0); | ||
| 2818 | |||
| 2819 | const std::string combiner = GetPredicateCombiner(instr.hsetp2.op); | ||
| 2820 | |||
| 2821 | const std::string component_combiner = instr.hsetp2.h_and ? "&&" : "||"; | ||
| 2822 | const std::string predicate = | ||
| 2823 | '(' + GetPredicateComparison(instr.hsetp2.cond, op_a + ".x", op_b + ".x") + ' ' + | ||
| 2824 | component_combiner + ' ' + | ||
| 2825 | GetPredicateComparison(instr.hsetp2.cond, op_a + ".y", op_b + ".y") + ')'; | ||
| 2826 | |||
| 2827 | // Set the primary predicate to the result of Predicate OP SecondPredicate | ||
| 2828 | SetPredicate(instr.hsetp2.pred3, | ||
| 2829 | '(' + predicate + ") " + combiner + " (" + second_pred + ')'); | ||
| 2830 | |||
| 2831 | if (instr.hsetp2.pred0 != static_cast<u64>(Pred::UnusedIndex)) { | ||
| 2832 | // Set the secondary predicate to the result of !Predicate OP SecondPredicate, | ||
| 2833 | // if enabled | ||
| 2834 | SetPredicate(instr.hsetp2.pred0, | ||
| 2835 | "!(" + predicate + ") " + combiner + " (" + second_pred + ')'); | ||
| 2836 | } | ||
| 2837 | break; | ||
| 2838 | } | ||
| 2794 | case OpCode::Type::PredicateSetRegister: { | 2839 | case OpCode::Type::PredicateSetRegister: { |
| 2795 | const std::string op_a = | 2840 | const std::string op_a = |
| 2796 | GetPredicateCondition(instr.pset.pred12, instr.pset.neg_pred12 != 0); | 2841 | GetPredicateCondition(instr.pset.pred12, instr.pset.neg_pred12 != 0); |