diff options
Diffstat (limited to 'src/shader_recompiler/backend')
| -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 |
3 files changed, 58 insertions, 22 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); |