summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-02-23 04:46:39 -0300
committerGravatar ameerj2021-07-22 21:51:22 -0400
commit9d6a98d950da39dd2a7ca5ad25525de4fb825415 (patch)
treeed7374adf60d5330f78d48f0ccea65fd65702fac
parentshader: FMUL, select, RRO, and MUFU fixes (diff)
downloadyuzu-9d6a98d950da39dd2a7ca5ad25525de4fb825415.tar.gz
yuzu-9d6a98d950da39dd2a7ca5ad25525de4fb825415.tar.xz
yuzu-9d6a98d950da39dd2a7ca5ad25525de4fb825415.zip
shader: Implement more of XMAD and FFMA32I and fix XMAD.CBCC
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h4
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp8
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp41
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_short_multiply_add.cpp49
5 files changed, 76 insertions, 28 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index 130c71996..4b74cf04d 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -224,8 +224,8 @@ void EmitShiftRightArithmetic32(EmitContext& ctx);
224Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b); 224Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b);
225Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b); 225Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b);
226Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b); 226Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b);
227void EmitBitFieldInsert(EmitContext& ctx); 227Id EmitBitFieldInsert(EmitContext& ctx, Id base, Id insert, Id offset, Id count);
228void EmitBitFieldSExtract(EmitContext& ctx); 228Id EmitBitFieldSExtract(EmitContext& ctx, Id base, Id offset, Id count);
229Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count); 229Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count);
230Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs); 230Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs);
231Id EmitULessThan(EmitContext& ctx, Id lhs, Id rhs); 231Id EmitULessThan(EmitContext& ctx, Id lhs, Id rhs);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
index 329dcb351..8aaa0e381 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
@@ -90,12 +90,12 @@ Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b) {
90 return ctx.OpBitwiseXor(ctx.U32[1], a, b); 90 return ctx.OpBitwiseXor(ctx.U32[1], a, b);
91} 91}
92 92
93void EmitBitFieldInsert(EmitContext&) { 93Id EmitBitFieldInsert(EmitContext& ctx, Id base, Id insert, Id offset, Id count) {
94 throw NotImplementedException("SPIR-V Instruction"); 94 return ctx.OpBitFieldInsert(ctx.U32[1], base, insert, offset, count);
95} 95}
96 96
97void EmitBitFieldSExtract(EmitContext&) { 97Id EmitBitFieldSExtract(EmitContext& ctx, Id base, Id offset, Id count) {
98 throw NotImplementedException("SPIR-V Instruction"); 98 return ctx.OpBitFieldSExtract(ctx.U32[1], base, offset, count);
99} 99}
100 100
101Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count) { 101Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp
index c2ca0873b..18561bc9c 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp
@@ -17,9 +17,6 @@ void FFMA(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, const IR::F32& s
17 BitField<8, 8, IR::Reg> src_a; 17 BitField<8, 8, IR::Reg> src_a;
18 } const ffma{insn}; 18 } const ffma{insn};
19 19
20 if (sat) {
21 throw NotImplementedException("FFMA SAT");
22 }
23 if (cc) { 20 if (cc) {
24 throw NotImplementedException("FFMA CC"); 21 throw NotImplementedException("FFMA CC");
25 } 22 }
@@ -31,7 +28,20 @@ void FFMA(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, const IR::F32& s
31 .rounding{CastFpRounding(fp_rounding)}, 28 .rounding{CastFpRounding(fp_rounding)},
32 .fmz_mode{CastFmzMode(fmz_mode)}, 29 .fmz_mode{CastFmzMode(fmz_mode)},
33 }; 30 };
34 v.F(ffma.dest_reg, v.ir.FPFma(op_a, op_b, op_c, fp_control)); 31 IR::F32 value{v.ir.FPFma(op_a, op_b, op_c, fp_control)};
32 if (fmz_mode == FmzMode::FMZ && !sat) {
33 // Do not implement FMZ if SAT is enabled, as it does the logic for us.
34 // On D3D9 mode, anything * 0 is zero, even NAN and infinity
35 const IR::F32 zero{v.ir.Imm32(0.0f)};
36 const IR::U1 zero_a{v.ir.FPEqual(op_a, zero)};
37 const IR::U1 zero_b{v.ir.FPEqual(op_b, zero)};
38 const IR::U1 any_zero{v.ir.LogicalOr(zero_a, zero_b)};
39 value = IR::F32{v.ir.Select(any_zero, op_c, value)};
40 }
41 if (sat) {
42 value = v.ir.FPSaturate(value);
43 }
44 v.F(ffma.dest_reg, value);
35} 45}
36 46
37void FFMA(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, const IR::F32& src_c) { 47void FFMA(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, const IR::F32& src_c) {
@@ -54,20 +64,31 @@ void TranslatorVisitor::FFMA_reg(u64 insn) {
54 FFMA(*this, insn, GetFloatReg20(insn), GetFloatReg39(insn)); 64 FFMA(*this, insn, GetFloatReg20(insn), GetFloatReg39(insn));
55} 65}
56 66
57void TranslatorVisitor::FFMA_rc(u64) { 67void TranslatorVisitor::FFMA_rc(u64 insn) {
58 throw NotImplementedException("FFMA (rc)"); 68 FFMA(*this, insn, GetFloatReg39(insn), GetFloatCbuf(insn));
59} 69}
60 70
61void TranslatorVisitor::FFMA_cr(u64 insn) { 71void TranslatorVisitor::FFMA_cr(u64 insn) {
62 FFMA(*this, insn, GetFloatCbuf(insn), GetFloatReg39(insn)); 72 FFMA(*this, insn, GetFloatCbuf(insn), GetFloatReg39(insn));
63} 73}
64 74
65void TranslatorVisitor::FFMA_imm(u64) { 75void TranslatorVisitor::FFMA_imm(u64 insn) {
66 throw NotImplementedException("FFMA (imm)"); 76 FFMA(*this, insn, GetFloatImm20(insn), GetFloatReg39(insn));
67} 77}
68 78
69void TranslatorVisitor::FFMA32I(u64) { 79void TranslatorVisitor::FFMA32I(u64 insn) {
70 throw NotImplementedException("FFMA32I"); 80 union {
81 u64 raw;
82 BitField<0, 8, IR::Reg> src_c; // FFMA32I mirrors the destination and addition register
83 BitField<52, 1, u64> cc;
84 BitField<53, 2, FmzMode> fmz_mode;
85 BitField<55, 1, u64> sat;
86 BitField<56, 1, u64> neg_a;
87 BitField<57, 1, u64> neg_c;
88 } const ffma32i{insn};
89
90 FFMA(*this, insn, GetFloatImm32(insn), F(ffma32i.src_c), ffma32i.neg_a != 0, false,
91 ffma32i.neg_c != 0, ffma32i.sat != 0, ffma32i.cc != 0, ffma32i.fmz_mode, FpRounding::RN);
71} 92}
72 93
73} // namespace Shader::Maxwell 94} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp
index edf2cadae..72f0a18ae 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp
@@ -94,6 +94,7 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
94 BitField<48, 1, u64> neg_b; 94 BitField<48, 1, u64> neg_b;
95 BitField<50, 1, u64> sat; 95 BitField<50, 1, u64> sat;
96 } const fmul{insn}; 96 } const fmul{insn};
97
97 FMUL(v, insn, src_b, fmul.fmz, fmul.fp_rounding, fmul.scale, fmul.sat != 0, fmul.cc != 0, 98 FMUL(v, insn, src_b, fmul.fmz, fmul.fp_rounding, fmul.scale, fmul.sat != 0, fmul.cc != 0,
98 fmul.neg_b != 0); 99 fmul.neg_b != 0);
99} 100}
@@ -118,6 +119,7 @@ void TranslatorVisitor::FMUL32I(u64 insn) {
118 BitField<53, 2, FmzMode> fmz; 119 BitField<53, 2, FmzMode> fmz;
119 BitField<55, 1, u64> sat; 120 BitField<55, 1, u64> sat;
120 } const fmul32i{insn}; 121 } const fmul32i{insn};
122
121 FMUL(*this, insn, GetFloatImm32(insn), fmul32i.fmz, FpRounding::RN, Scale::None, 123 FMUL(*this, insn, GetFloatImm32(insn), fmul32i.fmz, FpRounding::RN, Scale::None,
122 fmul32i.sat != 0, fmul32i.cc != 0, false); 124 fmul32i.sat != 0, fmul32i.cc != 0, false);
123} 125}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_short_multiply_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_short_multiply_add.cpp
index 70a7c76c5..2932cdc42 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_short_multiply_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_short_multiply_add.cpp
@@ -58,7 +58,7 @@ void XMAD(TranslatorVisitor& v, u64 insn, const IR::U32& src_b, const IR::U32& s
58 case SelectMode::CHI: 58 case SelectMode::CHI:
59 return ExtractHalf(v, src_c, Half::H1, false); 59 return ExtractHalf(v, src_c, Half::H1, false);
60 case SelectMode::CBCC: 60 case SelectMode::CBCC:
61 return v.ir.IAdd(v.ir.ShiftLeftLogical(src_b, v.ir.Imm32(16)), src_b); 61 return v.ir.IAdd(v.ir.ShiftLeftLogical(src_b, v.ir.Imm32(16)), src_c);
62 case SelectMode::CSFU: 62 case SelectMode::CSFU:
63 throw NotImplementedException("XMAD CSFU"); 63 throw NotImplementedException("XMAD CSFU");
64 } 64 }
@@ -78,16 +78,44 @@ void XMAD(TranslatorVisitor& v, u64 insn, const IR::U32& src_b, const IR::U32& s
78} 78}
79} // Anonymous namespace 79} // Anonymous namespace
80 80
81void TranslatorVisitor::XMAD_reg(u64) { 81void TranslatorVisitor::XMAD_reg(u64 insn) {
82 throw NotImplementedException("XMAD (reg)"); 82 union {
83 u64 raw;
84 BitField<35, 1, Half> half_b;
85 BitField<36, 1, u64> psl;
86 BitField<37, 1, u64> mrg;
87 BitField<38, 1, u64> x;
88 BitField<50, 3, SelectMode> select_mode;
89 } const xmad{insn};
90
91 XMAD(*this, insn, GetReg20(insn), GetReg39(insn), xmad.select_mode, xmad.half_b, xmad.psl != 0,
92 xmad.mrg != 0, xmad.x != 0);
83} 93}
84 94
85void TranslatorVisitor::XMAD_rc(u64) { 95void TranslatorVisitor::XMAD_rc(u64 insn) {
86 throw NotImplementedException("XMAD (rc)"); 96 union {
97 u64 raw;
98 BitField<50, 2, SelectMode> select_mode;
99 BitField<52, 1, Half> half_b;
100 BitField<54, 1, u64> x;
101 } const xmad{insn};
102
103 XMAD(*this, insn, GetReg39(insn), GetCbuf(insn), xmad.select_mode, xmad.half_b, false, false,
104 xmad.x != 0);
87} 105}
88 106
89void TranslatorVisitor::XMAD_cr(u64) { 107void TranslatorVisitor::XMAD_cr(u64 insn) {
90 throw NotImplementedException("XMAD (cr)"); 108 union {
109 u64 raw;
110 BitField<50, 2, SelectMode> select_mode;
111 BitField<52, 1, Half> half_b;
112 BitField<54, 1, u64> x;
113 BitField<55, 1, u64> psl;
114 BitField<56, 1, u64> mrg;
115 } const xmad{insn};
116
117 XMAD(*this, insn, GetCbuf(insn), GetReg39(insn), xmad.select_mode, xmad.half_b, xmad.psl != 0,
118 xmad.mrg != 0, xmad.x != 0);
91} 119}
92 120
93void TranslatorVisitor::XMAD_imm(u64 insn) { 121void TranslatorVisitor::XMAD_imm(u64 insn) {
@@ -97,14 +125,11 @@ void TranslatorVisitor::XMAD_imm(u64 insn) {
97 BitField<36, 1, u64> psl; 125 BitField<36, 1, u64> psl;
98 BitField<37, 1, u64> mrg; 126 BitField<37, 1, u64> mrg;
99 BitField<38, 1, u64> x; 127 BitField<38, 1, u64> x;
100 BitField<39, 8, IR::Reg> src_c;
101 BitField<50, 3, SelectMode> select_mode; 128 BitField<50, 3, SelectMode> select_mode;
102 } const xmad{insn}; 129 } const xmad{insn};
103 130
104 const IR::U32 src_b{ir.Imm32(static_cast<u32>(xmad.src_b))}; 131 XMAD(*this, insn, ir.Imm32(static_cast<u32>(xmad.src_b)), GetReg39(insn), xmad.select_mode,
105 const IR::U32 src_c{X(xmad.src_c)}; 132 Half::H0, xmad.psl != 0, xmad.mrg != 0, xmad.x != 0);
106 XMAD(*this, insn, src_b, src_c, xmad.select_mode, Half::H0, xmad.psl != 0, xmad.mrg != 0,
107 xmad.x != 0);
108} 133}
109 134
110} // namespace Shader::Maxwell 135} // namespace Shader::Maxwell