From 674f552ff1a1de499ae62a87de70d54606350d09 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Sat, 15 Nov 2025 19:41:26 -0400 Subject: [PATCH] [vk, texture_cache] Workaround for games with wrong usage of R32 with float samplers --- .../renderer_vulkan/vk_texture_cache.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index edd2c7b4a7..0745787945 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -2120,6 +2120,21 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI } } const auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format); + + // This causes validation errors and undefined behavior (flickering, missing geometry) on certain games + // Reinterpret R32_UINT as R32_SFLOAT for sampled images to match shader expectations + VkFormat view_format = format_info.format; + if (view_format == VK_FORMAT_R32_UINT && + !info.IsRenderTarget() && + (ImageUsageFlags(format_info, format) & VK_IMAGE_USAGE_SAMPLED_BIT)) { + // Only reinterpret if NOT used as storage image (storage requires matching types) + const bool is_storage = (ImageUsageFlags(format_info, format) & VK_IMAGE_USAGE_STORAGE_BIT) != 0; + if (!is_storage) { + view_format = VK_FORMAT_R32_SFLOAT; + LOG_DEBUG(Render_Vulkan, "Reinterpreting R32_UINT as R32_SFLOAT for sampled image compatibility"); + } + } + if (ImageUsageFlags(format_info, format) != image.UsageFlags()) { LOG_WARNING(Render_Vulkan, "Image view format {} has different usage flags than image format {}", format, @@ -2142,7 +2157,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI .flags = 0, .image = image.Handle(), .viewType = VkImageViewType{}, - .format = format_info.format, + .format = view_format, .components{ .r = requires_identity_swizzle ? VK_COMPONENT_SWIZZLE_IDENTITY : ComponentSwizzle(swizzle[0]), .g = requires_identity_swizzle ? VK_COMPONENT_SWIZZLE_IDENTITY : ComponentSwizzle(swizzle[1]),