From 1a919e99b29fff4e2158e622cb3dfbee21293b6d Mon Sep 17 00:00:00 2001 From: riperiperi Date: Thu, 18 Jul 2024 00:21:32 +0100 Subject: Vulkan: Defer guest barriers, and improve image barrier timings (#7012) * More guarantees for buffer correct placement, defer guest requested buffers * Split RP on indirect barrier rn * Better handling for feedback loops. * Qualcomm barriers suck too * Fix condition * Remove unused field * Allow render pass barriers on turnip for now --- src/Ryujinx.Graphics.Vulkan/RenderPassHolder.cs | 40 ++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'src/Ryujinx.Graphics.Vulkan/RenderPassHolder.cs') diff --git a/src/Ryujinx.Graphics.Vulkan/RenderPassHolder.cs b/src/Ryujinx.Graphics.Vulkan/RenderPassHolder.cs index 9edea578..b2dd0dd8 100644 --- a/src/Ryujinx.Graphics.Vulkan/RenderPassHolder.cs +++ b/src/Ryujinx.Graphics.Vulkan/RenderPassHolder.cs @@ -1,5 +1,7 @@ using Silk.NET.Vulkan; using System; +using System.Collections.Generic; +using System.Linq; namespace Ryujinx.Graphics.Vulkan { @@ -29,10 +31,13 @@ namespace Ryujinx.Graphics.Vulkan } } + private readonly record struct ForcedFence(TextureStorage Texture, PipelineStageFlags StageFlags); + private readonly TextureView[] _textures; private readonly Auto _renderPass; private readonly HashTableSlim> _framebuffers; private readonly RenderPassCacheKey _key; + private readonly List _forcedFences; public unsafe RenderPassHolder(VulkanRenderer gd, Device device, RenderPassCacheKey key, FramebufferParams fb) { @@ -105,7 +110,7 @@ namespace Ryujinx.Graphics.Vulkan } } - var subpassDependency = PipelineConverter.CreateSubpassDependency(); + var subpassDependency = PipelineConverter.CreateSubpassDependency(gd); fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs) { @@ -138,6 +143,8 @@ namespace Ryujinx.Graphics.Vulkan _textures = textures; _key = key; + + _forcedFences = new List(); } public Auto GetFramebuffer(VulkanRenderer gd, CommandBufferScoped cbs, FramebufferParams fb) @@ -159,6 +166,37 @@ namespace Ryujinx.Graphics.Vulkan return _renderPass; } + public void AddForcedFence(TextureStorage storage, PipelineStageFlags stageFlags) + { + if (!_forcedFences.Any(fence => fence.Texture == storage)) + { + _forcedFences.Add(new ForcedFence(storage, stageFlags)); + } + } + + public void InsertForcedFences(CommandBufferScoped cbs) + { + if (_forcedFences.Count > 0) + { + _forcedFences.RemoveAll((entry) => + { + if (entry.Texture.Disposed) + { + return true; + } + + entry.Texture.QueueWriteToReadBarrier(cbs, AccessFlags.ShaderReadBit, entry.StageFlags); + + return false; + }); + } + } + + public bool ContainsAttachment(TextureStorage storage) + { + return _textures.Any(view => view.Storage == storage); + } + public void Dispose() { // Dispose all framebuffers. -- cgit v1.2.3