diff options
| author | 2021-03-21 03:48:40 +0100 | |
|---|---|---|
| committer | 2021-07-22 21:51:23 -0400 | |
| commit | 9e213fd861d264cf79d7a6ed0268a57c87306b9b (patch) | |
| tree | be63773390ec95dbaf349e27db08b98f050d8250 /src/shader_recompiler/frontend | |
| parent | shader: Implement HMUL2 (diff) | |
| download | yuzu-9e213fd861d264cf79d7a6ed0268a57c87306b9b.tar.gz yuzu-9e213fd861d264cf79d7a6ed0268a57c87306b9b.tar.xz yuzu-9e213fd861d264cf79d7a6ed0268a57c87306b9b.zip | |
shader: Implement HSET2
Diffstat (limited to 'src/shader_recompiler/frontend')
4 files changed, 118 insertions, 14 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/maxwell.inc b/src/shader_recompiler/frontend/maxwell/maxwell.inc index f2a2ff331..1b87d04fc 100644 --- a/src/shader_recompiler/frontend/maxwell/maxwell.inc +++ b/src/shader_recompiler/frontend/maxwell/maxwell.inc | |||
| @@ -105,8 +105,8 @@ INST(HMUL2_cbuf, "HMUL2 (cbuf)", "0111 100- 1--- ----") | |||
| 105 | INST(HMUL2_imm, "HMUL2 (imm)", "0111 100- 0--- ----") | 105 | INST(HMUL2_imm, "HMUL2 (imm)", "0111 100- 0--- ----") |
| 106 | INST(HMUL2_32I, "HMUL2_32I", "0010 101- ---- ----") | 106 | INST(HMUL2_32I, "HMUL2_32I", "0010 101- ---- ----") |
| 107 | INST(HSET2_reg, "HSET2 (reg)", "0101 1101 0001 1---") | 107 | INST(HSET2_reg, "HSET2 (reg)", "0101 1101 0001 1---") |
| 108 | INST(HSET2_cbuf, "HSET2 (cbuf)", "0111 1100 1--- ----") | 108 | INST(HSET2_cbuf, "HSET2 (cbuf)", "0111 110- 1--- ----") |
| 109 | INST(HSET2_imm, "HSET2 (imm)", "0111 1100 0--- ----") | 109 | INST(HSET2_imm, "HSET2 (imm)", "0111 110- 0--- ----") |
| 110 | INST(HSETP2_reg, "HSETP2 (reg)", "0101 1101 0010 0---") | 110 | INST(HSETP2_reg, "HSETP2 (reg)", "0101 1101 0010 0---") |
| 111 | INST(HSETP2_cbuf, "HSETP2 (cbuf)", "0111 111- 1--- ----") | 111 | INST(HSETP2_cbuf, "HSETP2 (cbuf)", "0111 111- 1--- ----") |
| 112 | INST(HSETP2_imm, "HSETP2 (imm)", "0111 111- 0--- ----") | 112 | INST(HSETP2_imm, "HSETP2 (imm)", "0111 111- 0--- ----") |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_helper.h b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_helper.h index f26ef0949..24063b2ab 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_helper.h +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_helper.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "common/common_types.h" | 5 | #include "common/common_types.h" |
| 6 | #include "shader_recompiler/exception.h" | 6 | #include "shader_recompiler/exception.h" |
| 7 | #include "shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h" | 7 | #include "shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h" |
| 8 | #include "shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h" | ||
| 8 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | 9 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" |
| 9 | 10 | ||
| 10 | namespace Shader::Maxwell { | 11 | namespace Shader::Maxwell { |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set.cpp new file mode 100644 index 000000000..4825ca06a --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/half_floating_point_set.cpp | |||
| @@ -0,0 +1,115 @@ | |||
| 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 HSET2(TranslatorVisitor& v, u64 insn, const IR::U32& src_b, bool bf, bool ftz, bool neg_b, | ||
| 10 | bool abs_b, FPCompareOp compare_op, Swizzle swizzle_b) { | ||
| 11 | union { | ||
| 12 | u64 insn; | ||
| 13 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 14 | BitField<8, 8, IR::Reg> src_a_reg; | ||
| 15 | BitField<39, 3, IR::Pred> pred; | ||
| 16 | BitField<42, 1, u64> neg_pred; | ||
| 17 | BitField<43, 1, u64> neg_a; | ||
| 18 | BitField<45, 2, BooleanOp> bop; | ||
| 19 | BitField<44, 1, u64> abs_a; | ||
| 20 | BitField<47, 2, Swizzle> swizzle_a; | ||
| 21 | } const hset2{insn}; | ||
| 22 | |||
| 23 | auto [lhs_a, rhs_a]{Extract(v.ir, v.X(hset2.src_a_reg), hset2.swizzle_a)}; | ||
| 24 | auto [lhs_b, rhs_b]{Extract(v.ir, src_b, swizzle_b)}; | ||
| 25 | // TODO: Implement FP16 FloatingPointCompare | ||
| 26 | //if (lhs_a.Type() != lhs_b.Type()) { | ||
| 27 | if (lhs_a.Type() == IR::Type::F16) { | ||
| 28 | lhs_a = v.ir.FPConvert(32, lhs_a); | ||
| 29 | rhs_a = v.ir.FPConvert(32, rhs_a); | ||
| 30 | } | ||
| 31 | if (lhs_b.Type() == IR::Type::F16) { | ||
| 32 | lhs_b = v.ir.FPConvert(32, lhs_b); | ||
| 33 | rhs_b = v.ir.FPConvert(32, rhs_b); | ||
| 34 | } | ||
| 35 | //} | ||
| 36 | |||
| 37 | lhs_a = v.ir.FPAbsNeg(lhs_a, hset2.abs_a != 0, hset2.neg_a != 0); | ||
| 38 | rhs_a = v.ir.FPAbsNeg(rhs_a, hset2.abs_a != 0, hset2.neg_a != 0); | ||
| 39 | |||
| 40 | lhs_b = v.ir.FPAbsNeg(lhs_b, abs_b, neg_b); | ||
| 41 | rhs_b = v.ir.FPAbsNeg(rhs_b, abs_b, neg_b); | ||
| 42 | |||
| 43 | const IR::FpControl control{ | ||
| 44 | .no_contraction{false}, | ||
| 45 | .rounding{IR::FpRounding::DontCare}, | ||
| 46 | .fmz_mode{ftz ? IR::FmzMode::FTZ : IR::FmzMode::None}, | ||
| 47 | }; | ||
| 48 | |||
| 49 | IR::U1 pred{v.ir.GetPred(hset2.pred)}; | ||
| 50 | if (hset2.neg_pred != 0) { | ||
| 51 | pred = v.ir.LogicalNot(pred); | ||
| 52 | } | ||
| 53 | const IR::U1 cmp_result_lhs{FloatingPointCompare(v.ir, lhs_a, lhs_b, compare_op, control)}; | ||
| 54 | const IR::U1 cmp_result_rhs{FloatingPointCompare(v.ir, rhs_a, rhs_b, compare_op, control)}; | ||
| 55 | const IR::U1 bop_result_lhs{PredicateCombine(v.ir, cmp_result_lhs, pred, hset2.bop)}; | ||
| 56 | const IR::U1 bop_result_rhs{PredicateCombine(v.ir, cmp_result_rhs, pred, hset2.bop)}; | ||
| 57 | |||
| 58 | const u32 true_value = bf ? 0x3c00 : 0xffff; | ||
| 59 | const IR::U32 true_val_lhs{v.ir.Imm32(true_value)}; | ||
| 60 | const IR::U32 true_val_rhs{v.ir.Imm32(true_value << 16)}; | ||
| 61 | const IR::U32 fail_result{v.ir.Imm32(0)}; | ||
| 62 | const IR::U32 result_lhs{v.ir.Select(bop_result_lhs, true_val_lhs, fail_result)}; | ||
| 63 | const IR::U32 result_rhs{v.ir.Select(bop_result_rhs, true_val_rhs, fail_result)}; | ||
| 64 | |||
| 65 | v.X(hset2.dest_reg, IR::U32{v.ir.BitwiseOr(result_lhs, result_rhs)}); | ||
| 66 | } | ||
| 67 | } // Anonymous namespace | ||
| 68 | |||
| 69 | void TranslatorVisitor::HSET2_reg(u64 insn) { | ||
| 70 | union { | ||
| 71 | u64 insn; | ||
| 72 | BitField<30, 1, u64> abs_b; | ||
| 73 | BitField<49, 1, u64> bf; | ||
| 74 | BitField<31, 1, u64> neg_b; | ||
| 75 | BitField<50, 1, u64> ftz; | ||
| 76 | BitField<35, 4, FPCompareOp> compare_op; | ||
| 77 | BitField<28, 2, Swizzle> swizzle_b; | ||
| 78 | } const hset2{insn}; | ||
| 79 | HSET2(*this, insn, GetReg20(insn), hset2.bf != 0, hset2.ftz != 0, hset2.neg_b != 0, | ||
| 80 | hset2.abs_b != 0, hset2.compare_op, hset2.swizzle_b); | ||
| 81 | } | ||
| 82 | |||
| 83 | void TranslatorVisitor::HSET2_cbuf(u64 insn) { | ||
| 84 | union { | ||
| 85 | u64 insn; | ||
| 86 | BitField<53, 1, u64> bf; | ||
| 87 | BitField<56, 1, u64> neg_b; | ||
| 88 | BitField<54, 1, u64> ftz; | ||
| 89 | BitField<49, 4, FPCompareOp> compare_op; | ||
| 90 | } const hset2{insn}; | ||
| 91 | |||
| 92 | HSET2(*this, insn, GetCbuf(insn), hset2.bf != 0, hset2.ftz != 0, hset2.neg_b != 0, false, | ||
| 93 | hset2.compare_op, Swizzle::F32); | ||
| 94 | } | ||
| 95 | |||
| 96 | void TranslatorVisitor::HSET2_imm(u64 insn) { | ||
| 97 | union { | ||
| 98 | u64 insn; | ||
| 99 | BitField<53, 1, u64> bf; | ||
| 100 | BitField<54, 1, u64> ftz; | ||
| 101 | BitField<49, 4, FPCompareOp> compare_op; | ||
| 102 | BitField<56, 1, u64> neg_high; | ||
| 103 | BitField<30, 9, u64> high; | ||
| 104 | BitField<29, 1, u64> neg_low; | ||
| 105 | BitField<20, 9, u64> low; | ||
| 106 | } const hset2{insn}; | ||
| 107 | |||
| 108 | const u32 imm{static_cast<u32>(hset2.low << 6) | ((hset2.neg_low != 0 ? 1 : 0) << 15) | | ||
| 109 | static_cast<u32>(hset2.high << 22) | ((hset2.neg_high != 0 ? 1 : 0) << 31)}; | ||
| 110 | |||
| 111 | HSET2(*this, insn, ir.Imm32(imm), hset2.bf != 0, hset2.ftz != 0, false, false, | ||
| 112 | hset2.compare_op, Swizzle::H1_H0); | ||
| 113 | } | ||
| 114 | |||
| 115 | } // 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 6c159301f..d1aeceef1 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::HSET2_reg(u64) { | ||
| 185 | ThrowNotImplemented(Opcode::HSET2_reg); | ||
| 186 | } | ||
| 187 | |||
| 188 | void TranslatorVisitor::HSET2_cbuf(u64) { | ||
| 189 | ThrowNotImplemented(Opcode::HSET2_cbuf); | ||
| 190 | } | ||
| 191 | |||
| 192 | void TranslatorVisitor::HSET2_imm(u64) { | ||
| 193 | ThrowNotImplemented(Opcode::HSET2_imm); | ||
| 194 | } | ||
| 195 | |||
| 196 | void TranslatorVisitor::HSETP2_reg(u64) { | 184 | void TranslatorVisitor::HSETP2_reg(u64) { |
| 197 | ThrowNotImplemented(Opcode::HSETP2_reg); | 185 | ThrowNotImplemented(Opcode::HSETP2_reg); |
| 198 | } | 186 | } |