diff options
Diffstat (limited to 'src/shader_recompiler')
3 files changed, 117 insertions, 12 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index eebca982b..87654931b 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt | |||
| @@ -82,6 +82,7 @@ add_library(shader_recompiler STATIC | |||
| 82 | frontend/maxwell/translate/impl/half_floating_point_helper.cpp | 82 | frontend/maxwell/translate/impl/half_floating_point_helper.cpp |
| 83 | frontend/maxwell/translate/impl/half_floating_point_helper.h | 83 | frontend/maxwell/translate/impl/half_floating_point_helper.h |
| 84 | frontend/maxwell/translate/impl/half_floating_point_multiply.cpp | 84 | frontend/maxwell/translate/impl/half_floating_point_multiply.cpp |
| 85 | frontend/maxwell/translate/impl/half_floating_point_set_predicate.cpp | ||
| 85 | frontend/maxwell/translate/impl/half_floating_point_set.cpp | 86 | frontend/maxwell/translate/impl/half_floating_point_set.cpp |
| 86 | frontend/maxwell/translate/impl/impl.cpp | 87 | frontend/maxwell/translate/impl/impl.cpp |
| 87 | frontend/maxwell/translate/impl/impl.h | 88 | frontend/maxwell/translate/impl/impl.h |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set_predicate.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set_predicate.cpp new file mode 100644 index 000000000..6b1ac21d5 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set_predicate.cpp | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_helper.h" | ||
| 6 | |||
| 7 | namespace Shader::Maxwell { | ||
| 8 | namespace { | ||
| 9 | void HSETP2(TranslatorVisitor& v, u64 insn, const IR::U32& src_b, bool neg_b, bool abs_b, | ||
| 10 | Swizzle swizzle_b, FPCompareOp compare_op, bool h_and) { | ||
| 11 | union { | ||
| 12 | u64 insn; | ||
| 13 | BitField<8, 8, IR::Reg> src_a_reg; | ||
| 14 | BitField<3, 3, IR::Pred> dest_pred_a; | ||
| 15 | BitField<0, 3, IR::Pred> dest_pred_b; | ||
| 16 | BitField<39, 3, IR::Pred> pred; | ||
| 17 | BitField<42, 1, u64> neg_pred; | ||
| 18 | BitField<43, 1, u64> neg_a; | ||
| 19 | BitField<45, 2, BooleanOp> bop; | ||
| 20 | BitField<44, 1, u64> abs_a; | ||
| 21 | BitField<6, 1, u64> ftz; | ||
| 22 | BitField<47, 2, Swizzle> swizzle_a; | ||
| 23 | } const hsetp2{insn}; | ||
| 24 | |||
| 25 | auto [lhs_a, rhs_a]{Extract(v.ir, v.X(hsetp2.src_a_reg), hsetp2.swizzle_a)}; | ||
| 26 | auto [lhs_b, rhs_b]{Extract(v.ir, src_b, swizzle_b)}; | ||
| 27 | // TODO: Implement FP16 FloatingPointCompare | ||
| 28 | // if (lhs_a.Type() != lhs_b.Type()) { | ||
| 29 | if (lhs_a.Type() == IR::Type::F16) { | ||
| 30 | lhs_a = v.ir.FPConvert(32, lhs_a); | ||
| 31 | rhs_a = v.ir.FPConvert(32, rhs_a); | ||
| 32 | } | ||
| 33 | if (lhs_b.Type() == IR::Type::F16) { | ||
| 34 | lhs_b = v.ir.FPConvert(32, lhs_b); | ||
| 35 | rhs_b = v.ir.FPConvert(32, rhs_b); | ||
| 36 | } | ||
| 37 | //} | ||
| 38 | |||
| 39 | lhs_a = v.ir.FPAbsNeg(lhs_a, hsetp2.abs_a != 0, hsetp2.neg_a != 0); | ||
| 40 | rhs_a = v.ir.FPAbsNeg(rhs_a, hsetp2.abs_a != 0, hsetp2.neg_a != 0); | ||
| 41 | |||
| 42 | lhs_b = v.ir.FPAbsNeg(lhs_b, abs_b, neg_b); | ||
| 43 | rhs_b = v.ir.FPAbsNeg(rhs_b, abs_b, neg_b); | ||
| 44 | |||
| 45 | const IR::FpControl control{ | ||
| 46 | .no_contraction{false}, | ||
| 47 | .rounding{IR::FpRounding::DontCare}, | ||
| 48 | .fmz_mode{hsetp2.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None}, | ||
| 49 | }; | ||
| 50 | |||
| 51 | IR::U1 pred{v.ir.GetPred(hsetp2.pred)}; | ||
| 52 | if (hsetp2.neg_pred != 0) { | ||
| 53 | pred = v.ir.LogicalNot(pred); | ||
| 54 | } | ||
| 55 | const IR::U1 cmp_result_lhs{FloatingPointCompare(v.ir, lhs_a, lhs_b, compare_op, control)}; | ||
| 56 | const IR::U1 cmp_result_rhs{FloatingPointCompare(v.ir, rhs_a, rhs_b, compare_op, control)}; | ||
| 57 | const IR::U1 bop_result_lhs{PredicateCombine(v.ir, cmp_result_lhs, pred, hsetp2.bop)}; | ||
| 58 | const IR::U1 bop_result_rhs{PredicateCombine(v.ir, cmp_result_rhs, pred, hsetp2.bop)}; | ||
| 59 | |||
| 60 | if (h_and) { | ||
| 61 | auto result = v.ir.LogicalAnd(bop_result_lhs, bop_result_rhs); | ||
| 62 | v.ir.SetPred(hsetp2.dest_pred_a, result); | ||
| 63 | v.ir.SetPred(hsetp2.dest_pred_b, v.ir.LogicalNot(result)); | ||
| 64 | } else { | ||
| 65 | v.ir.SetPred(hsetp2.dest_pred_a, bop_result_lhs); | ||
| 66 | v.ir.SetPred(hsetp2.dest_pred_b, bop_result_rhs); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | } // Anonymous namespace | ||
| 70 | |||
| 71 | void TranslatorVisitor::HSETP2_reg(u64 insn) { | ||
| 72 | union { | ||
| 73 | u64 insn; | ||
| 74 | BitField<30, 1, u64> abs_b; | ||
| 75 | BitField<49, 1, u64> h_and; | ||
| 76 | BitField<31, 1, u64> neg_b; | ||
| 77 | BitField<35, 4, FPCompareOp> compare_op; | ||
| 78 | BitField<28, 2, Swizzle> swizzle_b; | ||
| 79 | } const hsetp2{insn}; | ||
| 80 | HSETP2(*this, insn, GetReg20(insn), hsetp2.neg_b != 0, hsetp2.abs_b != 0, hsetp2.swizzle_b, | ||
| 81 | hsetp2.compare_op, hsetp2.h_and != 0); | ||
| 82 | } | ||
| 83 | |||
| 84 | void TranslatorVisitor::HSETP2_cbuf(u64 insn) { | ||
| 85 | union { | ||
| 86 | u64 insn; | ||
| 87 | BitField<53, 1, u64> h_and; | ||
| 88 | BitField<54, 1, u64> abs_b; | ||
| 89 | BitField<56, 1, u64> neg_b; | ||
| 90 | BitField<49, 4, FPCompareOp> compare_op; | ||
| 91 | } const hsetp2{insn}; | ||
| 92 | |||
| 93 | HSETP2(*this, insn, GetCbuf(insn), hsetp2.neg_b != 0, hsetp2.abs_b != 0, Swizzle::F32, | ||
| 94 | hsetp2.compare_op, hsetp2.h_and != 0); | ||
| 95 | } | ||
| 96 | |||
| 97 | void TranslatorVisitor::HSETP2_imm(u64 insn) { | ||
| 98 | union { | ||
| 99 | u64 insn; | ||
| 100 | BitField<53, 1, u64> h_and; | ||
| 101 | BitField<54, 1, u64> ftz; | ||
| 102 | BitField<49, 4, FPCompareOp> compare_op; | ||
| 103 | BitField<56, 1, u64> neg_high; | ||
| 104 | BitField<30, 9, u64> high; | ||
| 105 | BitField<29, 1, u64> neg_low; | ||
| 106 | BitField<20, 9, u64> low; | ||
| 107 | } const hsetp2{insn}; | ||
| 108 | |||
| 109 | const u32 imm{static_cast<u32>(hsetp2.low << 6) | ((hsetp2.neg_low != 0 ? 1 : 0) << 15) | | ||
| 110 | static_cast<u32>(hsetp2.high << 22) | ((hsetp2.neg_high != 0 ? 1 : 0) << 31)}; | ||
| 111 | |||
| 112 | HSETP2(*this, insn, ir.Imm32(imm), false, false, Swizzle::H1_H0, hsetp2.compare_op, | ||
| 113 | hsetp2.h_and != 0); | ||
| 114 | } | ||
| 115 | |||
| 116 | } // namespace Shader::Maxwell | ||
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp index d1aeceef1..bd3c1f9d6 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | |||
| @@ -181,18 +181,6 @@ void TranslatorVisitor::GETLMEMBASE(u64) { | |||
| 181 | ThrowNotImplemented(Opcode::GETLMEMBASE); | 181 | ThrowNotImplemented(Opcode::GETLMEMBASE); |
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | void TranslatorVisitor::HSETP2_reg(u64) { | ||
| 185 | ThrowNotImplemented(Opcode::HSETP2_reg); | ||
| 186 | } | ||
| 187 | |||
| 188 | void TranslatorVisitor::HSETP2_cbuf(u64) { | ||
| 189 | ThrowNotImplemented(Opcode::HSETP2_cbuf); | ||
| 190 | } | ||
| 191 | |||
| 192 | void TranslatorVisitor::HSETP2_imm(u64) { | ||
| 193 | ThrowNotImplemented(Opcode::HSETP2_imm); | ||
| 194 | } | ||
| 195 | |||
| 196 | void TranslatorVisitor::IDE(u64) { | 184 | void TranslatorVisitor::IDE(u64) { |
| 197 | ThrowNotImplemented(Opcode::IDE); | 185 | ThrowNotImplemented(Opcode::IDE); |
| 198 | } | 186 | } |