summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/frontend/maxwell
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-02-23 02:59:16 +0100
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:22 +0200
commite44752ddc8804961eb84f8c225bb36d5b4c77bc1 (patch)
tree84df0e38680470a0ee8c2230625193c4156ddea6 /src/shader_recompiler/frontend/maxwell
parentshader: Fix MOV(reg), add SHL variants and emit neg and abs instructions (diff)
downloadyuzu-e44752ddc8804961eb84f8c225bb36d5b4c77bc1.tar
yuzu-e44752ddc8804961eb84f8c225bb36d5b4c77bc1.tar.gz
yuzu-e44752ddc8804961eb84f8c225bb36d5b4c77bc1.tar.bz2
yuzu-e44752ddc8804961eb84f8c225bb36d5b4c77bc1.tar.lz
yuzu-e44752ddc8804961eb84f8c225bb36d5b4c77bc1.tar.xz
yuzu-e44752ddc8804961eb84f8c225bb36d5b4c77bc1.tar.zst
yuzu-e44752ddc8804961eb84f8c225bb36d5b4c77bc1.zip
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h3
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp8
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp42
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp41
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp12
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.h5
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp12
10 files changed, 93 insertions, 38 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h b/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h
index 3da37a2bb..fd73f656c 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h
@@ -46,7 +46,8 @@ inline IR::FmzMode CastFmzMode(FmzMode fmz_mode) {
case FmzMode::FTZ:
return IR::FmzMode::FTZ;
case FmzMode::FMZ:
- return IR::FmzMode::FMZ;
+ // FMZ is manually handled in the instruction
+ return IR::FmzMode::FTZ;
case FmzMode::INVALIDFMZ3:
break;
}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp
index 219ffcc6a..76a807d4e 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp
@@ -53,7 +53,7 @@ void FADD(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
} // Anonymous namespace
void TranslatorVisitor::FADD_reg(u64 insn) {
- FADD(*this, insn, GetRegFloat20(insn));
+ FADD(*this, insn, GetFloatReg20(insn));
}
void TranslatorVisitor::FADD_cbuf(u64 insn) {
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 758700d3c..c2ca0873b 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
@@ -51,7 +51,7 @@ void FFMA(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, const IR::F32& s
} // Anonymous namespace
void TranslatorVisitor::FFMA_reg(u64 insn) {
- FFMA(*this, insn, GetRegFloat20(insn), GetRegFloat39(insn));
+ FFMA(*this, insn, GetFloatReg20(insn), GetFloatReg39(insn));
}
void TranslatorVisitor::FFMA_rc(u64) {
@@ -59,7 +59,7 @@ void TranslatorVisitor::FFMA_rc(u64) {
}
void TranslatorVisitor::FFMA_cr(u64 insn) {
- FFMA(*this, insn, GetFloatCbuf(insn), GetRegFloat39(insn));
+ FFMA(*this, insn, GetFloatCbuf(insn), GetFloatReg39(insn));
}
void TranslatorVisitor::FFMA_imm(u64) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp
index ba005fbf4..2f8605619 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp
@@ -10,7 +10,7 @@
namespace Shader::Maxwell {
namespace {
-enum class Operation {
+enum class Operation : u64 {
Cos = 0,
Sin = 1,
Ex2 = 2, // Base 2 exponent
@@ -39,11 +39,11 @@ void TranslatorVisitor::MUFU(u64 insn) {
IR::F32 value{[&]() -> IR::F32 {
switch (mufu.operation) {
case Operation::Cos:
- return ir.FPCosNotReduced(op_a);
+ return ir.FPCos(op_a);
case Operation::Sin:
- return ir.FPSinNotReduced(op_a);
+ return ir.FPSin(op_a);
case Operation::Ex2:
- return ir.FPExp2NotReduced(op_a);
+ return ir.FPExp2(op_a);
case Operation::Lg2:
return ir.FPLog2(op_a);
case Operation::Rcp:
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 5c38d3fc1..edf2cadae 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
@@ -55,9 +55,6 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, FmzMode fmz_mode
if (cc) {
throw NotImplementedException("FMUL CC");
}
- if (sat) {
- throw NotImplementedException("FMUL SAT");
- }
IR::F32 op_a{v.F(fmul.src_a)};
if (scale != Scale::None) {
if (fmz_mode != FmzMode::FTZ || fp_rounding != FpRounding::RN) {
@@ -71,7 +68,20 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, FmzMode fmz_mode
.rounding{CastFpRounding(fp_rounding)},
.fmz_mode{CastFmzMode(fmz_mode)},
};
- v.F(fmul.dest_reg, v.ir.FPMul(op_a, op_b, fp_control));
+ IR::F32 value{v.ir.FPMul(op_a, op_b, fp_control)};
+ if (fmz_mode == FmzMode::FMZ && !sat) {
+ // Do not implement FMZ if SAT is enabled, as it does the logic for us.
+ // On D3D9 mode, anything * 0 is zero, even NAN and infinity
+ const IR::F32 zero{v.ir.Imm32(0.0f)};
+ const IR::U1 zero_a{v.ir.FPEqual(op_a, zero)};
+ const IR::U1 zero_b{v.ir.FPEqual(op_b, zero)};
+ const IR::U1 any_zero{v.ir.LogicalOr(zero_a, zero_b)};
+ value = IR::F32{v.ir.Select(any_zero, zero, value)};
+ }
+ if (sat) {
+ value = v.ir.FPSaturate(value);
+ }
+ v.F(fmul.dest_reg, value);
}
void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
@@ -83,27 +93,33 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
BitField<47, 1, u64> cc;
BitField<48, 1, u64> neg_b;
BitField<50, 1, u64> sat;
- } fmul{insn};
-
+ } const fmul{insn};
FMUL(v, insn, src_b, fmul.fmz, fmul.fp_rounding, fmul.scale, fmul.sat != 0, fmul.cc != 0,
fmul.neg_b != 0);
}
} // Anonymous namespace
void TranslatorVisitor::FMUL_reg(u64 insn) {
- return FMUL(*this, insn, GetRegFloat20(insn));
+ return FMUL(*this, insn, GetFloatReg20(insn));
}
-void TranslatorVisitor::FMUL_cbuf(u64) {
- throw NotImplementedException("FMUL (cbuf)");
+void TranslatorVisitor::FMUL_cbuf(u64 insn) {
+ return FMUL(*this, insn, GetFloatCbuf(insn));
}
-void TranslatorVisitor::FMUL_imm(u64) {
- throw NotImplementedException("FMUL (imm)");
+void TranslatorVisitor::FMUL_imm(u64 insn) {
+ return FMUL(*this, insn, GetFloatImm20(insn));
}
-void TranslatorVisitor::FMUL32I(u64) {
- throw NotImplementedException("FMUL32I");
+void TranslatorVisitor::FMUL32I(u64 insn) {
+ union {
+ u64 raw;
+ BitField<52, 1, u64> cc;
+ BitField<53, 2, FmzMode> fmz;
+ BitField<55, 1, u64> sat;
+ } const fmul32i{insn};
+ FMUL(*this, insn, GetFloatImm32(insn), fmul32i.fmz, FpRounding::RN, Scale::None,
+ fmul32i.sat != 0, fmul32i.cc != 0, false);
}
} // namespace Shader::Maxwell \ No newline at end of file
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp
new file mode 100644
index 000000000..f91b93fad
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp
@@ -0,0 +1,41 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/bit_field.h"
+#include "common/common_types.h"
+#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
+
+namespace Shader::Maxwell {
+namespace {
+enum class Mode : u64 {
+ SINCOS,
+ EX2,
+};
+
+void RRO(TranslatorVisitor& v, u64 insn, const IR::F32& src) {
+ union {
+ u64 raw;
+ BitField<0, 8, IR::Reg> dest_reg;
+ BitField<39, 1, Mode> mode;
+ BitField<45, 1, u64> neg;
+ BitField<49, 1, u64> abs;
+ } const rro{insn};
+
+ v.F(rro.dest_reg, v.ir.FPAbsNeg(src, rro.abs != 0, rro.neg != 0));
+}
+} // Anonymous namespace
+
+void TranslatorVisitor::RRO_reg(u64 insn) {
+ RRO(*this, insn, GetFloatReg20(insn));
+}
+
+void TranslatorVisitor::RRO_cbuf(u64 insn) {
+ RRO(*this, insn, GetFloatCbuf(insn));
+}
+
+void TranslatorVisitor::RRO_imm(u64) {
+ throw NotImplementedException("RRO (imm)");
+}
+
+} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
index 165d475b9..a5a0e1a9b 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
@@ -48,11 +48,11 @@ IR::U32 TranslatorVisitor::GetReg39(u64 insn) {
return X(reg.index);
}
-IR::F32 TranslatorVisitor::GetRegFloat20(u64 insn) {
+IR::F32 TranslatorVisitor::GetFloatReg20(u64 insn) {
return ir.BitCast<IR::F32>(GetReg20(insn));
}
-IR::F32 TranslatorVisitor::GetRegFloat39(u64 insn) {
+IR::F32 TranslatorVisitor::GetFloatReg39(u64 insn) {
return ir.BitCast<IR::F32>(GetReg39(insn));
}
@@ -110,6 +110,14 @@ IR::U32 TranslatorVisitor::GetImm32(u64 insn) {
return ir.Imm32(static_cast<u32>(imm.value));
}
+IR::F32 TranslatorVisitor::GetFloatImm32(u64 insn) {
+ union {
+ u64 raw;
+ BitField<20, 32, u64> value;
+ } const imm{insn};
+ return ir.Imm32(Common::BitCast<f32>(static_cast<u32>(imm.value)));
+}
+
void TranslatorVisitor::SetZFlag(const IR::U1& value) {
ir.SetZFlag(value);
}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
index 4d4cf2ebf..4e722e205 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
@@ -304,8 +304,8 @@ public:
[[nodiscard]] IR::U32 GetReg8(u64 insn);
[[nodiscard]] IR::U32 GetReg20(u64 insn);
[[nodiscard]] IR::U32 GetReg39(u64 insn);
- [[nodiscard]] IR::F32 GetRegFloat20(u64 insn);
- [[nodiscard]] IR::F32 GetRegFloat39(u64 insn);
+ [[nodiscard]] IR::F32 GetFloatReg20(u64 insn);
+ [[nodiscard]] IR::F32 GetFloatReg39(u64 insn);
[[nodiscard]] IR::U32 GetCbuf(u64 insn);
[[nodiscard]] IR::F32 GetFloatCbuf(u64 insn);
@@ -314,6 +314,7 @@ public:
[[nodiscard]] IR::F32 GetFloatImm20(u64 insn);
[[nodiscard]] IR::U32 GetImm32(u64 insn);
+ [[nodiscard]] IR::F32 GetFloatImm32(u64 insn);
void SetZFlag(const IR::U1& value);
void SetSFlag(const IR::U1& value);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp
index d8a5158b5..20af68852 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp
@@ -50,7 +50,7 @@ void SHL(TranslatorVisitor& v, u64 insn, const IR::U32& unsafe_shift) {
//
const IR::U1 is_safe{v.ir.ILessThan(unsafe_shift, v.ir.Imm32(32), false)};
const IR::U32 unsafe_result{v.ir.ShiftLeftLogical(base, unsafe_shift)};
- result = v.ir.Select(is_safe, unsafe_result, v.ir.Imm32(0));
+ result = IR::U32{v.ir.Select(is_safe, unsafe_result, v.ir.Imm32(0))};
}
v.X(shl.dest_reg, result);
}
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 628cf1c14..4114e10be 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -721,18 +721,6 @@ void TranslatorVisitor::RET(u64) {
ThrowNotImplemented(Opcode::RET);
}
-void TranslatorVisitor::RRO_reg(u64) {
- ThrowNotImplemented(Opcode::RRO_reg);
-}
-
-void TranslatorVisitor::RRO_cbuf(u64) {
- ThrowNotImplemented(Opcode::RRO_cbuf);
-}
-
-void TranslatorVisitor::RRO_imm(u64) {
- ThrowNotImplemented(Opcode::RRO_imm);
-}
-
void TranslatorVisitor::RTT(u64) {
ThrowNotImplemented(Opcode::RTT);
}