From c05e48becbcd94ace3eb8d21a036b1f6430fd88f Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Tue, 7 Jan 2025 02:50:58 -0800 Subject: [PATCH] shader_recompiler: Account for instruction array flag in image type. --- .../backend/spirv/emit_spirv_image.cpp | 6 +++--- .../backend/spirv/spirv_emit_context.cpp | 3 ++- .../backend/spirv/spirv_emit_context.h | 1 + src/shader_recompiler/info.h | 17 ++++++++++++++++- src/shader_recompiler/specialization.h | 2 +- src/video_core/amdgpu/resource.h | 4 ---- src/video_core/texture_cache/image_view.cpp | 2 +- 7 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index c3d937fe7..68a8182e5 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -172,15 +172,15 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod const auto& texture = ctx.images[handle & 0xFFFF]; const Id image = ctx.OpLoad(texture.image_type, texture.id); const auto sharp = ctx.info.images[handle & 0xFFFF].GetSharp(ctx.info); - const auto type = sharp.GetBoundType(); const Id zero = ctx.u32_zero_value; const auto mips{[&] { return has_mips ? ctx.OpImageQueryLevels(ctx.U32[1], image) : zero; }}; - const bool uses_lod{type != AmdGpu::ImageType::Color2DMsaa && !texture.is_storage}; + const bool uses_lod{texture.bound_type != AmdGpu::ImageType::Color2DMsaa && + !texture.is_storage}; const auto query{[&](Id type) { return uses_lod ? ctx.OpImageQuerySizeLod(type, image, lod) : ctx.OpImageQuerySize(type, image); }}; - switch (type) { + switch (texture.bound_type) { case AmdGpu::ImageType::Color1D: return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips()); case AmdGpu::ImageType::Color1DArray: diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 575bf91f7..5df5f4ee4 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -773,7 +773,7 @@ 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 = image.GetBoundType(); + const auto type = desc.GetBoundType(image); const u32 sampled = desc.IsStorage(image) ? 2 : 1; switch (type) { case AmdGpu::ImageType::Color1D: @@ -817,6 +817,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), .is_integer = is_integer, .is_storage = is_storage, }); diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index 583d96b99..80d0d4d9f 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h @@ -222,6 +222,7 @@ public: Id sampled_type; Id pointer_type; Id image_type; + AmdGpu::ImageType bound_type; bool is_integer = false; bool is_storage = false; }; diff --git a/src/shader_recompiler/info.h b/src/shader_recompiler/info.h index b6ac12785..963faab8b 100644 --- a/src/shader_recompiler/info.h +++ b/src/shader_recompiler/info.h @@ -73,9 +73,24 @@ struct ImageResource { bool is_read{}; bool is_written{}; + 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 (image.IsPartialCubemap()) { + // Partial cube map + return AmdGpu::ImageType::Color2DArray; + } + return base_type; + } + [[nodiscard]] bool IsStorage(const AmdGpu::Image& image) const noexcept { // Need cube as storage when used with ImageRead. - return is_written || (is_read && image.GetBoundType() == AmdGpu::ImageType::Cube); + return is_written || (is_read && GetBoundType(image) == AmdGpu::ImageType::Cube); } [[nodiscard]] constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept; diff --git a/src/shader_recompiler/specialization.h b/src/shader_recompiler/specialization.h index f58d2e2d3..c1020dab9 100644 --- a/src/shader_recompiler/specialization.h +++ b/src/shader_recompiler/specialization.h @@ -113,7 +113,7 @@ struct StageSpecialization { }); ForEachSharp(binding, images, info->images, [](auto& spec, const auto& desc, AmdGpu::Image sharp) { - spec.type = sharp.GetBoundType(); + spec.type = desc.GetBoundType(sharp); spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt()); spec.is_storage = desc.IsStorage(sharp); if (spec.is_storage) { diff --git a/src/video_core/amdgpu/resource.h b/src/video_core/amdgpu/resource.h index ffee7964a..e4e442498 100644 --- a/src/video_core/amdgpu/resource.h +++ b/src/video_core/amdgpu/resource.h @@ -293,10 +293,6 @@ struct Image { const auto viewed_slice = last_array - base_array + 1; return GetType() == ImageType::Cube && viewed_slice < 6; } - - ImageType GetBoundType() const noexcept { - return IsPartialCubemap() ? ImageType::Color2DArray : GetType(); - } }; static_assert(sizeof(Image) == 32); // 256bits diff --git a/src/video_core/texture_cache/image_view.cpp b/src/video_core/texture_cache/image_view.cpp index 68b116558..73fe8f35e 100644 --- a/src/video_core/texture_cache/image_view.cpp +++ b/src/video_core/texture_cache/image_view.cpp @@ -51,7 +51,7 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageReso range.extent.levels = image.last_level - image.base_level + 1; } range.extent.layers = image.last_array - image.base_array + 1; - type = ConvertImageViewType(image.GetBoundType()); + type = ConvertImageViewType(desc.GetBoundType(image)); // Adjust view type for arrays if (type == vk::ImageViewType::eCube) {