Fix some Vulkan validation errors (mostly related to barriers) (#5603)

* Replace image barriers inside render pass with more generic memory barrier

* Remove forceStorage since it was creating images with storage bit for formats that are not StorageImage compatible

* Add missing flags on subpass dependency

* Don't call vkCmdSetScissor with a scissor count of 0

* One semaphore per swapchain image

* Remove compute stage from read to write barriers

* Try to improve Pipeline.Barrier nonsense

* Set PipelineStateFlags based on supported stages
This commit is contained in:
gdkchan
2023-09-14 14:58:11 -03:00
committed by GitHub
parent a745913329
commit 7ccff037e8
9 changed files with 145 additions and 54 deletions

View File

@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.Vulkan
var sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
var usage = GetImageUsage(info.Format, info.Target, gd.Capabilities.SupportsShaderStorageImageMultisample, forceStorage: true);
var usage = GetImageUsage(info.Format, info.Target, gd.Capabilities.SupportsShaderStorageImageMultisample);
var flags = ImageCreateFlags.CreateMutableFormatBit;
@ -291,7 +291,7 @@ namespace Ryujinx.Graphics.Vulkan
}
}
public static ImageUsageFlags GetImageUsage(Format format, Target target, bool supportsMsStorage, bool forceStorage = false)
public static ImageUsageFlags GetImageUsage(Format format, Target target, bool supportsMsStorage)
{
var usage = DefaultUsageFlags;
@ -304,7 +304,7 @@ namespace Ryujinx.Graphics.Vulkan
usage |= ImageUsageFlags.ColorAttachmentBit;
}
if (((forceStorage && !format.IsDepthOrStencil()) || format.IsImageCompatible()) && (supportsMsStorage || !target.IsMultisample()))
if (format.IsImageCompatible() && (supportsMsStorage || !target.IsMultisample()))
{
usage |= ImageUsageFlags.StorageBit;
}
@ -440,25 +440,27 @@ namespace Ryujinx.Graphics.Vulkan
_lastModificationStage = stage;
}
public void InsertReadToWriteBarrier(CommandBufferScoped cbs, AccessFlags dstAccessFlags, PipelineStageFlags dstStageFlags)
public void InsertReadToWriteBarrier(CommandBufferScoped cbs, AccessFlags dstAccessFlags, PipelineStageFlags dstStageFlags, bool insideRenderPass)
{
if (_lastReadAccess != AccessFlags.None)
{
ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags();
var lastReadStage = _lastReadStage;
TextureView.InsertImageBarrier(
if (insideRenderPass)
{
// We can't have barrier from compute inside a render pass,
// as it is invalid to specify compute in the subpass dependency stage mask.
lastReadStage &= ~PipelineStageFlags.ComputeShaderBit;
}
if (lastReadStage != PipelineStageFlags.None)
{
TextureView.InsertMemoryBarrier(
_gd.Api,
cbs.CommandBuffer,
_imageAuto.Get(cbs).Value,
_lastReadAccess,
dstAccessFlags,
_lastReadStage,
dstStageFlags,
aspectFlags,
0,
0,
_info.GetLayers(),
_info.Levels);
lastReadStage,
dstStageFlags);
_lastReadAccess = AccessFlags.None;
_lastReadStage = PipelineStageFlags.None;
@ -472,21 +474,13 @@ namespace Ryujinx.Graphics.Vulkan
if (_lastModificationAccess != AccessFlags.None)
{
ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags();
TextureView.InsertImageBarrier(
TextureView.InsertMemoryBarrier(
_gd.Api,
cbs.CommandBuffer,
_imageAuto.Get(cbs).Value,
_lastModificationAccess,
dstAccessFlags,
_lastModificationStage,
dstStageFlags,
aspectFlags,
0,
0,
_info.GetLayers(),
_info.Levels);
dstStageFlags);
_lastModificationAccess = AccessFlags.None;
}