From e7eb4dba78eb8ae13b3b15d433bdc383860c990e Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Sun, 23 Nov 2025 14:46:48 -0400 Subject: [PATCH] [vk, texture_cache, vendor] Adding path for hardware resolve on shader stencil export/ MSAA image blits --- .../renderer_vulkan/vk_texture_cache.cpp | 11 ++++++++ .../vulkan_common/vulkan_device.cpp | 26 +++++++++++++++++-- src/video_core/vulkan_common/vulkan_device.h | 8 ++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 136a11f78d..baddfe8cbf 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1104,6 +1104,8 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst UNREACHABLE(); } }(); + // Use shader-based depth/stencil blits if hardware doesn't support the format + // Note: MSAA resolves (MSAA->single) use vkCmdResolveImage which works fine if (!can_blit_depth_stencil) { UNIMPLEMENTED_IF(is_src_msaa || is_dst_msaa); blit_image_helper.BlitDepthStencil(dst_framebuffer, src, dst_region, src_region, @@ -1118,6 +1120,15 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst const VkImage src_image = src.ImageHandle(); const VkImageSubresourceLayers dst_layers = MakeSubresourceLayers(&dst); const VkImageSubresourceLayers src_layers = MakeSubresourceLayers(&src); + const bool is_msaa_to_msaa = is_src_msaa && is_dst_msaa; + + // NVIDIA 510+ and Intel crash on MSAA->MSAA blits (scaling operations) + // Fall back to 3D helpers for MSAA scaling + if (is_msaa_to_msaa && device.CantBlitMSAA()) { + // This should be handled by NeedsScaleHelper() and use 3D helpers instead + UNIMPLEMENTED_MSG("MSAA to MSAA blit not supported on this driver"); + return; + } const bool is_resolve = is_src_msaa && !is_dst_msaa; scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([filter, dst_region, src_region, dst_image, src_image, dst_layers, src_layers, diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index e6224228ae..ceb01ca741 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -545,9 +545,29 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } if (nv_major_version >= 510) { - LOG_WARNING(Render_Vulkan, "NVIDIA Drivers >= 510 do not support MSAA image blits"); + LOG_WARNING(Render_Vulkan, + "NVIDIA Drivers >= 510 do not support MSAA->MSAA image blits. " + "MSAA scaling will use 3D helpers. MSAA resolves work normally."); cant_blit_msaa = true; } + + // Mali/ NVIDIA proprietary drivers: Shader stencil export not supported + // Use hardware depth/stencil blits instead when available + if (!extensions.shader_stencil_export) { + LOG_INFO(Render_Vulkan, + "NVIDIA: VK_EXT_shader_stencil_export not supported, using hardware blits " + "for depth/stencil operations"); + LOG_INFO(Render_Vulkan, " D24S8 hardware blit support: {}", + is_blit_depth24_stencil8_supported); + LOG_INFO(Render_Vulkan, " D32S8 hardware blit support: {}", + is_blit_depth32_stencil8_supported); + + if (!is_blit_depth24_stencil8_supported && !is_blit_depth32_stencil8_supported) { + LOG_WARNING(Render_Vulkan, + "NVIDIA: Neither shader export nor hardware blits available for " + "depth/stencil. Performance may be degraded."); + } + } } sets_per_pool = 64; @@ -586,7 +606,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } if (is_intel_windows) { - LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits"); + LOG_WARNING(Render_Vulkan, + "Intel proprietary drivers do not support MSAA->MSAA image blits. " + "MSAA scaling will use 3D helpers. MSAA resolves work normally."); cant_blit_msaa = true; } diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 86f258a373..b3c477ca9c 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -493,10 +493,18 @@ public: } /// Returns true if the device supports VK_EXT_shader_stencil_export. + /// Note: Most Mali/NVIDIA drivers don't support this. Use hardware blits as fallback. bool IsExtShaderStencilExportSupported() const { return extensions.shader_stencil_export; } + /// Returns true if depth/stencil operations can be performed efficiently. + /// Either through shader export or hardware blits. + bool CanPerformDepthStencilOperations() const { + return extensions.shader_stencil_export || is_blit_depth24_stencil8_supported || + is_blit_depth32_stencil8_supported; + } + /// Returns true if the device supports VK_EXT_depth_range_unrestricted. bool IsExtDepthRangeUnrestrictedSupported() const { return extensions.depth_range_unrestricted;