diff options
Diffstat (limited to '')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.cpp | 70 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.h | 7 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | 3 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/texture_pass.cpp | 19 | ||||
| -rw-r--r-- | src/shader_recompiler/shader_info.h | 10 |
5 files changed, 86 insertions, 23 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index f96d5ae37..032cf5e03 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -54,28 +54,30 @@ Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) { | |||
| 54 | throw InvalidArgument("Invalid texture type {}", desc.type); | 54 | throw InvalidArgument("Invalid texture type {}", desc.type); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | spv::ImageFormat GetImageFormat(ImageFormat format) { | ||
| 58 | switch (format) { | ||
| 59 | case ImageFormat::Typeless: | ||
| 60 | return spv::ImageFormat::Unknown; | ||
| 61 | case ImageFormat::R8_UINT: | ||
| 62 | return spv::ImageFormat::R8ui; | ||
| 63 | case ImageFormat::R8_SINT: | ||
| 64 | return spv::ImageFormat::R8i; | ||
| 65 | case ImageFormat::R16_UINT: | ||
| 66 | return spv::ImageFormat::R16ui; | ||
| 67 | case ImageFormat::R16_SINT: | ||
| 68 | return spv::ImageFormat::R16i; | ||
| 69 | case ImageFormat::R32_UINT: | ||
| 70 | return spv::ImageFormat::R32ui; | ||
| 71 | case ImageFormat::R32G32_UINT: | ||
| 72 | return spv::ImageFormat::Rg32ui; | ||
| 73 | case ImageFormat::R32G32B32A32_UINT: | ||
| 74 | return spv::ImageFormat::Rgba32ui; | ||
| 75 | } | ||
| 76 | throw InvalidArgument("Invalid image format {}", format); | ||
| 77 | } | ||
| 78 | |||
| 57 | Id ImageType(EmitContext& ctx, const ImageDescriptor& desc) { | 79 | Id ImageType(EmitContext& ctx, const ImageDescriptor& desc) { |
| 58 | const spv::ImageFormat format{[&] { | 80 | const spv::ImageFormat format{GetImageFormat(desc.format)}; |
| 59 | switch (desc.format) { | ||
| 60 | case ImageFormat::Typeless: | ||
| 61 | return spv::ImageFormat::Unknown; | ||
| 62 | case ImageFormat::R8_UINT: | ||
| 63 | return spv::ImageFormat::R8ui; | ||
| 64 | case ImageFormat::R8_SINT: | ||
| 65 | return spv::ImageFormat::R8i; | ||
| 66 | case ImageFormat::R16_UINT: | ||
| 67 | return spv::ImageFormat::R16ui; | ||
| 68 | case ImageFormat::R16_SINT: | ||
| 69 | return spv::ImageFormat::R16i; | ||
| 70 | case ImageFormat::R32_UINT: | ||
| 71 | return spv::ImageFormat::R32ui; | ||
| 72 | case ImageFormat::R32G32_UINT: | ||
| 73 | return spv::ImageFormat::Rg32ui; | ||
| 74 | case ImageFormat::R32G32B32A32_UINT: | ||
| 75 | return spv::ImageFormat::Rgba32ui; | ||
| 76 | } | ||
| 77 | throw InvalidArgument("Invalid image format {}", desc.format); | ||
| 78 | }()}; | ||
| 79 | const Id type{ctx.U32[1]}; | 81 | const Id type{ctx.U32[1]}; |
| 80 | switch (desc.type) { | 82 | switch (desc.type) { |
| 81 | case TextureType::Color1D: | 83 | case TextureType::Color1D: |
| @@ -388,6 +390,7 @@ EmitContext::EmitContext(const Profile& profile_, IR::Program& program, u32& bin | |||
| 388 | DefineConstantBuffers(program.info, binding); | 390 | DefineConstantBuffers(program.info, binding); |
| 389 | DefineStorageBuffers(program.info, binding); | 391 | DefineStorageBuffers(program.info, binding); |
| 390 | DefineTextureBuffers(program.info, binding); | 392 | DefineTextureBuffers(program.info, binding); |
| 393 | DefineImageBuffers(program.info, binding); | ||
| 391 | DefineTextures(program.info, binding); | 394 | DefineTextures(program.info, binding); |
| 392 | DefineImages(program.info, binding); | 395 | DefineImages(program.info, binding); |
| 393 | DefineAttributeMemAccess(program.info); | 396 | DefineAttributeMemAccess(program.info); |
| @@ -883,6 +886,31 @@ void EmitContext::DefineTextureBuffers(const Info& info, u32& binding) { | |||
| 883 | } | 886 | } |
| 884 | } | 887 | } |
| 885 | 888 | ||
| 889 | void EmitContext::DefineImageBuffers(const Info& info, u32& binding) { | ||
| 890 | image_buffers.reserve(info.image_buffer_descriptors.size()); | ||
| 891 | for (const ImageBufferDescriptor& desc : info.image_buffer_descriptors) { | ||
| 892 | if (desc.count != 1) { | ||
| 893 | throw NotImplementedException("Array of image buffers"); | ||
| 894 | } | ||
| 895 | const spv::ImageFormat format{GetImageFormat(desc.format)}; | ||
| 896 | const Id image_type{TypeImage(U32[4], spv::Dim::Buffer, false, false, false, 2, format)}; | ||
| 897 | const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)}; | ||
| 898 | const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)}; | ||
| 899 | Decorate(id, spv::Decoration::Binding, binding); | ||
| 900 | Decorate(id, spv::Decoration::DescriptorSet, 0U); | ||
| 901 | Name(id, fmt::format("imgbuf{}_{:02x}", desc.cbuf_index, desc.cbuf_offset)); | ||
| 902 | const ImageBufferDefinition def{ | ||
| 903 | .id = id, | ||
| 904 | .image_type = image_type, | ||
| 905 | }; | ||
| 906 | image_buffers.insert(image_buffers.end(), desc.count, def); | ||
| 907 | if (profile.supported_spirv >= 0x00010400) { | ||
| 908 | interfaces.push_back(id); | ||
| 909 | } | ||
| 910 | binding += desc.count; | ||
| 911 | } | ||
| 912 | } | ||
| 913 | |||
| 886 | void EmitContext::DefineTextures(const Info& info, u32& binding) { | 914 | void EmitContext::DefineTextures(const Info& info, u32& binding) { |
| 887 | textures.reserve(info.texture_descriptors.size()); | 915 | textures.reserve(info.texture_descriptors.size()); |
| 888 | for (const TextureDescriptor& desc : info.texture_descriptors) { | 916 | for (const TextureDescriptor& desc : info.texture_descriptors) { |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index 1f0d8be77..0da14d5f8 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h | |||
| @@ -35,6 +35,11 @@ struct TextureDefinition { | |||
| 35 | Id image_type; | 35 | Id image_type; |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | struct ImageBufferDefinition { | ||
| 39 | Id id; | ||
| 40 | Id image_type; | ||
| 41 | }; | ||
| 42 | |||
| 38 | struct ImageDefinition { | 43 | struct ImageDefinition { |
| 39 | Id id; | 44 | Id id; |
| 40 | Id image_type; | 45 | Id image_type; |
| @@ -136,6 +141,7 @@ public: | |||
| 136 | std::array<UniformDefinitions, Info::MAX_CBUFS> cbufs{}; | 141 | std::array<UniformDefinitions, Info::MAX_CBUFS> cbufs{}; |
| 137 | std::array<StorageDefinitions, Info::MAX_SSBOS> ssbos{}; | 142 | std::array<StorageDefinitions, Info::MAX_SSBOS> ssbos{}; |
| 138 | std::vector<Id> texture_buffers; | 143 | std::vector<Id> texture_buffers; |
| 144 | std::vector<ImageBufferDefinition> image_buffers; | ||
| 139 | std::vector<TextureDefinition> textures; | 145 | std::vector<TextureDefinition> textures; |
| 140 | std::vector<ImageDefinition> images; | 146 | std::vector<ImageDefinition> images; |
| 141 | 147 | ||
| @@ -213,6 +219,7 @@ private: | |||
| 213 | void DefineConstantBuffers(const Info& info, u32& binding); | 219 | void DefineConstantBuffers(const Info& info, u32& binding); |
| 214 | void DefineStorageBuffers(const Info& info, u32& binding); | 220 | void DefineStorageBuffers(const Info& info, u32& binding); |
| 215 | void DefineTextureBuffers(const Info& info, u32& binding); | 221 | void DefineTextureBuffers(const Info& info, u32& binding); |
| 222 | void DefineImageBuffers(const Info& info, u32& binding); | ||
| 216 | void DefineTextures(const Info& info, u32& binding); | 223 | void DefineTextures(const Info& info, u32& binding); |
| 217 | void DefineImages(const Info& info, u32& binding); | 224 | void DefineImages(const Info& info, u32& binding); |
| 218 | void DefineAttributeMemAccess(const Info& info); | 225 | void DefineAttributeMemAccess(const Info& info); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 17266ce77..c8d1d25b1 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | |||
| @@ -149,7 +149,8 @@ Id Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) { | |||
| 149 | throw NotImplementedException("Indirect image indexing"); | 149 | throw NotImplementedException("Indirect image indexing"); |
| 150 | } | 150 | } |
| 151 | if (info.type == TextureType::Buffer) { | 151 | if (info.type == TextureType::Buffer) { |
| 152 | throw NotImplementedException("Image buffer"); | 152 | const ImageBufferDefinition def{ctx.image_buffers.at(index.U32())}; |
| 153 | return ctx.OpLoad(def.image_type, def.id); | ||
| 153 | } else { | 154 | } else { |
| 154 | const ImageDefinition def{ctx.images.at(index.U32())}; | 155 | const ImageDefinition def{ctx.images.at(index.U32())}; |
| 155 | return ctx.OpLoad(def.image_type, def.id); | 156 | return ctx.OpLoad(def.image_type, def.id); |
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index a7b1fcfad..e1d5a2ce1 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp | |||
| @@ -158,9 +158,11 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) { | |||
| 158 | class Descriptors { | 158 | class Descriptors { |
| 159 | public: | 159 | public: |
| 160 | explicit Descriptors(TextureBufferDescriptors& texture_buffer_descriptors_, | 160 | explicit Descriptors(TextureBufferDescriptors& texture_buffer_descriptors_, |
| 161 | ImageBufferDescriptors& image_buffer_descriptors_, | ||
| 161 | TextureDescriptors& texture_descriptors_, | 162 | TextureDescriptors& texture_descriptors_, |
| 162 | ImageDescriptors& image_descriptors_) | 163 | ImageDescriptors& image_descriptors_) |
| 163 | : texture_buffer_descriptors{texture_buffer_descriptors_}, | 164 | : texture_buffer_descriptors{texture_buffer_descriptors_}, |
| 165 | image_buffer_descriptors{image_buffer_descriptors_}, | ||
| 164 | texture_descriptors{texture_descriptors_}, image_descriptors{image_descriptors_} {} | 166 | texture_descriptors{texture_descriptors_}, image_descriptors{image_descriptors_} {} |
| 165 | 167 | ||
| 166 | u32 Add(const TextureBufferDescriptor& desc) { | 168 | u32 Add(const TextureBufferDescriptor& desc) { |
| @@ -170,6 +172,13 @@ public: | |||
| 170 | }); | 172 | }); |
| 171 | } | 173 | } |
| 172 | 174 | ||
| 175 | u32 Add(const ImageBufferDescriptor& desc) { | ||
| 176 | return Add(image_buffer_descriptors, desc, [&desc](const auto& existing) { | ||
| 177 | return desc.format == existing.format && desc.cbuf_index == existing.cbuf_index && | ||
| 178 | desc.cbuf_offset == existing.cbuf_offset; | ||
| 179 | }); | ||
| 180 | } | ||
| 181 | |||
| 173 | u32 Add(const TextureDescriptor& desc) { | 182 | u32 Add(const TextureDescriptor& desc) { |
| 174 | return Add(texture_descriptors, desc, [&desc](const auto& existing) { | 183 | return Add(texture_descriptors, desc, [&desc](const auto& existing) { |
| 175 | return desc.cbuf_index == existing.cbuf_index && | 184 | return desc.cbuf_index == existing.cbuf_index && |
| @@ -200,6 +209,7 @@ private: | |||
| 200 | } | 209 | } |
| 201 | 210 | ||
| 202 | TextureBufferDescriptors& texture_buffer_descriptors; | 211 | TextureBufferDescriptors& texture_buffer_descriptors; |
| 212 | ImageBufferDescriptors& image_buffer_descriptors; | ||
| 203 | TextureDescriptors& texture_descriptors; | 213 | TextureDescriptors& texture_descriptors; |
| 204 | ImageDescriptors& image_descriptors; | 214 | ImageDescriptors& image_descriptors; |
| 205 | }; | 215 | }; |
| @@ -224,6 +234,7 @@ void TexturePass(Environment& env, IR::Program& program) { | |||
| 224 | }); | 234 | }); |
| 225 | Descriptors descriptors{ | 235 | Descriptors descriptors{ |
| 226 | program.info.texture_buffer_descriptors, | 236 | program.info.texture_buffer_descriptors, |
| 237 | program.info.image_buffer_descriptors, | ||
| 227 | program.info.texture_descriptors, | 238 | program.info.texture_descriptors, |
| 228 | program.info.image_descriptors, | 239 | program.info.image_descriptors, |
| 229 | }; | 240 | }; |
| @@ -261,7 +272,13 @@ void TexturePass(Environment& env, IR::Program& program) { | |||
| 261 | case IR::Opcode::ImageWrite: { | 272 | case IR::Opcode::ImageWrite: { |
| 262 | const bool is_written{inst->GetOpcode() == IR::Opcode::ImageWrite}; | 273 | const bool is_written{inst->GetOpcode() == IR::Opcode::ImageWrite}; |
| 263 | if (flags.type == TextureType::Buffer) { | 274 | if (flags.type == TextureType::Buffer) { |
| 264 | throw NotImplementedException("Image buffer"); | 275 | index = descriptors.Add(ImageBufferDescriptor{ |
| 276 | .format = flags.image_format, | ||
| 277 | .is_written = is_written, | ||
| 278 | .cbuf_index = cbuf.index, | ||
| 279 | .cbuf_offset = cbuf.offset, | ||
| 280 | .count = 1, | ||
| 281 | }); | ||
| 265 | } else { | 282 | } else { |
| 266 | index = descriptors.Add(ImageDescriptor{ | 283 | index = descriptors.Add(ImageDescriptor{ |
| 267 | .type = flags.type, | 284 | .type = flags.type, |
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index e078b0fa1..336c6131a 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h | |||
| @@ -67,6 +67,15 @@ struct TextureBufferDescriptor { | |||
| 67 | }; | 67 | }; |
| 68 | using TextureBufferDescriptors = boost::container::small_vector<TextureBufferDescriptor, 6>; | 68 | using TextureBufferDescriptors = boost::container::small_vector<TextureBufferDescriptor, 6>; |
| 69 | 69 | ||
| 70 | struct ImageBufferDescriptor { | ||
| 71 | ImageFormat format; | ||
| 72 | bool is_written; | ||
| 73 | u32 cbuf_index; | ||
| 74 | u32 cbuf_offset; | ||
| 75 | u32 count; | ||
| 76 | }; | ||
| 77 | using ImageBufferDescriptors = boost::container::small_vector<ImageBufferDescriptor, 2>; | ||
| 78 | |||
| 70 | struct TextureDescriptor { | 79 | struct TextureDescriptor { |
| 71 | TextureType type; | 80 | TextureType type; |
| 72 | bool is_depth; | 81 | bool is_depth; |
| @@ -153,6 +162,7 @@ struct Info { | |||
| 153 | constant_buffer_descriptors; | 162 | constant_buffer_descriptors; |
| 154 | boost::container::static_vector<StorageBufferDescriptor, MAX_SSBOS> storage_buffers_descriptors; | 163 | boost::container::static_vector<StorageBufferDescriptor, MAX_SSBOS> storage_buffers_descriptors; |
| 155 | TextureBufferDescriptors texture_buffer_descriptors; | 164 | TextureBufferDescriptors texture_buffer_descriptors; |
| 165 | ImageBufferDescriptors image_buffer_descriptors; | ||
| 156 | TextureDescriptors texture_descriptors; | 166 | TextureDescriptors texture_descriptors; |
| 157 | ImageDescriptors image_descriptors; | 167 | ImageDescriptors image_descriptors; |
| 158 | }; | 168 | }; |