From f355b1c30c935fac741e8a625eed9886be1d270f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 22 Mar 2025 00:23:26 +0100 Subject: [PATCH] [dxvk] Only flush clears if image to use has any pending clears We can reorder the clear after any operation that does not access the image. --- src/dxvk/dxvk_context.cpp | 21 ++++++++++++++++++--- src/dxvk/dxvk_context.h | 4 ++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 37d0c1efc..3158dc391 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -6534,8 +6534,9 @@ namespace dxvk { if (!(image->info().usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT))) return; - // Flush clears if there are any since they may affect the image - if (!m_deferredClears.empty() && flushClears) + // Flush clears if there are any that affect the image. We need + // to check all subresources here, not just the ones to be used. + if (flushClears && findOverlappingDeferredClear(image, image->getAvailableSubresources())) this->spillRenderPass(false); // All images are in their default layout for suspended passes @@ -6573,7 +6574,7 @@ namespace dxvk { const Rc& image, const VkImageSubresourceRange& subresources) { for (auto& entry : m_deferredClears) { - if ((entry.imageView->image() == image) && ((subresources.aspectMask & entry.clearAspects) == subresources.aspectMask) + if ((entry.imageView->image() == image.ptr()) && ((subresources.aspectMask & entry.clearAspects) == subresources.aspectMask) && (vk::checkSubresourceRangeSuperset(entry.imageView->imageSubresources(), subresources))) return &entry; } @@ -6582,6 +6583,20 @@ namespace dxvk { } + DxvkDeferredClear* DxvkContext::findOverlappingDeferredClear( + const Rc& image, + const VkImageSubresourceRange& subresources) { + for (auto& entry : m_deferredClears) { + if ((entry.imageView->image() == image.ptr()) + && (entry.clearAspects & entry.discardAspects & subresources.aspectMask) + && (vk::checkSubresourceRangeOverlap(entry.imageView->imageSubresources(), subresources))) + return &entry; + } + + return nullptr; + } + + bool DxvkContext::updateIndexBufferBinding() { if (unlikely(!m_state.vi.indexBuffer.length())) return false; diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index de223e323..7b7113dd5 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1754,6 +1754,10 @@ namespace dxvk { const Rc& image, const VkImageSubresourceRange& subresources); + DxvkDeferredClear* findOverlappingDeferredClear( + const Rc& image, + const VkImageSubresourceRange& subresources); + bool updateIndexBufferBinding(); void updateVertexBufferBindings();