diff --git a/src/video_core/renderer_vulkan/vk_render_pass_cache.cpp b/src/video_core/renderer_vulkan/vk_render_pass_cache.cpp index efb37bc787..a514ac9022 100644 --- a/src/video_core/renderer_vulkan/vk_render_pass_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_render_pass_cache.cpp @@ -175,8 +175,11 @@ VkRenderPass RenderPassCache::Get(const RenderPassKey& key) { const VkAttachmentLoadOp depth_load_op = key.depth_stencil_clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD; + const VkAttachmentStoreOp depth_store_op = key.depth_stencil_discard + ? VK_ATTACHMENT_STORE_OP_DONT_CARE + : VK_ATTACHMENT_STORE_OP_STORE; descriptions.push_back(AttachmentDescription(*device, key.depth_format, key.samples, - depth_load_op, VK_ATTACHMENT_STORE_OP_STORE)); + depth_load_op, depth_store_op)); } std::array resolve_references{}; const bool do_resolve_color = diff --git a/src/video_core/renderer_vulkan/vk_render_pass_cache.h b/src/video_core/renderer_vulkan/vk_render_pass_cache.h index 0b01fc0194..f9923be75a 100644 --- a/src/video_core/renderer_vulkan/vk_render_pass_cache.h +++ b/src/video_core/renderer_vulkan/vk_render_pass_cache.h @@ -26,6 +26,7 @@ struct RenderPassKey { u32 color_clear_mask; bool depth_stencil_clear; u32 color_discard_mask; + bool depth_stencil_discard; }; } // namespace Vulkan @@ -49,7 +50,8 @@ struct hash { (static_cast(key.color_discard_mask) << 24) | (static_cast(key.resolve_color) << 32) | (static_cast(key.depth_stencil_clear) << 33) | - (static_cast(key.resolve_depth_stencil) << 34); + (static_cast(key.resolve_depth_stencil) << 34) | + (static_cast(key.depth_stencil_discard) << 35); size_t seed = 0; Common::HashCombine(seed, formats); Common::HashCombine(seed, state); diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index f1f04d0b8c..68852a0e82 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -155,8 +155,10 @@ void Scheduler::RealizeDeferredClear() { } const u32 color_discard_mask = dc.framebuffer->DiscardsMsaaColor() ? dc.color_clear_mask : 0u; + const bool depth_stencil_discard = + dc.depth_stencil && dc.framebuffer->DiscardsMsaaDepthStencil(); const VkRenderPass renderpass = dc.framebuffer->RenderPassVariant( - dc.color_clear_mask, dc.depth_stencil, color_discard_mask); + dc.color_clear_mask, dc.depth_stencil, color_discard_mask, depth_stencil_discard); EndRenderPass(); BeginRenderPassImpl(dc.framebuffer, renderpass, clear_values.data(), count); } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 796039be38..432117ab0f 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -55,6 +55,7 @@ using VideoCore::Surface::SurfaceType; namespace { constexpr bool ENABLE_MSAA_RESOLVE_CONSUME = true; constexpr bool ENABLE_MSAA_COLOR_DISCARD = true; +constexpr bool ENABLE_MSAA_DEPTH_STENCIL_DISCARD = true; [[nodiscard]] constexpr bool NeedsExplicitBorderColorFormat(VkFormat format) { switch (format) { @@ -3000,6 +3001,8 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime, discard_msaa_color = ENABLE_MSAA_RESOLVE_CONSUME && ENABLE_MSAA_COLOR_DISCARD && do_resolve_color; + discard_msaa_depth_stencil = ENABLE_MSAA_RESOLVE_CONSUME && + ENABLE_MSAA_DEPTH_STENCIL_DISCARD && do_resolve_depth_stencil; renderpass = runtime.render_pass_cache.Get(renderpass_key); render_pass_key = renderpass_key; @@ -3089,13 +3092,16 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime, } VkRenderPass Framebuffer::RenderPassVariant(u32 color_clear_mask, bool depth_stencil_clear, - u32 color_discard_mask) const { - if (color_clear_mask == 0 && !depth_stencil_clear && color_discard_mask == 0) { + u32 color_discard_mask, + bool depth_stencil_discard) const { + if (color_clear_mask == 0 && !depth_stencil_clear && color_discard_mask == 0 && + !depth_stencil_discard) { return renderpass; } static_assert(NUM_RT <= 8); const u32 variant_key = color_clear_mask | (color_discard_mask << 8) | - (static_cast(depth_stencil_clear) << 16); + (static_cast(depth_stencil_clear) << 16) | + (static_cast(depth_stencil_discard) << 17); for (u32 index = 0; index < num_memoized_variants; ++index) { if (variant_keys[index] == variant_key) { return variant_render_passes[index]; @@ -3105,6 +3111,7 @@ VkRenderPass Framebuffer::RenderPassVariant(u32 color_clear_mask, bool depth_ste key.color_clear_mask = color_clear_mask; key.depth_stencil_clear = depth_stencil_clear; key.color_discard_mask = color_discard_mask; + key.depth_stencil_discard = depth_stencil_discard; const VkRenderPass variant = render_pass_cache->Get(key); if (num_memoized_variants < variant_keys.size()) { variant_keys[num_memoized_variants] = variant_key; diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 40088c4b74..681866d7e3 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -196,7 +196,8 @@ public: } [[nodiscard]] VkRenderPass RenderPassVariant(u32 color_clear_mask, bool depth_stencil_clear, - u32 color_discard_mask) const; + u32 color_discard_mask, + bool depth_stencil_discard) const; [[nodiscard]] VkExtent2D RenderArea() const noexcept { return render_area; @@ -250,6 +251,10 @@ public: return discard_msaa_color; } + [[nodiscard]] bool DiscardsMsaaDepthStencil() const noexcept { + return discard_msaa_depth_stencil; + } + private: static constexpr size_t NUM_MEMOIZED_RENDER_PASS_VARIANTS = 8; @@ -270,6 +275,7 @@ private: RenderPassKey render_pass_key{}; RenderPassCache* render_pass_cache{nullptr}; bool discard_msaa_color{}; + bool discard_msaa_depth_stencil{}; mutable std::array variant_keys{}; mutable std::array variant_render_passes{}; mutable u32 num_memoized_variants{};