summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend
diff options
context:
space:
mode:
authorGravatar FernandoS272021-03-25 19:59:35 +0100
committerGravatar ameerj2021-07-22 21:51:24 -0400
commitfda0835300a7ef6112791ae503435c81ffe883f5 (patch)
treeb9e669a7f19c8ce0fb30c37e32201bb2e10a36d0 /src/shader_recompiler/frontend
parentshader: Implement TLD4 and TLD4_B (diff)
downloadyuzu-fda0835300a7ef6112791ae503435c81ffe883f5.tar.gz
yuzu-fda0835300a7ef6112791ae503435c81ffe883f5.tar.xz
yuzu-fda0835300a7ef6112791ae503435c81ffe883f5.zip
shader: Implement TLD4S.
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp133
2 files changed, 133 insertions, 4 deletions
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 e59c3326e..788765c21 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -349,10 +349,6 @@ void TranslatorVisitor::TLD_b(u64) {
349 ThrowNotImplemented(Opcode::TLD_b); 349 ThrowNotImplemented(Opcode::TLD_b);
350} 350}
351 351
352void TranslatorVisitor::TLD4S(u64) {
353 ThrowNotImplemented(Opcode::TLD4S);
354}
355
356void TranslatorVisitor::TLDS(u64) { 352void TranslatorVisitor::TLDS(u64) {
357 ThrowNotImplemented(Opcode::TLDS); 353 ThrowNotImplemented(Opcode::TLDS);
358} 354}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp
new file mode 100644
index 000000000..beab515ad
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp
@@ -0,0 +1,133 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <utility>
6
7#include "common/bit_field.h"
8#include "common/common_types.h"
9#include "shader_recompiler/frontend/ir/modifiers.h"
10#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
11
12namespace Shader::Maxwell {
13namespace {
14enum class Precision : u64 {
15 F32,
16 F16,
17};
18
19enum class ComponentType : u64 {
20 R = 0,
21 G = 1,
22 B = 2,
23 A = 3,
24};
25
26union Encoding {
27 u64 raw;
28 BitField<55, 1, Precision> precision;
29 BitField<52, 2, ComponentType> component_type;
30 BitField<51, 1, u64> aoffi;
31 BitField<50, 1, u64> dc;
32 BitField<49, 1, u64> nodep;
33 BitField<28, 8, IR::Reg> dest_reg_b;
34 BitField<0, 8, IR::Reg> dest_reg_a;
35 BitField<8, 8, IR::Reg> src_reg_a;
36 BitField<20, 8, IR::Reg> src_reg_b;
37 BitField<36, 13, u64> cbuf_offset;
38};
39
40void CheckAlignment(IR::Reg reg, int alignment) {
41 if (!IR::IsAligned(reg, alignment)) {
42 throw NotImplementedException("Unaligned source register {}", reg);
43 }
44}
45
46IR::Value MakeOffset(TranslatorVisitor& v, IR::Reg reg) {
47 const IR::U32 value{v.X(reg)};
48 return v.ir.CompositeConstruct(v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(6), true),
49 v.ir.BitFieldExtract(value, v.ir.Imm32(8), v.ir.Imm32(6), true));
50}
51
52IR::Value Sample(TranslatorVisitor& v, u64 insn) {
53 const Encoding tld4s{insn};
54 const IR::U32 handle{v.ir.Imm32(static_cast<u32>(tld4s.cbuf_offset * 4))};
55 const IR::Reg reg_a{tld4s.src_reg_a};
56 const IR::Reg reg_b{tld4s.src_reg_b};
57 IR::TextureInstInfo info{};
58 if (tld4s.precision == Precision::F16) {
59 info.relaxed_precision.Assign(1);
60 }
61 info.gather_component.Assign(static_cast<u32>(tld4s.component_type.Value()));
62 info.type.Assign(tld4s.dc != 0 ? Shader::TextureType::Shadow2D : Shader::TextureType::Color2D);
63 IR::Value coords;
64 if (tld4s.aoffi != 0) {
65 CheckAlignment(reg_a, 2);
66 coords = v.ir.CompositeConstruct(v.F(reg_a), v.F(reg_a + 1));
67 IR::Value offset = MakeOffset(v, reg_b);
68 if (tld4s.dc != 0) {
69 CheckAlignment(reg_b, 2);
70 IR::F32 dref = v.F(reg_b + 1);
71 return v.ir.ImageGatherDref(handle, coords, offset, {}, dref, info);
72 }
73 return v.ir.ImageGather(handle, coords, offset, {}, info);
74 }
75 if (tld4s.dc != 0) {
76 CheckAlignment(reg_a, 2);
77 coords = v.ir.CompositeConstruct(v.F(reg_a), v.F(reg_a + 1));
78 IR::F32 dref = v.F(reg_b);
79 return v.ir.ImageGatherDref(handle, coords, {}, {}, dref, info);
80 }
81 coords = v.ir.CompositeConstruct(v.F(reg_a), v.F(reg_b));
82 return v.ir.ImageGather(handle, coords, {}, {}, info);
83}
84
85IR::Reg RegStoreComponent32(u64 insn, size_t index) {
86 const Encoding tlds4{insn};
87 switch (index) {
88 case 0:
89 return tlds4.dest_reg_a;
90 case 1:
91 CheckAlignment(tlds4.dest_reg_a, 2);
92 return tlds4.dest_reg_a + 1;
93 case 2:
94 return tlds4.dest_reg_b;
95 case 3:
96 CheckAlignment(tlds4.dest_reg_b, 2);
97 return tlds4.dest_reg_b + 1;
98 }
99 throw LogicError("Invalid store index {}", index);
100}
101
102void Store32(TranslatorVisitor& v, u64 insn, const IR::Value& sample) {
103 for (size_t component = 0; component < 4; ++component) {
104 const IR::Reg dest{RegStoreComponent32(insn, component)};
105 v.F(dest, IR::F32{v.ir.CompositeExtract(sample, component)});
106 }
107}
108
109IR::U32 Pack(TranslatorVisitor& v, const IR::F32& lhs, const IR::F32& rhs) {
110 return v.ir.PackHalf2x16(v.ir.CompositeConstruct(lhs, rhs));
111}
112
113void Store16(TranslatorVisitor& v, u64 insn, const IR::Value& sample) {
114 std::array<IR::F32, 4> swizzled;
115 for (size_t component = 0; component < 4; ++component) {
116 swizzled[component] = IR::F32{v.ir.CompositeExtract(sample, component)};
117 }
118 const Encoding tld4s{insn};
119 v.X(tld4s.dest_reg_a, Pack(v, swizzled[0], swizzled[1]));
120 v.X(tld4s.dest_reg_b, Pack(v, swizzled[2], swizzled[3]));
121}
122} // Anonymous namespace
123
124void TranslatorVisitor::TLD4S(u64 insn) {
125 const IR::Value sample{Sample(*this, insn)};
126 if (Encoding{insn}.precision == Precision::F32) {
127 Store32(*this, insn, sample);
128 } else {
129 Store16(*this, insn, sample);
130 }
131}
132
133} // namespace Shader::Maxwell