From cf1358b2f42345a2880a24aa5ff51bb9e50791f6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 30 Apr 2018 21:42:16 +0200 Subject: [PATCH] [dxvk] Fixed partial depth-stencil clear operations --- src/dxvk/dxvk_context.cpp | 73 ++++++++++++++++++++++++------------ src/dxvk/dxvk_renderpass.cpp | 14 ++++--- src/dxvk/dxvk_renderpass.h | 24 ++++++++++-- 3 files changed, 78 insertions(+), 33 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 9e0f58cb..1a2bfcd5 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -389,6 +389,35 @@ namespace dxvk { const VkClearValue& clearValue) { this->updateFramebuffer(); + // Prepare attachment ops + DxvkColorAttachmentOps colorOp; + colorOp.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + colorOp.loadLayout = imageView->imageInfo().layout; + colorOp.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + colorOp.storeLayout = imageView->imageInfo().layout; + + DxvkDepthAttachmentOps depthOp; + depthOp.loadOpD = VK_ATTACHMENT_LOAD_OP_LOAD; + depthOp.loadOpS = VK_ATTACHMENT_LOAD_OP_LOAD; + depthOp.loadLayout = imageView->imageInfo().layout; + depthOp.storeOpD = VK_ATTACHMENT_STORE_OP_STORE; + depthOp.storeOpS = VK_ATTACHMENT_STORE_OP_STORE; + depthOp.storeLayout = imageView->imageInfo().layout; + + if (clearAspects & VK_IMAGE_ASPECT_COLOR_BIT) + colorOp.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + + if (clearAspects & VK_IMAGE_ASPECT_DEPTH_BIT) + depthOp.loadOpD = VK_ATTACHMENT_LOAD_OP_CLEAR; + + if (clearAspects & VK_IMAGE_ASPECT_STENCIL_BIT) + depthOp.loadOpS = VK_ATTACHMENT_LOAD_OP_CLEAR; + + if (clearAspects == imageView->info().aspect) { + colorOp.loadLayout = VK_IMAGE_LAYOUT_UNDEFINED; + depthOp.loadLayout = VK_IMAGE_LAYOUT_UNDEFINED; + } + // Check whether the render target view is an attachment // of the current framebuffer. If not, we need to create // a temporary framebuffer. @@ -400,12 +429,6 @@ namespace dxvk { if (attachmentIndex < 0) { this->spillRenderPass(); - DxvkAttachmentOps op; - op.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - op.loadLayout = VK_IMAGE_LAYOUT_UNDEFINED; - op.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - op.storeLayout = imageView->imageInfo().layout; - // Set up and bind a temporary framebuffer DxvkRenderTargets attachments; DxvkRenderPassOps ops; @@ -413,11 +436,11 @@ namespace dxvk { if (clearAspects & VK_IMAGE_ASPECT_COLOR_BIT) { attachments.color[0].view = imageView; attachments.color[0].layout = imageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - ops.colorOps[0] = op; + ops.colorOps[0] = colorOp; } else { attachments.depth.view = imageView; attachments.depth.layout = imageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - ops.depthOps = op; + ops.depthOps = depthOp; } this->renderPassBindFramebuffer( @@ -437,13 +460,11 @@ namespace dxvk { 1, &clearInfo, 1, &clearRect); } else { // Perform the clear when starting the render pass - if (clearAspects & VK_IMAGE_ASPECT_COLOR_BIT) { - m_state.om.renderPassOps.colorOps[attachmentIndex].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - m_state.om.renderPassOps.colorOps[attachmentIndex].loadLayout = VK_IMAGE_LAYOUT_UNDEFINED; - } else { - m_state.om.renderPassOps.depthOps.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - m_state.om.renderPassOps.depthOps.loadLayout = VK_IMAGE_LAYOUT_UNDEFINED; - } + if (clearAspects & VK_IMAGE_ASPECT_COLOR_BIT) + m_state.om.renderPassOps.colorOps[attachmentIndex] = colorOp; + + if (clearAspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) + m_state.om.renderPassOps.depthOps = depthOp; m_state.om.clearValues[attachmentIndex] = clearValue; m_flags.set(DxvkContextFlag::GpClearRenderTargets); @@ -1586,17 +1607,23 @@ namespace dxvk { const DxvkRenderTargets& renderTargets, DxvkRenderPassOps& renderPassOps) { renderPassOps.depthOps = renderTargets.depth.view != nullptr - ? DxvkAttachmentOps { - VK_ATTACHMENT_LOAD_OP_LOAD, renderTargets.depth.view->imageInfo().layout, - VK_ATTACHMENT_STORE_OP_STORE, renderTargets.depth.view->imageInfo().layout } - : DxvkAttachmentOps { }; + ? DxvkDepthAttachmentOps { + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_LOAD_OP_LOAD, + renderTargets.depth.view->imageInfo().layout, + VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_STORE_OP_STORE, + renderTargets.depth.view->imageInfo().layout } + : DxvkDepthAttachmentOps { }; for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { renderPassOps.colorOps[i] = renderTargets.color[i].view != nullptr - ? DxvkAttachmentOps { - VK_ATTACHMENT_LOAD_OP_LOAD, renderTargets.color[i].view->imageInfo().layout, - VK_ATTACHMENT_STORE_OP_STORE, renderTargets.color[i].view->imageInfo().layout } - : DxvkAttachmentOps { }; + ? DxvkColorAttachmentOps { + VK_ATTACHMENT_LOAD_OP_LOAD, + renderTargets.color[i].view->imageInfo().layout, + VK_ATTACHMENT_STORE_OP_STORE, + renderTargets.color[i].view->imageInfo().layout } + : DxvkColorAttachmentOps { }; } // TODO provide a sane alternative for this diff --git a/src/dxvk/dxvk_renderpass.cpp b/src/dxvk/dxvk_renderpass.cpp index e24109c4..343cddaf 100644 --- a/src/dxvk/dxvk_renderpass.cpp +++ b/src/dxvk/dxvk_renderpass.cpp @@ -89,10 +89,10 @@ namespace dxvk { desc.flags = 0; desc.format = m_format.depth.format; desc.samples = m_format.sampleCount; - desc.loadOp = ops.depthOps.loadOp; - desc.storeOp = ops.depthOps.storeOp; - desc.stencilLoadOp = ops.depthOps.loadOp; - desc.stencilStoreOp = ops.depthOps.storeOp; + desc.loadOp = ops.depthOps.loadOpD; + desc.storeOp = ops.depthOps.storeOpD; + desc.stencilLoadOp = ops.depthOps.loadOpS; + desc.stencilStoreOp = ops.depthOps.storeOpS; desc.initialLayout = ops.depthOps.loadLayout; desc.finalLayout = ops.depthOps.storeLayout; @@ -179,9 +179,11 @@ namespace dxvk { bool DxvkRenderPass::compareOps( const DxvkRenderPassOps& a, const DxvkRenderPassOps& b) { - bool eq = a.depthOps.loadOp == b.depthOps.loadOp + bool eq = a.depthOps.loadOpD == b.depthOps.loadOpD + && a.depthOps.loadOpS == b.depthOps.loadOpS && a.depthOps.loadLayout == b.depthOps.loadLayout - && a.depthOps.storeOp == b.depthOps.storeOp + && a.depthOps.storeOpD == b.depthOps.storeOpD + && a.depthOps.storeOpS == b.depthOps.storeOpS && a.depthOps.storeLayout == b.depthOps.storeLayout; for (uint32_t i = 0; i < MaxNumRenderTargets && eq; i++) { diff --git a/src/dxvk/dxvk_renderpass.h b/src/dxvk/dxvk_renderpass.h index a65c5253..d44aa487 100644 --- a/src/dxvk/dxvk_renderpass.h +++ b/src/dxvk/dxvk_renderpass.h @@ -35,12 +35,12 @@ namespace dxvk { /** - * \brief Attachment transitions + * \brief Color attachment transitions * * Stores the load/store ops and the initial * and final layout of a single attachment. */ - struct DxvkAttachmentOps { + struct DxvkColorAttachmentOps { VkAttachmentLoadOp loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; VkImageLayout loadLayout = VK_IMAGE_LAYOUT_UNDEFINED; VkAttachmentStoreOp storeOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -48,6 +48,22 @@ namespace dxvk { }; + /** + * \brief Depth attachment transitions + * + * Stores the load/store ops and the initial and + * final layout of the depth-stencil attachment. + */ + struct DxvkDepthAttachmentOps { + VkAttachmentLoadOp loadOpD = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + VkAttachmentLoadOp loadOpS = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + VkImageLayout loadLayout = VK_IMAGE_LAYOUT_UNDEFINED; + VkAttachmentStoreOp storeOpD = VK_ATTACHMENT_STORE_OP_STORE; + VkAttachmentStoreOp storeOpS = VK_ATTACHMENT_STORE_OP_STORE; + VkImageLayout storeLayout = VK_IMAGE_LAYOUT_GENERAL; + }; + + /** * \brief Render pass transitions * @@ -56,8 +72,8 @@ namespace dxvk { * from a group of render passes with the same format. */ struct DxvkRenderPassOps { - DxvkAttachmentOps depthOps; - DxvkAttachmentOps colorOps[MaxNumRenderTargets]; + DxvkDepthAttachmentOps depthOps; + DxvkColorAttachmentOps colorOps[MaxNumRenderTargets]; };