mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 11:52:12 +01:00
[dxvk] Optimize image layout transitions
This should reduce unnecessary execution dependencies when transitioning image layouts before executing image copies.
This commit is contained in:
parent
8c65203ac2
commit
db2b6e1219
@ -650,7 +650,9 @@ namespace dxvk {
|
|||||||
dstSubresource.baseArrayLayer,
|
dstSubresource.baseArrayLayer,
|
||||||
dstSubresource.layerCount };
|
dstSubresource.layerCount };
|
||||||
|
|
||||||
m_barriers.recordCommands(m_cmd);
|
if (m_barriers.isImageDirty(dstImage, dstSubresourceRange, DxvkAccess::Write)
|
||||||
|
|| m_barriers.isBufferDirty(srcSlice, DxvkAccess::Read))
|
||||||
|
m_barriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
// Initialize the image if the entire subresource is covered
|
// Initialize the image if the entire subresource is covered
|
||||||
VkImageLayout dstImageLayoutInitial = dstImage->info().layout;
|
VkImageLayout dstImageLayoutInitial = dstImage->info().layout;
|
||||||
@ -659,16 +661,14 @@ namespace dxvk {
|
|||||||
if (dstImage->isFullSubresource(dstSubresource, dstExtent))
|
if (dstImage->isFullSubresource(dstSubresource, dstExtent))
|
||||||
dstImageLayoutInitial = VK_IMAGE_LAYOUT_UNDEFINED;
|
dstImageLayoutInitial = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
m_barriers.accessImage(
|
m_transitions.accessImage(
|
||||||
dstImage, dstSubresourceRange,
|
dstImage, dstSubresourceRange,
|
||||||
dstImageLayoutInitial,
|
dstImageLayoutInitial, 0, 0,
|
||||||
dstImage->info().stages,
|
|
||||||
dstImage->info().access,
|
|
||||||
dstImageLayoutTransfer,
|
dstImageLayoutTransfer,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
VK_ACCESS_TRANSFER_WRITE_BIT);
|
VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||||
|
|
||||||
m_barriers.recordCommands(m_cmd);
|
m_transitions.recordCommands(m_cmd);
|
||||||
|
|
||||||
VkBufferImageCopy copyRegion;
|
VkBufferImageCopy copyRegion;
|
||||||
copyRegion.bufferOffset = srcSlice.offset();
|
copyRegion.bufferOffset = srcSlice.offset();
|
||||||
@ -733,34 +733,26 @@ namespace dxvk {
|
|||||||
VkImageLayout dstImageLayout = dstImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
VkImageLayout dstImageLayout = dstImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
VkImageLayout srcImageLayout = srcImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
VkImageLayout srcImageLayout = srcImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||||
|
|
||||||
if (dstImageLayout != dstImage->info().layout) {
|
VkImageLayout dstInitImageLayout = dstImage->info().layout;
|
||||||
VkImageLayout dstInitImageLayout = dstImage->info().layout;
|
|
||||||
|
|
||||||
if (dstImage->mipLevelExtent(dstSubresource.mipLevel) == extent)
|
if (dstImage->isFullSubresource(dstSubresource, extent))
|
||||||
dstInitImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
dstInitImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
m_barriers.accessImage(
|
m_transitions.accessImage(
|
||||||
dstImage, dstSubresourceRange,
|
dstImage, dstSubresourceRange,
|
||||||
dstInitImageLayout,
|
dstInitImageLayout, 0, 0,
|
||||||
dstImage->info().stages,
|
dstImageLayout,
|
||||||
dstImage->info().access,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
dstImageLayout,
|
VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
||||||
VK_ACCESS_TRANSFER_WRITE_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (srcImageLayout != srcImage->info().layout) {
|
m_transitions.accessImage(
|
||||||
m_barriers.accessImage(
|
srcImage, srcSubresourceRange,
|
||||||
srcImage, srcSubresourceRange,
|
srcImage->info().layout, 0, 0,
|
||||||
srcImage->info().layout,
|
srcImageLayout,
|
||||||
srcImage->info().stages,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
srcImage->info().access,
|
VK_ACCESS_TRANSFER_READ_BIT);
|
||||||
srcImageLayout,
|
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
||||||
VK_ACCESS_TRANSFER_READ_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_barriers.recordCommands(m_cmd);
|
m_transitions.recordCommands(m_cmd);
|
||||||
|
|
||||||
if (dstSubresource.aspectMask == srcSubresource.aspectMask) {
|
if (dstSubresource.aspectMask == srcSubresource.aspectMask) {
|
||||||
VkImageCopy imageRegion;
|
VkImageCopy imageRegion;
|
||||||
@ -874,21 +866,21 @@ namespace dxvk {
|
|||||||
srcSubresource.baseArrayLayer,
|
srcSubresource.baseArrayLayer,
|
||||||
srcSubresource.layerCount };
|
srcSubresource.layerCount };
|
||||||
|
|
||||||
m_barriers.recordCommands(m_cmd);
|
if (m_barriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write)
|
||||||
|
|| m_barriers.isBufferDirty(dstSlice, DxvkAccess::Write))
|
||||||
|
m_barriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
// Select a suitable image layout for the transfer op
|
// Select a suitable image layout for the transfer op
|
||||||
VkImageLayout srcImageLayoutTransfer = srcImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
VkImageLayout srcImageLayoutTransfer = srcImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||||
|
|
||||||
m_barriers.accessImage(
|
m_transitions.accessImage(
|
||||||
srcImage, srcSubresourceRange,
|
srcImage, srcSubresourceRange,
|
||||||
srcImage->info().layout,
|
srcImage->info().layout, 0, 0,
|
||||||
srcImage->info().stages,
|
|
||||||
srcImage->info().access,
|
|
||||||
srcImageLayoutTransfer,
|
srcImageLayoutTransfer,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
VK_ACCESS_TRANSFER_READ_BIT);
|
VK_ACCESS_TRANSFER_READ_BIT);
|
||||||
|
|
||||||
m_barriers.recordCommands(m_cmd);
|
m_transitions.recordCommands(m_cmd);
|
||||||
|
|
||||||
VkBufferImageCopy copyRegion;
|
VkBufferImageCopy copyRegion;
|
||||||
copyRegion.bufferOffset = dstSlice.offset();
|
copyRegion.bufferOffset = dstSlice.offset();
|
||||||
@ -1043,8 +1035,7 @@ namespace dxvk {
|
|||||||
const Rc<DxvkImage>& image,
|
const Rc<DxvkImage>& image,
|
||||||
const VkImageSubresourceRange& subresources) {
|
const VkImageSubresourceRange& subresources) {
|
||||||
m_barriers.accessImage(image, subresources,
|
m_barriers.accessImage(image, subresources,
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
VK_IMAGE_LAYOUT_UNDEFINED, 0, 0,
|
||||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0,
|
|
||||||
image->info().layout,
|
image->info().layout,
|
||||||
image->info().stages,
|
image->info().stages,
|
||||||
image->info().access);
|
image->info().access);
|
||||||
@ -1471,13 +1462,14 @@ namespace dxvk {
|
|||||||
// Prepare the image layout. If the given extent covers
|
// Prepare the image layout. If the given extent covers
|
||||||
// the entire image, we may discard its previous contents.
|
// the entire image, we may discard its previous contents.
|
||||||
VkImageSubresourceRange subresourceRange;
|
VkImageSubresourceRange subresourceRange;
|
||||||
subresourceRange.aspectMask = subresources.aspectMask;
|
subresourceRange.aspectMask = formatInfo->aspectMask;
|
||||||
subresourceRange.baseMipLevel = subresources.mipLevel;
|
subresourceRange.baseMipLevel = subresources.mipLevel;
|
||||||
subresourceRange.levelCount = 1;
|
subresourceRange.levelCount = 1;
|
||||||
subresourceRange.baseArrayLayer = subresources.baseArrayLayer;
|
subresourceRange.baseArrayLayer = subresources.baseArrayLayer;
|
||||||
subresourceRange.layerCount = subresources.layerCount;
|
subresourceRange.layerCount = subresources.layerCount;
|
||||||
|
|
||||||
m_barriers.recordCommands(m_cmd);
|
if (m_barriers.isImageDirty(image, subresourceRange, DxvkAccess::Write))
|
||||||
|
m_barriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
// Initialize the image if the entire subresource is covered
|
// Initialize the image if the entire subresource is covered
|
||||||
VkImageLayout imageLayoutInitial = image->info().layout;
|
VkImageLayout imageLayoutInitial = image->info().layout;
|
||||||
@ -1486,16 +1478,14 @@ namespace dxvk {
|
|||||||
if (image->isFullSubresource(subresources, imageExtent))
|
if (image->isFullSubresource(subresources, imageExtent))
|
||||||
imageLayoutInitial = VK_IMAGE_LAYOUT_UNDEFINED;
|
imageLayoutInitial = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
m_barriers.accessImage(
|
m_transitions.accessImage(
|
||||||
image, subresourceRange,
|
image, subresourceRange,
|
||||||
imageLayoutInitial,
|
imageLayoutInitial, 0, 0,
|
||||||
image->info().stages,
|
|
||||||
image->info().access,
|
|
||||||
imageLayoutTransfer,
|
imageLayoutTransfer,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
VK_ACCESS_TRANSFER_WRITE_BIT);
|
VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||||
|
|
||||||
m_barriers.recordCommands(m_cmd);
|
m_transitions.recordCommands(m_cmd);
|
||||||
|
|
||||||
// Copy contents of the staging buffer into the image.
|
// Copy contents of the staging buffer into the image.
|
||||||
// Since our source data is tightly packed, we do not
|
// Since our source data is tightly packed, we do not
|
||||||
|
@ -631,7 +631,9 @@ namespace dxvk {
|
|||||||
Rc<DxvkCommandList> m_cmd;
|
Rc<DxvkCommandList> m_cmd;
|
||||||
DxvkContextFlags m_flags;
|
DxvkContextFlags m_flags;
|
||||||
DxvkContextState m_state;
|
DxvkContextState m_state;
|
||||||
|
|
||||||
DxvkBarrierSet m_barriers;
|
DxvkBarrierSet m_barriers;
|
||||||
|
DxvkBarrierSet m_transitions;
|
||||||
|
|
||||||
// TODO implement this properly...
|
// TODO implement this properly...
|
||||||
Rc<DxvkQueryPool> m_queryPools[3] = { nullptr, nullptr, nullptr };
|
Rc<DxvkQueryPool> m_queryPools[3] = { nullptr, nullptr, nullptr };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user