|
|
|
@ -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]), |
|
|
|
|