aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Vulkan/SyncManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Vulkan/SyncManager.cs')
-rw-r--r--Ryujinx.Graphics.Vulkan/SyncManager.cs44
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)