diff options
| author | 2021-04-09 01:45:39 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:26 -0400 | |
| commit | 7cb2ab358517d95ebcd35c94c72b9e91762906c3 (patch) | |
| tree | 3f75959e255026665a4dde406cb8c4cc34fb45a0 /src/shader_recompiler/ir_opt/texture_pass.cpp | |
| parent | shader: Fix Windows build issues (diff) | |
| download | yuzu-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.cpp | 91 |
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 | ||
| 148 | class Descriptors { | 158 | class Descriptors { |
| 149 | public: | 159 | public: |
| 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 | ||
| 169 | private: | 190 | private: |
| @@ -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 | } |