summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/frontend/maxwell/translate
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-03-19 23:28:31 +0100
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:23 +0200
commit260743f371236f7c57b01334b1c3474b15a47c39 (patch)
tree312d89fa8215199ef5f7ec1fc84b025df526e107 /src/shader_recompiler/frontend/maxwell/translate
parentshader: Implement DADD (diff)
downloadyuzu-260743f371236f7c57b01334b1c3474b15a47c39.tar
yuzu-260743f371236f7c57b01334b1c3474b15a47c39.tar.gz
yuzu-260743f371236f7c57b01334b1c3474b15a47c39.tar.bz2
yuzu-260743f371236f7c57b01334b1c3474b15a47c39.tar.lz
yuzu-260743f371236f7c57b01334b1c3474b15a47c39.tar.xz
yuzu-260743f371236f7c57b01334b1c3474b15a47c39.tar.zst
yuzu-260743f371236f7c57b01334b1c3474b15a47c39.zip
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/translate')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/exit.cpp15
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/exit_program.cpp43
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.h4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/load_store_attribute.cpp86
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp16
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp2
7 files changed, 134 insertions, 34 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/exit.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/exit.cpp
deleted file mode 100644
index e98bbd0d1..000000000
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/exit.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2021 yuzu Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "common/common_types.h"
-#include "shader_recompiler/exception.h"
-#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
-
-namespace Shader::Maxwell {
-
-void TranslatorVisitor::EXIT(u64) {
- ir.Exit();
-}
-
-} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/exit_program.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/exit_program.cpp
new file mode 100644
index 000000000..ea9b33da9
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/exit_program.cpp
@@ -0,0 +1,43 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/common_types.h"
+#include "shader_recompiler/exception.h"
+#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
+
+namespace Shader::Maxwell {
+namespace {
+void ExitFragment(TranslatorVisitor& v) {
+ const ProgramHeader sph{v.env.SPH()};
+ IR::Reg src_reg{IR::Reg::R0};
+ for (u32 render_target = 0; render_target < 8; ++render_target) {
+ const std::array<bool, 4> mask{sph.ps.EnabledOutputComponents(render_target)};
+ for (u32 component = 0; component < 4; ++component) {
+ if (!mask[component]) {
+ continue;
+ }
+ v.ir.SetFragColor(render_target, component, v.F(src_reg));
+ ++src_reg;
+ }
+ }
+ if (sph.ps.omap.sample_mask != 0) {
+ throw NotImplementedException("Sample mask");
+ }
+ if (sph.ps.omap.depth != 0) {
+ throw NotImplementedException("Fragment depth");
+ }
+}
+} // Anonymous namespace
+
+void TranslatorVisitor::EXIT() {
+ switch (env.ShaderStage()) {
+ case Stage::Fragment:
+ ExitFragment(*this);
+ break;
+ default:
+ break;
+ }
+}
+
+} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
index e3e298c3b..ed81d9c36 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
@@ -108,7 +108,7 @@ public:
void DSETP_reg(u64 insn);
void DSETP_cbuf(u64 insn);
void DSETP_imm(u64 insn);
- void EXIT(u64 insn);
+ void EXIT();
void F2F_reg(u64 insn);
void F2F_cbuf(u64 insn);
void F2F_imm(u64 insn);
@@ -220,7 +220,7 @@ public:
void JCAL(u64 insn);
void JMP(u64 insn);
void JMX(u64 insn);
- void KIL(u64 insn);
+ void KIL();
void LD(u64 insn);
void LDC(u64 insn);
void LDG(u64 insn);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_attribute.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_attribute.cpp
index ad97786d4..2922145ee 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_attribute.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_attribute.cpp
@@ -11,6 +11,13 @@
namespace Shader::Maxwell {
namespace {
+enum class Size : u64 {
+ B32,
+ B64,
+ B96,
+ B128,
+};
+
enum class InterpolationMode : u64 {
Pass,
Multiply,
@@ -23,8 +30,85 @@ enum class SampleMode : u64 {
Centroid,
Offset,
};
+
+int NumElements(Size size) {
+ switch (size) {
+ case Size::B32:
+ return 1;
+ case Size::B64:
+ return 2;
+ case Size::B96:
+ return 3;
+ case Size::B128:
+ return 4;
+ }
+ throw InvalidArgument("Invalid size {}", size);
+}
} // Anonymous namespace
+void TranslatorVisitor::ALD(u64 insn) {
+ union {
+ u64 raw;
+ BitField<0, 8, IR::Reg> dest_reg;
+ BitField<8, 8, IR::Reg> index_reg;
+ BitField<20, 10, u64> absolute_offset;
+ BitField<20, 11, s64> relative_offset;
+ BitField<39, 8, IR::Reg> stream_reg;
+ BitField<32, 1, u64> o;
+ BitField<31, 1, u64> patch;
+ BitField<47, 2, Size> size;
+ } const ald{insn};
+
+ if (ald.o != 0) {
+ throw NotImplementedException("O");
+ }
+ if (ald.patch != 0) {
+ throw NotImplementedException("P");
+ }
+ if (ald.index_reg != IR::Reg::RZ) {
+ throw NotImplementedException("Indexed");
+ }
+ const u64 offset{ald.absolute_offset.Value()};
+ if (offset % 4 != 0) {
+ throw NotImplementedException("Unaligned absolute offset {}", offset);
+ }
+ const int num_elements{NumElements(ald.size)};
+ for (int element = 0; element < num_elements; ++element) {
+ F(ald.dest_reg + element, ir.GetAttribute(IR::Attribute{offset / 4 + element}));
+ }
+}
+
+void TranslatorVisitor::AST(u64 insn) {
+ union {
+ u64 raw;
+ BitField<0, 8, IR::Reg> src_reg;
+ BitField<8, 8, IR::Reg> index_reg;
+ BitField<20, 10, u64> absolute_offset;
+ BitField<20, 11, s64> relative_offset;
+ BitField<31, 1, u64> patch;
+ BitField<39, 8, IR::Reg> stream_reg;
+ BitField<47, 2, Size> size;
+ } const ast{insn};
+
+ if (ast.patch != 0) {
+ throw NotImplementedException("P");
+ }
+ if (ast.stream_reg != IR::Reg::RZ) {
+ throw NotImplementedException("Stream store");
+ }
+ if (ast.index_reg != IR::Reg::RZ) {
+ throw NotImplementedException("Indexed store");
+ }
+ const u64 offset{ast.absolute_offset.Value()};
+ if (offset % 4 != 0) {
+ throw NotImplementedException("Unaligned absolute offset {}", offset);
+ }
+ const int num_elements{NumElements(ast.size)};
+ for (int element = 0; element < num_elements; ++element) {
+ ir.SetAttribute(IR::Attribute{offset / 4 + element}, F(ast.src_reg + element));
+ }
+}
+
void TranslatorVisitor::IPA(u64 insn) {
// IPA is the instruction used to read varyings from a fragment shader.
// gl_FragCoord is mapped to the gl_Position attribute.
@@ -51,7 +135,7 @@ void TranslatorVisitor::IPA(u64 insn) {
// }
const bool is_indexed{ipa.idx != 0 && ipa.index_reg != IR::Reg::RZ};
if (is_indexed) {
- throw NotImplementedException("IPA.IDX");
+ throw NotImplementedException("IDX");
}
const IR::Attribute attribute{ipa.attribute};
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 9675cef54..59252bcc5 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -17,14 +17,6 @@ void TranslatorVisitor::AL2P(u64) {
ThrowNotImplemented(Opcode::AL2P);
}
-void TranslatorVisitor::ALD(u64) {
- ThrowNotImplemented(Opcode::ALD);
-}
-
-void TranslatorVisitor::AST(u64) {
- ThrowNotImplemented(Opcode::AST);
-}
-
void TranslatorVisitor::ATOM_cas(u64) {
ThrowNotImplemented(Opcode::ATOM_cas);
}
@@ -153,10 +145,6 @@ void TranslatorVisitor::DSETP_imm(u64) {
ThrowNotImplemented(Opcode::DSETP_imm);
}
-void TranslatorVisitor::EXIT(u64) {
- throw LogicError("Visting EXIT instruction");
-}
-
void TranslatorVisitor::F2F_reg(u64) {
ThrowNotImplemented(Opcode::F2F_reg);
}
@@ -345,8 +333,8 @@ void TranslatorVisitor::JMX(u64) {
ThrowNotImplemented(Opcode::JMX);
}
-void TranslatorVisitor::KIL(u64) {
- ThrowNotImplemented(Opcode::KIL);
+void TranslatorVisitor::KIL() {
+ // KIL is a no-op
}
void TranslatorVisitor::LD(u64) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch.cpp
index 98d9f4c64..0fbb87ec4 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch.cpp
@@ -215,7 +215,7 @@ void TranslatorVisitor::TEX(u64 insn) {
BitField<36, 13, u64> cbuf_offset;
} const tex{insn};
- Impl(*this, insn, tex.aoffi != 0, tex.blod, tex.lc != 0, static_cast<u32>(tex.cbuf_offset));
+ Impl(*this, insn, tex.aoffi != 0, tex.blod, tex.lc != 0, static_cast<u32>(tex.cbuf_offset * 4));
}
void TranslatorVisitor::TEX_b(u64 insn) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp
index ac1615b00..54f0df754 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp
@@ -70,7 +70,7 @@ IR::F32 ReadArray(TranslatorVisitor& v, const IR::U32& value) {
IR::Value Sample(TranslatorVisitor& v, u64 insn) {
const Encoding texs{insn};
- const IR::U32 handle{v.ir.Imm32(static_cast<u32>(texs.cbuf_offset))};
+ const IR::U32 handle{v.ir.Imm32(static_cast<u32>(texs.cbuf_offset * 4))};
const IR::F32 zero{v.ir.Imm32(0.0f)};
const IR::Reg reg_a{texs.src_reg_a};
const IR::Reg reg_b{texs.src_reg_b};