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/backend/spirv/emit_context.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/backend/spirv/emit_context.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.cpp | 97 |
1 files changed, 76 insertions, 21 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 0c114402b..32f8c4508 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -18,41 +18,70 @@ namespace { | |||
| 18 | Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) { | 18 | Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) { |
| 19 | const spv::ImageFormat format{spv::ImageFormat::Unknown}; | 19 | const spv::ImageFormat format{spv::ImageFormat::Unknown}; |
| 20 | const Id type{ctx.F32[1]}; | 20 | const Id type{ctx.F32[1]}; |
| 21 | const bool depth{desc.is_depth}; | ||
| 21 | switch (desc.type) { | 22 | switch (desc.type) { |
| 22 | case TextureType::Color1D: | 23 | case TextureType::Color1D: |
| 23 | return ctx.TypeImage(type, spv::Dim::Dim1D, false, false, false, 1, format); | 24 | return ctx.TypeImage(type, spv::Dim::Dim1D, depth, false, false, 1, format); |
| 24 | case TextureType::ColorArray1D: | 25 | case TextureType::ColorArray1D: |
| 25 | return ctx.TypeImage(type, spv::Dim::Dim1D, false, true, false, 1, format); | 26 | return ctx.TypeImage(type, spv::Dim::Dim1D, depth, true, false, 1, format); |
| 26 | case TextureType::Color2D: | 27 | case TextureType::Color2D: |
| 27 | return ctx.TypeImage(type, spv::Dim::Dim2D, false, false, false, 1, format); | 28 | return ctx.TypeImage(type, spv::Dim::Dim2D, depth, false, false, 1, format); |
| 28 | case TextureType::ColorArray2D: | 29 | case TextureType::ColorArray2D: |
| 29 | return ctx.TypeImage(type, spv::Dim::Dim2D, false, true, false, 1, format); | 30 | return ctx.TypeImage(type, spv::Dim::Dim2D, depth, true, false, 1, format); |
| 30 | case TextureType::Color3D: | 31 | case TextureType::Color3D: |
| 31 | return ctx.TypeImage(type, spv::Dim::Dim3D, false, false, false, 1, format); | 32 | return ctx.TypeImage(type, spv::Dim::Dim3D, depth, false, false, 1, format); |
| 32 | case TextureType::ColorCube: | 33 | case TextureType::ColorCube: |
| 33 | return ctx.TypeImage(type, spv::Dim::Cube, false, false, false, 1, format); | 34 | return ctx.TypeImage(type, spv::Dim::Cube, depth, false, false, 1, format); |
| 34 | case TextureType::ColorArrayCube: | 35 | case TextureType::ColorArrayCube: |
| 35 | return ctx.TypeImage(type, spv::Dim::Cube, false, true, false, 1, format); | 36 | return ctx.TypeImage(type, spv::Dim::Cube, depth, true, false, 1, format); |
| 36 | case TextureType::Shadow1D: | ||
| 37 | return ctx.TypeImage(type, spv::Dim::Dim1D, true, false, false, 1, format); | ||
| 38 | case TextureType::ShadowArray1D: | ||
| 39 | return ctx.TypeImage(type, spv::Dim::Dim1D, true, true, false, 1, format); | ||
| 40 | case TextureType::Shadow2D: | ||
| 41 | return ctx.TypeImage(type, spv::Dim::Dim2D, true, false, false, 1, format); | ||
| 42 | case TextureType::ShadowArray2D: | ||
| 43 | return ctx.TypeImage(type, spv::Dim::Dim2D, true, true, false, 1, format); | ||
| 44 | case TextureType::Shadow3D: | ||
| 45 | return ctx.TypeImage(type, spv::Dim::Dim3D, true, false, false, 1, format); | ||
| 46 | case TextureType::ShadowCube: | ||
| 47 | return ctx.TypeImage(type, spv::Dim::Cube, true, false, false, 1, format); | ||
| 48 | case TextureType::ShadowArrayCube: | ||
| 49 | return ctx.TypeImage(type, spv::Dim::Cube, true, true, false, 1, format); | ||
| 50 | case TextureType::Buffer: | 37 | case TextureType::Buffer: |
| 51 | break; | 38 | break; |
| 52 | } | 39 | } |
| 53 | throw InvalidArgument("Invalid texture type {}", desc.type); | 40 | throw InvalidArgument("Invalid texture type {}", desc.type); |
| 54 | } | 41 | } |
| 55 | 42 | ||
| 43 | Id ImageType(EmitContext& ctx, const ImageDescriptor& desc) { | ||
| 44 | const spv::ImageFormat format{[&] { | ||
| 45 | switch (desc.format) { | ||
| 46 | case ImageFormat::Typeless: | ||
| 47 | return spv::ImageFormat::Unknown; | ||
| 48 | case ImageFormat::R8_UINT: | ||
| 49 | return spv::ImageFormat::R8ui; | ||
| 50 | case ImageFormat::R8_SINT: | ||
| 51 | return spv::ImageFormat::R8i; | ||
| 52 | case ImageFormat::R16_UINT: | ||
| 53 | return spv::ImageFormat::R16ui; | ||
| 54 | case ImageFormat::R16_SINT: | ||
| 55 | return spv::ImageFormat::R16i; | ||
| 56 | case ImageFormat::R32_UINT: | ||
| 57 | return spv::ImageFormat::R32ui; | ||
| 58 | case ImageFormat::R32G32_UINT: | ||
| 59 | return spv::ImageFormat::Rg32ui; | ||
| 60 | case ImageFormat::R32G32B32A32_UINT: | ||
| 61 | return spv::ImageFormat::Rgba32ui; | ||
| 62 | } | ||
| 63 | throw InvalidArgument("Invalid image format {}", desc.format); | ||
| 64 | }()}; | ||
| 65 | const Id type{ctx.U32[1]}; | ||
| 66 | switch (desc.type) { | ||
| 67 | case TextureType::Color1D: | ||
| 68 | return ctx.TypeImage(type, spv::Dim::Dim1D, false, false, false, 2, format); | ||
| 69 | case TextureType::ColorArray1D: | ||
| 70 | return ctx.TypeImage(type, spv::Dim::Dim1D, false, true, false, 2, format); | ||
| 71 | case TextureType::Color2D: | ||
| 72 | return ctx.TypeImage(type, spv::Dim::Dim2D, false, false, false, 2, format); | ||
| 73 | case TextureType::ColorArray2D: | ||
| 74 | return ctx.TypeImage(type, spv::Dim::Dim2D, false, true, false, 2, format); | ||
| 75 | case TextureType::Color3D: | ||
| 76 | return ctx.TypeImage(type, spv::Dim::Dim3D, false, false, false, 2, format); | ||
| 77 | case TextureType::Buffer: | ||
| 78 | throw NotImplementedException("Image buffer"); | ||
| 79 | default: | ||
| 80 | break; | ||
| 81 | } | ||
| 82 | throw InvalidArgument("Invalid texture type {}", desc.type); | ||
| 83 | } | ||
| 84 | |||
| 56 | Id DefineVariable(EmitContext& ctx, Id type, std::optional<spv::BuiltIn> builtin, | 85 | Id DefineVariable(EmitContext& ctx, Id type, std::optional<spv::BuiltIn> builtin, |
| 57 | spv::StorageClass storage_class) { | 86 | spv::StorageClass storage_class) { |
| 58 | const Id pointer_type{ctx.TypePointer(storage_class, type)}; | 87 | const Id pointer_type{ctx.TypePointer(storage_class, type)}; |
| @@ -134,6 +163,7 @@ EmitContext::EmitContext(const Profile& profile_, IR::Program& program, u32& bin | |||
| 134 | DefineStorageBuffers(program.info, binding); | 163 | DefineStorageBuffers(program.info, binding); |
| 135 | DefineTextureBuffers(program.info, binding); | 164 | DefineTextureBuffers(program.info, binding); |
| 136 | DefineTextures(program.info, binding); | 165 | DefineTextures(program.info, binding); |
| 166 | DefineImages(program.info, binding); | ||
| 137 | DefineAttributeMemAccess(program.info); | 167 | DefineAttributeMemAccess(program.info); |
| 138 | DefineLabels(program); | 168 | DefineLabels(program); |
| 139 | } | 169 | } |
| @@ -572,6 +602,31 @@ void EmitContext::DefineTextures(const Info& info, u32& binding) { | |||
| 572 | } | 602 | } |
| 573 | } | 603 | } |
| 574 | 604 | ||
| 605 | void EmitContext::DefineImages(const Info& info, u32& binding) { | ||
| 606 | images.reserve(info.image_descriptors.size()); | ||
| 607 | for (const ImageDescriptor& desc : info.image_descriptors) { | ||
| 608 | if (desc.count != 1) { | ||
| 609 | throw NotImplementedException("Array of textures"); | ||
| 610 | } | ||
| 611 | const Id image_type{ImageType(*this, desc)}; | ||
| 612 | const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)}; | ||
| 613 | const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)}; | ||
| 614 | Decorate(id, spv::Decoration::Binding, binding); | ||
| 615 | Decorate(id, spv::Decoration::DescriptorSet, 0U); | ||
| 616 | Name(id, fmt::format("img{}_{:02x}", desc.cbuf_index, desc.cbuf_offset)); | ||
| 617 | for (u32 index = 0; index < desc.count; ++index) { | ||
| 618 | images.push_back(ImageDefinition{ | ||
| 619 | .id{id}, | ||
| 620 | .image_type{image_type}, | ||
| 621 | }); | ||
| 622 | } | ||
| 623 | if (profile.supported_spirv >= 0x00010400) { | ||
| 624 | interfaces.push_back(id); | ||
| 625 | } | ||
| 626 | binding += desc.count; | ||
| 627 | } | ||
| 628 | } | ||
| 629 | |||
| 575 | void EmitContext::DefineLabels(IR::Program& program) { | 630 | void EmitContext::DefineLabels(IR::Program& program) { |
| 576 | for (IR::Block* const block : program.blocks) { | 631 | for (IR::Block* const block : program.blocks) { |
| 577 | block->SetDefinition(OpLabel()); | 632 | block->SetDefinition(OpLabel()); |