diff options
Diffstat (limited to 'Ryujinx.Graphics.Vulkan/SyncManager.cs')
-rw-r--r-- | Ryujinx.Graphics.Vulkan/SyncManager.cs | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/Ryujinx.Graphics.Vulkan/SyncManager.cs b/Ryujinx.Graphics.Vulkan/SyncManager.cs index 35e3adf1..c046dc3c 100644 --- a/Ryujinx.Graphics.Vulkan/SyncManager.cs +++ b/Ryujinx.Graphics.Vulkan/SyncManager.cs @@ -11,7 +11,13 @@ namespace Ryujinx.Graphics.Vulkan { public ulong ID; public MultiFenceHolder Waitable; + public ulong FlushId; public bool Signalled; + + public bool NeedsFlush(ulong currentFlushId) + { + return (long)(FlushId - currentFlushId) >= 0; + } } private ulong _firstHandle = 0; @@ -19,6 +25,7 @@ namespace Ryujinx.Graphics.Vulkan private readonly VulkanRenderer _gd; private readonly Device _device; private List<SyncHandle> _handles; + private ulong FlushId; public SyncManager(VulkanRenderer gd, Device device) { @@ -27,17 +34,33 @@ namespace Ryujinx.Graphics.Vulkan _handles = new List<SyncHandle>(); } - public void Create(ulong id) + public void RegisterFlush() + { + FlushId++; + } + + public void Create(ulong id, bool strict) { + ulong flushId = FlushId; MultiFenceHolder waitable = new MultiFenceHolder(); + if (strict || _gd.InterruptAction == null) + { + _gd.FlushAllCommands(); + _gd.CommandBufferPool.AddWaitable(waitable); + } + else + { + // Don't flush commands, instead wait for the current command buffer to finish. + // If this sync is waited on before the command buffer is submitted, interrupt the gpu thread and flush it manually. - _gd.FlushAllCommands(); - _gd.CommandBufferPool.AddWaitable(waitable); + _gd.CommandBufferPool.AddInUseWaitable(waitable); + } SyncHandle handle = new SyncHandle { ID = id, - Waitable = waitable + Waitable = waitable, + FlushId = flushId }; lock (_handles) @@ -107,6 +130,17 @@ namespace Ryujinx.Graphics.Vulkan return; } + if (result.NeedsFlush(FlushId)) + { + _gd.InterruptAction(() => + { + if (result.NeedsFlush(FlushId)) + { + _gd.FlushAllCommands(); + } + }); + } + bool signaled = result.Signalled || result.Waitable.WaitForFences(_gd.Api, _device, 1000000000); if (!signaled) { @@ -132,7 +166,7 @@ namespace Ryujinx.Graphics.Vulkan first = _handles.FirstOrDefault(); } - if (first == null) break; + if (first == null || first.NeedsFlush(FlushId)) break; bool signaled = first.Waitable.WaitForFences(_gd.Api, _device, 0); if (signaled) |