From 8ed05425dddf17aeafa4daa751cb3a3a13c5a31b Mon Sep 17 00:00:00 2001 From: wildcard Date: Thu, 28 Aug 2025 05:21:05 +0200 Subject: [PATCH] [Vulkan][TextureCache] Always use identity-swizzled views for storage images (#321) Validation flagged writes to a VK_DESCRIPTOR_TYPE_STORAGE_IMAGE descriptor because the bound VkImageView had a non-identity component mapping and hence the vuid-00336 error, this fixes the said error. ------ This commit helps to fix some graphical issues on games like Trident's Tale, where game didn't render anything than just plain terrain, helps to stabilize Nier Automata graphical issues, meanwhile the most annoying glitches are gone, there's still remain other issues. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/321 Reviewed-by: CamilleLaVey Co-authored-by: wildcard Co-committed-by: wildcard --- .../renderer_vulkan/vk_texture_cache.cpp | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index ba58060d20..eda9ff2a5a 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -2160,20 +2160,34 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type, if (!image_handle) { return VK_NULL_HANDLE; } - if (image_format == Shader::ImageFormat::Typeless) { - return Handle(texture_type); - } - const bool is_signed{image_format == Shader::ImageFormat::R8_SINT || - image_format == Shader::ImageFormat::R16_SINT}; + if (!storage_views) { storage_views = std::make_unique(); } - auto& views{is_signed ? storage_views->signeds : storage_views->unsigneds}; - auto& view{views[static_cast(texture_type)]}; - if (view) { + + // Storage images MUST use identity component mapping. + // Typeless: use the underlying image's native format. + if (image_format == Shader::ImageFormat::Typeless) { + auto& view = storage_views->unsigneds[static_cast(texture_type)]; + if (view) { + return *view; + } + const auto fmt_info = + MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, /*is_image=*/true, format); + const VkFormat vk_format = fmt_info.format; + // Storage images are color-aspect only + view = MakeView(vk_format, VK_IMAGE_ASPECT_COLOR_BIT); // identity components inside return *view; } - view = MakeView(Format(image_format), VK_IMAGE_ASPECT_COLOR_BIT); + const bool is_signed = (image_format == Shader::ImageFormat::R8_SINT ||image_format == Shader::ImageFormat::R16_SINT); + auto& views = is_signed ? storage_views->signeds : storage_views->unsigneds; + auto& view = views[static_cast(texture_type)]; + if (view) { + return *view; + } + + const VkFormat vk_format = Format(image_format); + view = MakeView(vk_format, VK_IMAGE_ASPECT_COLOR_BIT);// identity components inside return *view; }