diff options
Diffstat (limited to 'src/shader_recompiler')
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); | |||
| 224 | Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b); | 224 | Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b); |
| 225 | Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b); | 225 | Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b); |
| 226 | Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b); | 226 | Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b); |
| 227 | void EmitBitFieldInsert(EmitContext& ctx); | 227 | Id EmitBitFieldInsert(EmitContext& ctx, Id base, Id insert, Id offset, Id count); |
| 228 | void EmitBitFieldSExtract(EmitContext& ctx); | 228 | Id EmitBitFieldSExtract(EmitContext& ctx, Id base, Id offset, Id count); |
| 229 | Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count); | 229 | Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count); |
| 230 | Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs); | 230 | Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs); |
| 231 | Id EmitULessThan(EmitContext& ctx, Id lhs, Id rhs); | 231 | Id 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 | ||
| 93 | void EmitBitFieldInsert(EmitContext&) { | 93 | Id 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 | ||
| 97 | void EmitBitFieldSExtract(EmitContext&) { | 97 | Id 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 | ||
| 101 | Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count) { | 101 | Id 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 | ||
| 37 | void FFMA(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, const IR::F32& src_c) { | 47 | void 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 | ||
| 57 | void TranslatorVisitor::FFMA_rc(u64) { | 67 | void TranslatorVisitor::FFMA_rc(u64 insn) { |
| 58 | throw NotImplementedException("FFMA (rc)"); | 68 | FFMA(*this, insn, GetFloatReg39(insn), GetFloatCbuf(insn)); |
| 59 | } | 69 | } |
| 60 | 70 | ||
| 61 | void TranslatorVisitor::FFMA_cr(u64 insn) { | 71 | void 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 | ||
| 65 | void TranslatorVisitor::FFMA_imm(u64) { | 75 | void TranslatorVisitor::FFMA_imm(u64 insn) { |
| 66 | throw NotImplementedException("FFMA (imm)"); | 76 | FFMA(*this, insn, GetFloatImm20(insn), GetFloatReg39(insn)); |
| 67 | } | 77 | } |
| 68 | 78 | ||
| 69 | void TranslatorVisitor::FFMA32I(u64) { | 79 | void 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 | ||
| 81 | void TranslatorVisitor::XMAD_reg(u64) { | 81 | void 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 | ||
| 85 | void TranslatorVisitor::XMAD_rc(u64) { | 95 | void 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 | ||
| 89 | void TranslatorVisitor::XMAD_cr(u64) { | 107 | void 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 | ||
| 93 | void TranslatorVisitor::XMAD_imm(u64 insn) { | 121 | void 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 |