diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 83dfc5ce..55f27544 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4126,6 +4126,50 @@ namespace dxvk { } + void DxvkContext::prepareImage( + DxvkBarrierSet& barriers, + const Rc& image, + const VkImageSubresourceRange& subresources) { + // Images that can't be used as attachments are always in their + // default layout, so we don't have to do anything in this case + 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()) + this->spillRenderPass(false); + + // All images are in their default layout for suspended passes + if (!m_flags.test(DxvkContextFlag::GpRenderPassSuspended)) + return; + + // 3D images require special care because they only have one + // layer, but views may address individual 2D slices as layers + bool is3D = image->info().type == VK_IMAGE_TYPE_3D; + + // Transition any attachment with overlapping subresources + if (image->info().usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + const DxvkAttachment& attachment = m_state.om.framebuffer->getColorTarget(i); + + if (attachment.view != nullptr && attachment.view->image() == image + && (is3D || vk::checkSubresourceRangeOverlap(attachment.view->subresources(), subresources))) { + this->transitionColorAttachment(barriers, attachment, m_rtLayouts.color[i]); + m_rtLayouts.color[i] = image->info().layout; + } + } + } else { + const DxvkAttachment& attachment = m_state.om.framebuffer->getDepthTarget(); + + if (attachment.view != nullptr && attachment.view->image() == image + && (is3D || vk::checkSubresourceRangeOverlap(attachment.view->subresources(), subresources))) { + this->transitionDepthAttachment(barriers, attachment, m_rtLayouts.depth); + m_rtLayouts.depth = image->info().layout; + } + } + } + + bool DxvkContext::updateIndexBufferBinding() { if (unlikely(!m_state.vi.indexBuffer.defined())) return false; diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index e5789c8e..bbd9ce7e 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1162,6 +1162,11 @@ namespace dxvk { const Rc& newFb, const Rc& oldFb); + void prepareImage( + DxvkBarrierSet& barriers, + const Rc& image, + const VkImageSubresourceRange& subresources); + bool updateIndexBufferBinding(); void updateVertexBufferBindings();