summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend
diff options
context:
space:
mode:
authorGravatar FernandoS272021-03-26 20:51:05 +0100
committerGravatar ameerj2021-07-22 21:51:25 -0400
commitdc1a9a3bed2aa9b0851f07976b0c687172aa3edc (patch)
tree8bfc0b3afc76b1b9a6100dfe8fb60b013927932b /src/shader_recompiler/frontend
parentspirv: Add fixed pipeline point size (diff)
downloadyuzu-dc1a9a3bed2aa9b0851f07976b0c687172aa3edc.tar.gz
yuzu-dc1a9a3bed2aa9b0851f07976b0c687172aa3edc.tar.xz
yuzu-dc1a9a3bed2aa9b0851f07976b0c687172aa3edc.zip
shader: Implement TLD
Diffstat (limited to 'src/shader_recompiler/frontend')
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc6
-rw-r--r--src/shader_recompiler/frontend/maxwell/maxwell.inc4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp8
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/texture_load.cpp165
4 files changed, 170 insertions, 13 deletions
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc
index 717aa71ca..302b8471d 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -378,7 +378,7 @@ OPCODE(BindlessImageSampleDrefImplicitLod, F32, U32,
378OPCODE(BindlessImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) 378OPCODE(BindlessImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, )
379OPCODE(BindlessImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) 379OPCODE(BindlessImageGather, F32x4, U32, Opaque, Opaque, Opaque, )
380OPCODE(BindlessImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) 380OPCODE(BindlessImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, )
381OPCODE(BindlessImageFetch, F32x4, U32, Opaque, U32, U32, ) 381OPCODE(BindlessImageFetch, F32x4, U32, Opaque, Opaque, Opaque, Opaque, )
382OPCODE(BindlessImageQueryDimensions, U32x4, U32, U32, ) 382OPCODE(BindlessImageQueryDimensions, U32x4, U32, U32, )
383 383
384OPCODE(BoundImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) 384OPCODE(BoundImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, )
@@ -387,7 +387,7 @@ OPCODE(BoundImageSampleDrefImplicitLod, F32, U32,
387OPCODE(BoundImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) 387OPCODE(BoundImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, )
388OPCODE(BoundImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) 388OPCODE(BoundImageGather, F32x4, U32, Opaque, Opaque, Opaque, )
389OPCODE(BoundImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) 389OPCODE(BoundImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, )
390OPCODE(BoundImageFetch, F32x4, U32, Opaque, U32, U32, ) 390OPCODE(BoundImageFetch, F32x4, U32, Opaque, Opaque, Opaque, Opaque, )
391OPCODE(BoundImageQueryDimensions, U32x4, U32, U32, ) 391OPCODE(BoundImageQueryDimensions, U32x4, U32, U32, )
392 392
393OPCODE(ImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) 393OPCODE(ImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, )
@@ -396,7 +396,7 @@ OPCODE(ImageSampleDrefImplicitLod, F32, U32,
396OPCODE(ImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) 396OPCODE(ImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, )
397OPCODE(ImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) 397OPCODE(ImageGather, F32x4, U32, Opaque, Opaque, Opaque, )
398OPCODE(ImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) 398OPCODE(ImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, )
399OPCODE(ImageFetch, F32x4, U32, Opaque, U32, U32, ) 399OPCODE(ImageFetch, F32x4, U32, Opaque, Opaque, Opaque, Opaque, )
400OPCODE(ImageQueryDimensions, U32x4, U32, U32, ) 400OPCODE(ImageQueryDimensions, U32x4, U32, U32, )
401 401
402// Warp operations 402// Warp operations
diff --git a/src/shader_recompiler/frontend/maxwell/maxwell.inc b/src/shader_recompiler/frontend/maxwell/maxwell.inc
index d668dc1aa..b47fb9c2e 100644
--- a/src/shader_recompiler/frontend/maxwell/maxwell.inc
+++ b/src/shader_recompiler/frontend/maxwell/maxwell.inc
@@ -252,8 +252,8 @@ INST(SYNC, "SYNC", "1111 0000 1111 1---")
252INST(TEX, "TEX", "1100 0--- ---- ----") 252INST(TEX, "TEX", "1100 0--- ---- ----")
253INST(TEX_b, "TEX (b)", "1101 1110 10-- ----") 253INST(TEX_b, "TEX (b)", "1101 1110 10-- ----")
254INST(TEXS, "TEXS", "1101 -00- ---- ----") 254INST(TEXS, "TEXS", "1101 -00- ---- ----")
255INST(TLD, "TLD", "1101 1100 --11 1---") 255INST(TLD, "TLD", "1101 1100 ---- ----")
256INST(TLD_b, "TLD (b)", "1101 1101 --11 1---") 256INST(TLD_b, "TLD (b)", "1101 1101 ---- ----")
257INST(TLD4, "TLD4", "1100 10-- ---- ----") 257INST(TLD4, "TLD4", "1100 10-- ---- ----")
258INST(TLD4_b, "TLD4 (b)", "1101 1110 11-- ----") 258INST(TLD4_b, "TLD4 (b)", "1101 1110 11-- ----")
259INST(TLD4S, "TLD4S", "1101 1111 -0-- ----") 259INST(TLD4S, "TLD4S", "1101 1111 -0-- ----")
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 6a580f831..60d61ec6e 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -313,14 +313,6 @@ void TranslatorVisitor::SYNC(u64) {
313 ThrowNotImplemented(Opcode::SYNC); 313 ThrowNotImplemented(Opcode::SYNC);
314} 314}
315 315
316void TranslatorVisitor::TLD(u64) {
317 ThrowNotImplemented(Opcode::TLD);
318}
319
320void TranslatorVisitor::TLD_b(u64) {
321 ThrowNotImplemented(Opcode::TLD_b);
322}
323
324void TranslatorVisitor::TLDS(u64) { 316void TranslatorVisitor::TLDS(u64) {
325 ThrowNotImplemented(Opcode::TLDS); 317 ThrowNotImplemented(Opcode::TLDS);
326} 318}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load.cpp
new file mode 100644
index 000000000..b4063fa6e
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load.cpp
@@ -0,0 +1,165 @@
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 <optional>
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 {
14
15enum class TextureType : u64 {
16 _1D,
17 ARRAY_1D,
18 _2D,
19 ARRAY_2D,
20 _3D,
21 ARRAY_3D,
22 CUBE,
23 ARRAY_CUBE,
24};
25
26Shader::TextureType GetType(TextureType type, bool dc) {
27 switch (type) {
28 case TextureType::_1D:
29 return dc ? Shader::TextureType::Shadow1D : Shader::TextureType::Color1D;
30 case TextureType::ARRAY_1D:
31 return dc ? Shader::TextureType::ShadowArray1D : Shader::TextureType::ColorArray1D;
32 case TextureType::_2D:
33 return dc ? Shader::TextureType::Shadow2D : Shader::TextureType::Color2D;
34 case TextureType::ARRAY_2D:
35 return dc ? Shader::TextureType::ShadowArray2D : Shader::TextureType::ColorArray2D;
36 case TextureType::_3D:
37 return dc ? Shader::TextureType::Shadow3D : Shader::TextureType::Color3D;
38 case TextureType::ARRAY_3D:
39 throw NotImplementedException("3D array texture type");
40 case TextureType::CUBE:
41 return dc ? Shader::TextureType::ShadowCube : Shader::TextureType::ColorCube;
42 case TextureType::ARRAY_CUBE:
43 return dc ? Shader::TextureType::ShadowArrayCube : Shader::TextureType::ColorArrayCube;
44 }
45 throw NotImplementedException("Invalid texture type {}", type);
46}
47
48IR::Value MakeCoords(TranslatorVisitor& v, IR::Reg reg, TextureType type) {
49 const auto read_array{
50 [&]() -> IR::U32 { return v.ir.BitFieldExtract(v.X(reg), v.ir.Imm32(0), v.ir.Imm32(16)); }};
51 switch (type) {
52 case TextureType::_1D:
53 return v.X(reg);
54 case TextureType::ARRAY_1D:
55 return v.ir.CompositeConstruct(v.X(reg + 1), read_array());
56 case TextureType::_2D:
57 return v.ir.CompositeConstruct(v.X(reg), v.X(reg + 1));
58 case TextureType::ARRAY_2D:
59 return v.ir.CompositeConstruct(v.X(reg + 1), v.X(reg + 2), read_array());
60 case TextureType::_3D:
61 return v.ir.CompositeConstruct(v.X(reg), v.X(reg + 1), v.X(reg + 2));
62 case TextureType::ARRAY_3D:
63 throw NotImplementedException("3D array texture type");
64 case TextureType::CUBE:
65 return v.ir.CompositeConstruct(v.X(reg), v.X(reg + 1), v.X(reg + 2));
66 case TextureType::ARRAY_CUBE:
67 return v.ir.CompositeConstruct(v.X(reg + 1), v.X(reg + 2), v.X(reg + 3), read_array());
68 }
69 throw NotImplementedException("Invalid texture type {}", type);
70}
71
72IR::Value MakeOffset(TranslatorVisitor& v, IR::Reg& reg, TextureType type) {
73 const IR::U32 value{v.X(reg++)};
74 switch (type) {
75 case TextureType::_1D:
76 case TextureType::ARRAY_1D:
77 return v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4), true);
78 case TextureType::_2D:
79 case TextureType::ARRAY_2D:
80 return v.ir.CompositeConstruct(
81 v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4), true),
82 v.ir.BitFieldExtract(value, v.ir.Imm32(4), v.ir.Imm32(4), true));
83 case TextureType::_3D:
84 case TextureType::ARRAY_3D:
85 return v.ir.CompositeConstruct(
86 v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4), true),
87 v.ir.BitFieldExtract(value, v.ir.Imm32(4), v.ir.Imm32(4), true),
88 v.ir.BitFieldExtract(value, v.ir.Imm32(8), v.ir.Imm32(4), true));
89 case TextureType::CUBE:
90 case TextureType::ARRAY_CUBE:
91 throw NotImplementedException("Illegal offset on CUBE sample");
92 }
93 throw NotImplementedException("Invalid texture type {}", type);
94}
95
96void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
97 union {
98 u64 raw;
99 BitField<49, 1, u64> nodep;
100 BitField<55, 1, u64> lod;
101 BitField<50, 1, u64> multisample;
102 BitField<35, 1, u64> aoffi;
103 BitField<54, 1, u64> clamp;
104 BitField<51, 3, IR::Pred> sparse_pred;
105 BitField<0, 8, IR::Reg> dest_reg;
106 BitField<8, 8, IR::Reg> coord_reg;
107 BitField<20, 8, IR::Reg> meta_reg;
108 BitField<28, 3, TextureType> type;
109 BitField<31, 4, u64> mask;
110 BitField<36, 13, u64> cbuf_offset;
111 } const tld{insn};
112
113 const IR::Value coords{MakeCoords(v, tld.coord_reg, tld.type)};
114
115 IR::Reg meta_reg{tld.meta_reg};
116 IR::Value handle;
117 IR::Value offset;
118 IR::U32 lod;
119 IR::U32 multisample;
120 if (!is_bindless) {
121 handle = v.ir.Imm32(static_cast<u32>(tld.cbuf_offset.Value() * 4));
122 } else {
123 handle = v.X(meta_reg++);
124 }
125 if (tld.lod != 0) {
126 lod = v.X(meta_reg++);
127 }
128 if (tld.aoffi != 0) {
129 offset = MakeOffset(v, meta_reg, tld.type);
130 }
131 if (tld.multisample != 0) {
132 multisample = v.X(meta_reg++);
133 }
134 if (tld.clamp != 0) {
135 throw NotImplementedException("TLD.CL - CLAMP is not implmented");
136 }
137 IR::TextureInstInfo info{};
138 info.type.Assign(GetType(tld.type, false));
139 const IR::Value sample{[&]() -> IR::Value {
140 return v.ir.ImageFetch(handle, coords, offset, lod, multisample, info);
141 }()};
142
143 IR::Reg dest_reg{tld.dest_reg};
144 for (size_t element = 0; element < 4; ++element) {
145 if (((tld.mask >> element) & 1) == 0) {
146 continue;
147 }
148 v.F(dest_reg, IR::F32{v.ir.CompositeExtract(sample, element)});
149 ++dest_reg;
150 }
151 if (tld.sparse_pred != IR::Pred::PT) {
152 v.ir.SetPred(tld.sparse_pred, v.ir.LogicalNot(v.ir.GetSparseFromOp(sample)));
153 }
154}
155} // Anonymous namespace
156
157void TranslatorVisitor::TLD(u64 insn) {
158 Impl(*this, insn, false);
159}
160
161void TranslatorVisitor::TLD_b(u64 insn) {
162 Impl(*this, insn, true);
163}
164
165} // namespace Shader::Maxwell