diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index ee6532489..6151c5c65 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -773,8 +773,8 @@ spv::ImageFormat GetFormat(const AmdGpu::Image& image) { Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) { const auto image = desc.GetSharp(ctx.info); const auto format = desc.is_atomic ? GetFormat(image) : spv::ImageFormat::Unknown; - const auto type = desc.GetBoundType(image); - const u32 sampled = desc.IsStorage(image) ? 2 : 1; + const auto type = image.GetBoundType(desc.is_array); + const u32 sampled = desc.is_written ? 2 : 1; switch (type) { case AmdGpu::ImageType::Color1D: return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, false, false, sampled, format); @@ -799,7 +799,7 @@ void EmitContext::DefineImagesAndSamplers() { const auto sharp = image_desc.GetSharp(info); const auto nfmt = sharp.GetNumberFmt(); const bool is_integer = AmdGpu::IsInteger(nfmt); - const bool is_storage = image_desc.IsStorage(sharp); + const bool is_storage = image_desc.is_written; const VectorIds& data_types = GetAttributeType(*this, nfmt); const Id sampled_type = data_types[1]; const Id image_type{ImageType(*this, image_desc, sampled_type)}; @@ -814,7 +814,7 @@ void EmitContext::DefineImagesAndSamplers() { .sampled_type = is_storage ? sampled_type : TypeSampledImage(image_type), .pointer_type = pointer_type, .image_type = image_type, - .bound_type = image_desc.GetBoundType(sharp), + .bound_type = sharp.GetBoundType(image_desc.is_array), .is_integer = is_integer, .is_storage = is_storage, }); diff --git a/src/shader_recompiler/info.h b/src/shader_recompiler/info.h index b5f94cd8c..aeff346fa 100644 --- a/src/shader_recompiler/info.h +++ b/src/shader_recompiler/info.h @@ -70,49 +70,8 @@ struct ImageResource { bool is_depth{}; bool is_atomic{}; bool is_array{}; - bool is_read{}; bool is_written{}; - [[nodiscard]] AmdGpu::ImageType GetBoundType(const AmdGpu::Image& image) const noexcept { - const auto base_type = image.GetType(); - if (base_type == AmdGpu::ImageType::Color1DArray && !is_array) { - return AmdGpu::ImageType::Color1D; - } - if (base_type == AmdGpu::ImageType::Color2DArray && !is_array) { - return AmdGpu::ImageType::Color2D; - } - if (base_type == AmdGpu::ImageType::Color2DMsaaArray && !is_array) { - return AmdGpu::ImageType::Color2DMsaa; - } - return base_type; - } - - [[nodiscard]] u32 NumViewLevels(const AmdGpu::Image& image) const noexcept { - switch (GetBoundType(image)) { - case AmdGpu::ImageType::Color2DMsaa: - case AmdGpu::ImageType::Color2DMsaaArray: - return 1; - default: - return image.last_level - image.base_level + 1; - } - } - - [[nodiscard]] u32 NumViewLayers(const AmdGpu::Image image) const noexcept { - switch (GetBoundType(image)) { - case AmdGpu::ImageType::Color1D: - case AmdGpu::ImageType::Color2D: - case AmdGpu::ImageType::Color2DMsaa: - case AmdGpu::ImageType::Color3D: - return 1; - default: - return image.last_array - image.base_array + 1; - } - } - - [[nodiscard]] bool IsStorage(const AmdGpu::Image& image) const noexcept { - return is_written; - } - [[nodiscard]] constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept; }; using ImageResourceList = boost::container::small_vector; diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index c3d171585..c00b8e6bb 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -164,7 +164,6 @@ public: return desc.sharp_idx == existing.sharp_idx && desc.is_array == existing.is_array; })}; auto& image = image_resources[index]; - image.is_read |= desc.is_read; image.is_written |= desc.is_written; return index; } @@ -361,7 +360,6 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& image = AmdGpu::Image::Null(); } ASSERT(image.GetType() != AmdGpu::ImageType::Invalid); - const bool is_read = inst.GetOpcode() == IR::Opcode::ImageRead; const bool is_written = inst.GetOpcode() == IR::Opcode::ImageWrite; // Patch image instruction if image is FMask. @@ -402,7 +400,6 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& .is_depth = bool(inst_info.is_depth), .is_atomic = IsImageAtomicInstruction(inst), .is_array = bool(inst_info.is_array), - .is_read = is_read, .is_written = is_written, }); @@ -785,7 +782,7 @@ void PatchImageArgs(IR::Block& block, IR::Inst& inst, Info& info) { const auto lod = inst_info.has_lod ? IR::U32{arg} : IR::U32{}; const auto ms = has_ms ? IR::U32{arg} : IR::U32{}; - const auto is_storage = image_res.IsStorage(image); + const auto is_storage = image_res.is_written; if (inst.GetOpcode() == IR::Opcode::ImageRead) { auto texel = ir.ImageRead(handle, coords, lod, ms, inst_info); if (is_storage) { diff --git a/src/shader_recompiler/specialization.h b/src/shader_recompiler/specialization.h index c1020dab9..fcaeb8069 100644 --- a/src/shader_recompiler/specialization.h +++ b/src/shader_recompiler/specialization.h @@ -100,7 +100,7 @@ struct StageSpecialization { ForEachSharp(binding, buffers, info->buffers, [](auto& spec, const auto& desc, AmdGpu::Buffer sharp) { spec.stride = sharp.GetStride(); - spec.is_storage = desc.IsStorage(sharp); + spec.is_storage = desc.is_written; if (!spec.is_storage) { spec.size = sharp.GetSize(); } @@ -113,9 +113,9 @@ struct StageSpecialization { }); ForEachSharp(binding, images, info->images, [](auto& spec, const auto& desc, AmdGpu::Image sharp) { - spec.type = desc.GetBoundType(sharp); + spec.type = sharp.GetBoundType(desc.is_array); spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt()); - spec.is_storage = desc.IsStorage(sharp); + spec.is_storage = desc.is_written; if (spec.is_storage) { spec.dst_select = sharp.DstSelect(); } diff --git a/src/video_core/amdgpu/resource.h b/src/video_core/amdgpu/resource.h index b8c20dcc2..3dc1eadde 100644 --- a/src/video_core/amdgpu/resource.h +++ b/src/video_core/amdgpu/resource.h @@ -287,6 +287,42 @@ struct Image { return GetDataFmt() >= DataFormat::FormatFmask8_1 && GetDataFmt() <= DataFormat::FormatFmask64_8; } + + [[nodiscard]] ImageType GetBoundType(const bool is_array) const noexcept { + const auto base_type = GetType(); + if (base_type == ImageType::Color1DArray && !is_array) { + return ImageType::Color1D; + } + if (base_type == ImageType::Color2DArray && !is_array) { + return ImageType::Color2D; + } + if (base_type == ImageType::Color2DMsaaArray && !is_array) { + return ImageType::Color2DMsaa; + } + return base_type; + } + + [[nodiscard]] u32 NumViewLevels(const bool is_array) const noexcept { + switch (GetBoundType(is_array)) { + case ImageType::Color2DMsaa: + case ImageType::Color2DMsaaArray: + return 1; + default: + return last_level - base_level + 1; + } + } + + [[nodiscard]] u32 NumViewLayers(const bool is_array) const noexcept { + switch (GetBoundType(is_array)) { + case ImageType::Color1D: + case ImageType::Color2D: + case ImageType::Color2DMsaa: + case ImageType::Color3D: + return 1; + default: + return last_array - base_array + 1; + } + } }; static_assert(sizeof(Image) == 32); // 256bits diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index b24767e8a..23faacfc2 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -59,9 +59,8 @@ ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler for (const auto& image : info->images) { bindings.push_back({ .binding = binding++, - .descriptorType = image.IsStorage(image.GetSharp(*info)) - ? vk::DescriptorType::eStorageImage - : vk::DescriptorType::eSampledImage, + .descriptorType = image.is_written ? vk::DescriptorType::eStorageImage + : vk::DescriptorType::eSampledImage, .descriptorCount = 1, .stageFlags = vk::ShaderStageFlagBits::eCompute, }); diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 0ca1bed8b..0154172d9 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -367,9 +367,8 @@ void GraphicsPipeline::BuildDescSetLayout() { for (const auto& image : stage->images) { bindings.push_back({ .binding = binding++, - .descriptorType = image.IsStorage(image.GetSharp(*stage)) - ? vk::DescriptorType::eStorageImage - : vk::DescriptorType::eSampledImage, + .descriptorType = image.is_written ? vk::DescriptorType::eStorageImage + : vk::DescriptorType::eSampledImage, .descriptorCount = 1, .stageFlags = gp_stage_flags, }); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index e8616550b..ceb1d094d 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -661,7 +661,7 @@ void Rasterizer::BindTextures(const Shader::Info& stage, Shader::Backend::Bindin if (image->binding.is_bound) { // The image is already bound. In case if it is about to be used as storage we need // to force general layout on it. - image->binding.force_general |= image_desc.IsStorage(tsharp); + image->binding.force_general |= image_desc.is_written; } if (image->binding.is_target) { // The image is already bound as target. Since we read and output to it need to force diff --git a/src/video_core/texture_cache/image_view.cpp b/src/video_core/texture_cache/image_view.cpp index 22ede4402..569238168 100644 --- a/src/video_core/texture_cache/image_view.cpp +++ b/src/video_core/texture_cache/image_view.cpp @@ -30,7 +30,7 @@ vk::ImageViewType ConvertImageViewType(AmdGpu::ImageType type) { } ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageResource& desc) noexcept - : is_storage{desc.IsStorage(image)} { + : is_storage{desc.is_written} { const auto dfmt = image.GetDataFmt(); auto nfmt = image.GetNumberFmt(); if (is_storage && nfmt == AmdGpu::NumberFormat::Srgb) { @@ -43,9 +43,9 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageReso range.base.level = image.base_level; range.base.layer = image.base_array; - range.extent.levels = desc.NumViewLevels(image); - range.extent.layers = desc.NumViewLayers(image); - type = ConvertImageViewType(desc.GetBoundType(image)); + range.extent.levels = image.NumViewLevels(desc.is_array); + range.extent.layers = image.NumViewLayers(desc.is_array); + type = ConvertImageViewType(image.GetBoundType(desc.is_array)); if (!is_storage) { mapping = Vulkan::LiverpoolToVK::ComponentMapping(image.DstSelect()); diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 944f021df..69907f000 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -65,7 +65,7 @@ public: struct TextureDesc : public BaseDesc { TextureDesc() = default; TextureDesc(const AmdGpu::Image& image, const Shader::ImageResource& desc) - : BaseDesc{desc.IsStorage(image) ? BindingType::Storage : BindingType::Texture, + : BaseDesc{desc.is_written ? BindingType::Storage : BindingType::Texture, ImageInfo{image, desc}, ImageViewInfo{image, desc}} {} };