summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/ir_opt/texture_pass.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-04-09 01:45:39 -0300
committerGravatar ameerj2021-07-22 21:51:26 -0400
commit7cb2ab358517d95ebcd35c94c72b9e91762906c3 (patch)
tree3f75959e255026665a4dde406cb8c4cc34fb45a0 /src/shader_recompiler/ir_opt/texture_pass.cpp
parentshader: Fix Windows build issues (diff)
downloadyuzu-7cb2ab358517d95ebcd35c94c72b9e91762906c3.tar.gz
yuzu-7cb2ab358517d95ebcd35c94c72b9e91762906c3.tar.xz
yuzu-7cb2ab358517d95ebcd35c94c72b9e91762906c3.zip
shader: Implement SULD and SUST
Diffstat (limited to 'src/shader_recompiler/ir_opt/texture_pass.cpp')
-rw-r--r--src/shader_recompiler/ir_opt/texture_pass.cpp91
1 files changed, 68 insertions, 23 deletions
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp
index c8aee3d3d..a7b1fcfad 100644
--- a/src/shader_recompiler/ir_opt/texture_pass.cpp
+++ b/src/shader_recompiler/ir_opt/texture_pass.cpp
@@ -61,6 +61,12 @@ IR::Opcode IndexedInstruction(const IR::Inst& inst) {
61 case IR::Opcode::BoundImageGradient: 61 case IR::Opcode::BoundImageGradient:
62 case IR::Opcode::BindlessImageGradient: 62 case IR::Opcode::BindlessImageGradient:
63 return IR::Opcode::ImageGradient; 63 return IR::Opcode::ImageGradient;
64 case IR::Opcode::BoundImageRead:
65 case IR::Opcode::BindlessImageRead:
66 return IR::Opcode::ImageRead;
67 case IR::Opcode::BoundImageWrite:
68 case IR::Opcode::BindlessImageWrite:
69 return IR::Opcode::ImageWrite;
64 default: 70 default:
65 return IR::Opcode::Void; 71 return IR::Opcode::Void;
66 } 72 }
@@ -78,6 +84,8 @@ bool IsBindless(const IR::Inst& inst) {
78 case IR::Opcode::BindlessImageQueryDimensions: 84 case IR::Opcode::BindlessImageQueryDimensions:
79 case IR::Opcode::BindlessImageQueryLod: 85 case IR::Opcode::BindlessImageQueryLod:
80 case IR::Opcode::BindlessImageGradient: 86 case IR::Opcode::BindlessImageGradient:
87 case IR::Opcode::BindlessImageRead:
88 case IR::Opcode::BindlessImageWrite:
81 return true; 89 return true;
82 case IR::Opcode::BoundImageSampleImplicitLod: 90 case IR::Opcode::BoundImageSampleImplicitLod:
83 case IR::Opcode::BoundImageSampleExplicitLod: 91 case IR::Opcode::BoundImageSampleExplicitLod:
@@ -89,6 +97,8 @@ bool IsBindless(const IR::Inst& inst) {
89 case IR::Opcode::BoundImageQueryDimensions: 97 case IR::Opcode::BoundImageQueryDimensions:
90 case IR::Opcode::BoundImageQueryLod: 98 case IR::Opcode::BoundImageQueryLod:
91 case IR::Opcode::BoundImageGradient: 99 case IR::Opcode::BoundImageGradient:
100 case IR::Opcode::BoundImageRead:
101 case IR::Opcode::BoundImageWrite:
92 return false; 102 return false;
93 default: 103 default:
94 throw InvalidArgument("Invalid opcode {}", inst.GetOpcode()); 104 throw InvalidArgument("Invalid opcode {}", inst.GetOpcode());
@@ -147,10 +157,18 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) {
147 157
148class Descriptors { 158class Descriptors {
149public: 159public:
150 explicit Descriptors(TextureDescriptors& texture_descriptors_, 160 explicit Descriptors(TextureBufferDescriptors& texture_buffer_descriptors_,
151 TextureBufferDescriptors& texture_buffer_descriptors_) 161 TextureDescriptors& texture_descriptors_,
152 : texture_descriptors{texture_descriptors_}, texture_buffer_descriptors{ 162 ImageDescriptors& image_descriptors_)
153 texture_buffer_descriptors_} {} 163 : texture_buffer_descriptors{texture_buffer_descriptors_},
164 texture_descriptors{texture_descriptors_}, image_descriptors{image_descriptors_} {}
165
166 u32 Add(const TextureBufferDescriptor& desc) {
167 return Add(texture_buffer_descriptors, desc, [&desc](const auto& existing) {
168 return desc.cbuf_index == existing.cbuf_index &&
169 desc.cbuf_offset == existing.cbuf_offset;
170 });
171 }
154 172
155 u32 Add(const TextureDescriptor& desc) { 173 u32 Add(const TextureDescriptor& desc) {
156 return Add(texture_descriptors, desc, [&desc](const auto& existing) { 174 return Add(texture_descriptors, desc, [&desc](const auto& existing) {
@@ -159,11 +177,14 @@ public:
159 }); 177 });
160 } 178 }
161 179
162 u32 Add(const TextureBufferDescriptor& desc) { 180 u32 Add(const ImageDescriptor& desc) {
163 return Add(texture_buffer_descriptors, desc, [&desc](const auto& existing) { 181 const u32 index{Add(image_descriptors, desc, [&desc](const auto& existing) {
164 return desc.cbuf_index == existing.cbuf_index && 182 return desc.type == existing.type && desc.format == existing.format &&
183 desc.cbuf_index == existing.cbuf_index &&
165 desc.cbuf_offset == existing.cbuf_offset; 184 desc.cbuf_offset == existing.cbuf_offset;
166 }); 185 })};
186 image_descriptors[index].is_written |= desc.is_written;
187 return index;
167 } 188 }
168 189
169private: 190private:
@@ -178,8 +199,9 @@ private:
178 return static_cast<u32>(descriptors.size()) - 1; 199 return static_cast<u32>(descriptors.size()) - 1;
179 } 200 }
180 201
181 TextureDescriptors& texture_descriptors;
182 TextureBufferDescriptors& texture_buffer_descriptors; 202 TextureBufferDescriptors& texture_buffer_descriptors;
203 TextureDescriptors& texture_descriptors;
204 ImageDescriptors& image_descriptors;
183}; 205};
184} // Anonymous namespace 206} // Anonymous namespace
185 207
@@ -201,8 +223,9 @@ void TexturePass(Environment& env, IR::Program& program) {
201 return lhs.cbuf.index < rhs.cbuf.index; 223 return lhs.cbuf.index < rhs.cbuf.index;
202 }); 224 });
203 Descriptors descriptors{ 225 Descriptors descriptors{
204 program.info.texture_descriptors,
205 program.info.texture_buffer_descriptors, 226 program.info.texture_buffer_descriptors,
227 program.info.texture_descriptors,
228 program.info.image_descriptors,
206 }; 229 };
207 for (TextureInst& texture_inst : to_replace) { 230 for (TextureInst& texture_inst : to_replace) {
208 // TODO: Handle arrays 231 // TODO: Handle arrays
@@ -233,19 +256,41 @@ void TexturePass(Environment& env, IR::Program& program) {
233 break; 256 break;
234 } 257 }
235 u32 index; 258 u32 index;
236 if (flags.type == TextureType::Buffer) { 259 switch (inst->GetOpcode()) {
237 index = descriptors.Add(TextureBufferDescriptor{ 260 case IR::Opcode::ImageRead:
238 .cbuf_index = cbuf.index, 261 case IR::Opcode::ImageWrite: {
239 .cbuf_offset = cbuf.offset, 262 const bool is_written{inst->GetOpcode() == IR::Opcode::ImageWrite};
240 .count = 1, 263 if (flags.type == TextureType::Buffer) {
241 }); 264 throw NotImplementedException("Image buffer");
242 } else { 265 } else {
243 index = descriptors.Add(TextureDescriptor{ 266 index = descriptors.Add(ImageDescriptor{
244 .type = flags.type, 267 .type = flags.type,
245 .cbuf_index = cbuf.index, 268 .format = flags.image_format,
246 .cbuf_offset = cbuf.offset, 269 .is_written = is_written,
247 .count = 1, 270 .cbuf_index = cbuf.index,
248 }); 271 .cbuf_offset = cbuf.offset,
272 .count = 1,
273 });
274 }
275 break;
276 }
277 default:
278 if (flags.type == TextureType::Buffer) {
279 index = descriptors.Add(TextureBufferDescriptor{
280 .cbuf_index = cbuf.index,
281 .cbuf_offset = cbuf.offset,
282 .count = 1,
283 });
284 } else {
285 index = descriptors.Add(TextureDescriptor{
286 .type = flags.type,
287 .is_depth = flags.is_depth != 0,
288 .cbuf_index = cbuf.index,
289 .cbuf_offset = cbuf.offset,
290 .count = 1,
291 });
292 }
293 break;
249 } 294 }
250 inst->SetArg(0, IR::Value{index}); 295 inst->SetArg(0, IR::Value{index});
251 } 296 }