shader: Add partial rasterizer integration

This commit is contained in:
ReinUsesLisp 2021-03-19 19:28:31 -03:00 committed by ameerj
parent 72990df7ba
commit 260743f371
54 changed files with 1929 additions and 568 deletions

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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};

View file

@ -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) {

View file

@ -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) {

View file

@ -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};