1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-02 01:24:11 +01:00

[dxvk] Optimize barriers around vkCmdCopyImage

We don't need to force layout transitions and emit double pipeline
barriers in case the GENERAL layout is being used for both images.
This is somewhat common for images used by compute shaders, and
this optimization ensures that only required barriers are emitted.
This commit is contained in:
Philip Rebohle 2018-06-18 22:30:00 +02:00
parent f7587014c7
commit 15aabcb878
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99

View File

@ -707,27 +707,39 @@ namespace dxvk {
srcSubresource.baseArrayLayer,
srcSubresource.layerCount };
m_barriers.recordCommands(m_cmd);
m_barriers.accessImage(
dstImage, dstSubresourceRange,
dstImage->mipLevelExtent(dstSubresource.mipLevel) == extent
? VK_IMAGE_LAYOUT_UNDEFINED
: dstImage->info().layout,
dstImage->info().stages,
dstImage->info().access,
dstImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL),
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT);
if (m_barriers.isImageDirty(dstImage, dstSubresourceRange, DxvkAccess::Write)
|| m_barriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write))
m_barriers.recordCommands(m_cmd);
m_barriers.accessImage(
srcImage, srcSubresourceRange,
srcImage->info().layout,
srcImage->info().stages,
srcImage->info().access,
srcImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL),
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_READ_BIT);
VkImageLayout dstImageLayout = dstImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkImageLayout srcImageLayout = srcImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
if (dstImageLayout != dstImage->info().layout) {
VkImageLayout dstInitImageLayout = dstImage->info().layout;
if (dstImage->mipLevelExtent(dstSubresource.mipLevel) == extent)
dstInitImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
m_barriers.accessImage(
dstImage, dstSubresourceRange,
dstInitImageLayout,
dstImage->info().stages,
dstImage->info().access,
dstImageLayout,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT);
}
if (srcImageLayout != srcImage->info().layout) {
m_barriers.accessImage(
srcImage, srcSubresourceRange,
srcImage->info().layout,
srcImage->info().stages,
srcImage->info().access,
srcImageLayout,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_READ_BIT);
}
m_barriers.recordCommands(m_cmd);
@ -740,8 +752,8 @@ namespace dxvk {
imageRegion.extent = extent;
m_cmd->cmdCopyImage(
srcImage->handle(), srcImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL),
dstImage->handle(), dstImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL),
srcImage->handle(), srcImageLayout,
dstImage->handle(), dstImageLayout,
1, &imageRegion);
} else {
const VkDeviceSize transferBufferSize = std::max(
@ -771,8 +783,7 @@ namespace dxvk {
bufferImageCopy.imageExtent = extent;
m_cmd->cmdCopyImageToBuffer(
srcImage->handle(),
srcImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL),
srcImage->handle(), srcImageLayout,
tmpSlice.handle(), 1, &bufferImageCopy);
m_barriers.accessBuffer(tmpSlice,
@ -786,10 +797,9 @@ namespace dxvk {
bufferImageCopy.imageSubresource = dstSubresource;
bufferImageCopy.imageOffset = dstOffset;
m_cmd->cmdCopyBufferToImage(tmpSlice.handle(),
dstImage->handle(),
dstImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL),
1, &bufferImageCopy);
m_cmd->cmdCopyBufferToImage(
tmpSlice.handle(), dstImage->handle(),
dstImageLayout, 1, &bufferImageCopy);
m_barriers.accessBuffer(tmpSlice,
VK_PIPELINE_STAGE_TRANSFER_BIT,
@ -802,7 +812,7 @@ namespace dxvk {
m_barriers.accessImage(
dstImage, dstSubresourceRange,
dstImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL),
dstImageLayout,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
dstImage->info().layout,
@ -811,7 +821,7 @@ namespace dxvk {
m_barriers.accessImage(
srcImage, srcSubresourceRange,
srcImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL),
srcImageLayout,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
srcImage->info().layout,