From c1fcc3fc989df765ae625137d4fe0d1b4abafd82 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 2 May 2020 18:40:42 +0200 Subject: [PATCH] [dxvk] Simplify barriers around meta copy operations --- src/dxvk/dxvk_context.cpp | 37 +++++++++++++------------------------ src/dxvk/dxvk_meta_copy.cpp | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index d5cfe1550..a9e1a2e4b 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2913,7 +2913,8 @@ namespace dxvk { if (srcImage->info().layout != srcLayout) { m_execAcquires.accessImage( srcImage, srcSubresourceRange, - srcImage->info().layout, 0, 0, + srcImage->info().layout, + srcImage->info().stages, 0, srcLayout, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT); @@ -2945,9 +2946,8 @@ namespace dxvk { info.numLayers = dstSubresource.layerCount; info.mipLevels = 1; info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | tgtUsage; - info.stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT - | VK_PIPELINE_STAGE_TRANSFER_BIT; - info.access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT; + info.access = VK_ACCESS_TRANSFER_READ_BIT; info.tiling = VK_IMAGE_TILING_OPTIMAL; info.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; @@ -3071,26 +3071,15 @@ namespace dxvk { m_cmd->cmdDraw(3, tgtSubresource.layerCount, 0, 0); m_cmd->cmdEndRenderPass(); - m_execBarriers.accessImage( - srcImage, srcSubresourceRange, - srcLayout, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_ACCESS_SHADER_READ_BIT, - srcImage->info().layout, - srcImage->info().stages, - srcImage->info().access); - - m_execBarriers.accessImage( - dstImage, dstSubresourceRange, - dstImage->info().layout, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - dstImage->info().layout, - dstImage->info().stages, - dstImage->info().access); + if (srcLayout != srcImage->info().layout) { + m_execBarriers.accessImage( + srcImage, srcSubresourceRange, srcLayout, + srcImage->info().stages, + srcImage->info().access, + srcImage->info().layout, + srcImage->info().stages, + srcImage->info().access); + } m_cmd->trackResource(tgtImage); m_cmd->trackResource(srcImage); diff --git a/src/dxvk/dxvk_meta_copy.cpp b/src/dxvk/dxvk_meta_copy.cpp index 200b4df2f..fa4fd36ee 100644 --- a/src/dxvk/dxvk_meta_copy.cpp +++ b/src/dxvk/dxvk_meta_copy.cpp @@ -42,6 +42,9 @@ namespace dxvk { VkRenderPass DxvkMetaCopyRenderPass::createRenderPass(bool discard) const { auto aspect = m_dstImageView->info().aspect; + VkPipelineStageFlags cpyStages = 0; + VkAccessFlags cpyAccess = 0; + VkAttachmentDescription attachment; attachment.flags = 0; attachment.format = m_dstImageView->info().format; @@ -62,8 +65,8 @@ namespace dxvk { VkAttachmentReference attachmentRef; attachmentRef.attachment = 0; attachmentRef.layout = (aspect & VK_IMAGE_ASPECT_COLOR_BIT) - ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + ? m_dstImageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + : m_dstImageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); VkSubpassDescription subpass; subpass.flags = 0; @@ -80,10 +83,33 @@ namespace dxvk { if (aspect & VK_IMAGE_ASPECT_COLOR_BIT) { subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &attachmentRef; + + 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 { subpass.pDepthStencilAttachment = &attachmentRef; + + 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; } + // We have to be somewhat conservative here since we cannot assume + // that the backend blocks stages that are only used for meta ops + VkPipelineStageFlags extStages = m_dstImageView->imageInfo().stages | m_srcImageView->imageInfo().stages; + VkAccessFlags extAccess = m_dstImageView->imageInfo().access; + + std::array dependencies = {{ + { VK_SUBPASS_EXTERNAL, 0, extStages, cpyStages, 0, cpyAccess, 0 }, + { 0, VK_SUBPASS_EXTERNAL, cpyStages, extStages, cpyAccess, extAccess, 0 }, + }}; + VkRenderPassCreateInfo info; info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; info.pNext = nullptr; @@ -92,8 +118,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)