Add barriers around vkCmdCopyImage

Write->Read barrier for src image (we want to wait for a write to read it)
Write->Read barrier for dst image (we want to wait for the copy to complete before use)
This commit is contained in:
riperiperi 2021-12-19 02:16:45 +00:00
parent d3e7606a74
commit 066094241a
2 changed files with 40 additions and 9 deletions

View file

@ -246,6 +246,23 @@ namespace Ryujinx.Graphics.Vulkan
int width = Math.Min(srcWidth, dstWidth);
int height = Math.Min(srcHeight, dstHeight);
ImageAspectFlags srcAspect = srcInfo.Format.ConvertAspectFlags();
ImageAspectFlags dstAspect = dstInfo.Format.ConvertAspectFlags();
TextureView.InsertImageBarrier(
api,
commandBuffer,
srcImage,
AccessFlags.AccessTransferWriteBit,
AccessFlags.AccessTransferReadBit,
PipelineStageFlags.PipelineStageAllCommandsBit,
PipelineStageFlags.PipelineStageTransferBit,
srcAspect,
srcViewLayer + srcLayer,
srcViewLevel + srcLevel,
srcLayers,
levels);
for (int level = 0; level < levels; level++)
{
// Stop copy if we are already out of the levels range.
@ -255,13 +272,13 @@ namespace Ryujinx.Graphics.Vulkan
}
var srcSl = new ImageSubresourceLayers(
srcInfo.Format.ConvertAspectFlags(),
srcAspect,
(uint)(srcViewLevel + srcLevel + level),
(uint)(srcViewLayer + srcLayer),
(uint)srcLayers);
var dstSl = new ImageSubresourceLayers(
dstInfo.Format.ConvertAspectFlags(),
dstAspect,
(uint)(dstViewLevel + dstLevel + level),
(uint)(dstViewLayer + dstLayer),
(uint)dstLayers);
@ -283,6 +300,20 @@ namespace Ryujinx.Graphics.Vulkan
srcDepth = Math.Max(1, srcDepth >> 1);
}
}
TextureView.InsertImageBarrier(
api,
commandBuffer,
dstImage,
AccessFlags.AccessTransferWriteBit,
AccessFlags.AccessTransferReadBit,
PipelineStageFlags.PipelineStageTransferBit,
PipelineStageFlags.PipelineStageAllCommandsBit,
dstAspect,
dstViewLayer + dstLayer,
dstViewLevel + dstLevel,
dstLayers,
levels);
}
}
}

View file

@ -153,8 +153,6 @@ namespace Ryujinx.Graphics.Vulkan
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
{
_gd.FlushAllCommands();
var src = this;
var dst = (TextureView)destination;
@ -163,7 +161,9 @@ namespace Ryujinx.Graphics.Vulkan
return;
}
using var cbs = _gd.CommandBufferPool.Rent();
_gd.PipelineInternal.EndRenderPass();
var cbs = _gd.PipelineInternal.CurrentCommandBuffer;
var srcImage = src.GetImage().Get(cbs).Value;
var dstImage = dst.GetImage().Get(cbs).Value;
@ -471,7 +471,7 @@ namespace Ryujinx.Graphics.Vulkan
aspectFlags);
InsertImageBarrier(
gd,
gd.Api,
cbs.CommandBuffer,
srcTemp.GetImage().Get(cbs).Value,
AccessFlags.AccessTransferWriteBit,
@ -504,7 +504,7 @@ namespace Ryujinx.Graphics.Vulkan
aspectFlags);
InsertImageBarrier(
gd,
gd.Api,
cbs.CommandBuffer,
dstTemp.GetImage().Get(cbs).Value,
AccessFlags.AccessTransferWriteBit,
@ -564,7 +564,7 @@ namespace Ryujinx.Graphics.Vulkan
}
public static unsafe void InsertImageBarrier(
VulkanGraphicsDevice gd,
Vk api,
CommandBuffer commandBuffer,
Image image,
AccessFlags srcAccessMask,
@ -590,7 +590,7 @@ namespace Ryujinx.Graphics.Vulkan
SubresourceRange = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, (uint)levels, (uint)firstLayer, (uint)layers)
};
gd.Api.CmdPipelineBarrier(
api.CmdPipelineBarrier(
commandBuffer,
srcStageMask,
dstStageMask,