From 5d7b5b0e35cda905ae62e5b63ec5324db9611d3b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 May 2020 16:23:44 +0200 Subject: [PATCH] [dxvk] Fix framebuffer resolve barriers --- src/dxvk/dxvk_context.cpp | 44 +++++------------------- src/dxvk/dxvk_meta_resolve.cpp | 61 +++++++++++++++++++++++++++------- 2 files changed, 57 insertions(+), 48 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 10db8ae6..2a4ad227 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -3219,27 +3219,6 @@ namespace dxvk { m_cmd->cmdBeginRenderPass(&info, VK_SUBPASS_CONTENTS_INLINE); m_cmd->cmdEndRenderPass(); - m_execBarriers.accessImage( - dstImage, dstSubresourceRange, - dstImage->info().layout, - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - dstImage->info().layout, - dstImage->info().stages, - dstImage->info().access); - - m_execBarriers.accessImage( - srcImage, srcSubresourceRange, - srcImage->info().layout, - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, - srcImage->info().layout, - srcImage->info().stages, - srcImage->info().access); - m_cmd->trackResource(dstImage); m_cmd->trackResource(srcImage); m_cmd->trackResource(fb); @@ -3381,21 +3360,14 @@ namespace dxvk { m_cmd->cmdDraw(3, region.dstSubresource.layerCount, 0, 0); m_cmd->cmdEndRenderPass(); - m_execBarriers.accessImage( - dstImage, dstSubresourceRange, - dstImage->info().layout, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - dstImage->info().layout, - dstImage->info().stages, - dstImage->info().access); - - m_execBarriers.accessImage( - srcImage, srcSubresourceRange, srcLayout, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, - srcImage->info().layout, - srcImage->info().stages, - srcImage->info().access); + if (srcImage->info().layout != srcLayout) { + m_execBarriers.accessImage( + srcImage, srcSubresourceRange, srcLayout, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, + srcImage->info().layout, + srcImage->info().stages, + srcImage->info().access); + } m_cmd->trackResource(dstImage); m_cmd->trackResource(srcImage); diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index cd8e78c2..cac7a729 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -77,16 +77,43 @@ namespace dxvk { dstRef.layout = layout; VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = isColorImage ? 1 : 0; - subpass.pColorAttachments = isColorImage ? &dstRef : nullptr; - subpass.pResolveAttachments = nullptr; + subpass.flags = 0; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.inputAttachmentCount = 0; + subpass.pInputAttachments = nullptr; + subpass.colorAttachmentCount = isColorImage ? 1 : 0; + subpass.pColorAttachments = isColorImage ? &dstRef : nullptr; + subpass.pResolveAttachments = nullptr; subpass.pDepthStencilAttachment = isColorImage ? nullptr : &dstRef; subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; + subpass.pPreserveAttachments = nullptr; + + VkPipelineStageFlags cpyStages = 0; + VkAccessFlags cpyAccess = 0; + + if (isColorImage) { + cpyStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + cpyAccess |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + if (!discard) + cpyAccess |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + } else { + cpyStages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT + | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + cpyAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + + if (!discard) + cpyAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + } + + // Resolve targets are required to be render targets + VkPipelineStageFlags extStages = m_dstImageView->imageInfo().stages | m_srcImageView->imageInfo().stages; + VkAccessFlags extAccess = m_dstImageView->imageInfo().access; + + std::array dependencies = {{ + { VK_SUBPASS_EXTERNAL, 0, cpyStages, cpyStages, 0, cpyAccess, 0 }, + { 0, VK_SUBPASS_EXTERNAL, cpyStages, extStages, cpyAccess, extAccess, 0 }, + }}; VkRenderPassCreateInfo info; info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; @@ -96,8 +123,8 @@ namespace dxvk { info.pAttachments = &attachment; info.subpassCount = 1; info.pSubpasses = &subpass; - info.dependencyCount = 0; - info.pDependencies = nullptr; + info.dependencyCount = dependencies.size(); + info.pDependencies = dependencies.data(); VkRenderPass result = VK_NULL_HANDLE; if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) @@ -176,6 +203,16 @@ namespace dxvk { subpass.preserveAttachmentCount = 0; subpass.pPreserveAttachments = nullptr; + VkPipelineStageFlags cpyStages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + VkPipelineStageFlags extStages = m_dstImageView->imageInfo().stages | m_srcImageView->imageInfo().stages; + VkAccessFlags cpyAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + VkAccessFlags extAccess = m_dstImageView->imageInfo().access; + + std::array dependencies = {{ + { VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR, nullptr, VK_SUBPASS_EXTERNAL, 0, cpyStages, cpyStages, 0, cpyAccess, 0 }, + { VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR, nullptr, 0, VK_SUBPASS_EXTERNAL, cpyStages, extStages, cpyAccess, extAccess, 0 }, + }}; + VkRenderPassCreateInfo2KHR info; info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR; info.pNext = nullptr; @@ -184,8 +221,8 @@ namespace dxvk { info.pAttachments = attachments.data(); info.subpassCount = 1; info.pSubpasses = &subpass; - info.dependencyCount = 0; - info.pDependencies = nullptr; + info.dependencyCount = dependencies.size(); + info.pDependencies = dependencies.data(); info.correlatedViewMaskCount = 0; info.pCorrelatedViewMasks = nullptr;