Prevent waits with zero timeout on Turnip

This commit is contained in:
gdkchan
2026-08-12 14:00:36 -05:00
committed by KeatonTheBot
parent 2eecc18dc7
commit 8ccf83d9a3
5 changed files with 24 additions and 5 deletions
@@ -36,6 +36,7 @@ namespace Ryujinx.Graphics.Vulkan
queueLock, queueLock,
_gd.QueueFamilyIndex, _gd.QueueFamilyIndex,
_gd.IsQualcommProprietary, _gd.IsQualcommProprietary,
_gd.IsTurnip,
isLight: true); isLight: true);
} }
} }
@@ -19,6 +19,7 @@ namespace Ryujinx.Graphics.Vulkan
private readonly Queue _queue; private readonly Queue _queue;
private readonly Lock _queueLock; private readonly Lock _queueLock;
private readonly bool _concurrentFenceWaitUnsupported; private readonly bool _concurrentFenceWaitUnsupported;
private readonly bool _fenceAlwaysWaits;
private readonly CommandPool _pool; private readonly CommandPool _pool;
private readonly Thread _owner; private readonly Thread _owner;
@@ -66,6 +67,7 @@ namespace Ryujinx.Graphics.Vulkan
Lock queueLock, Lock queueLock,
uint queueFamilyIndex, uint queueFamilyIndex,
bool concurrentFenceWaitUnsupported, bool concurrentFenceWaitUnsupported,
bool fenceAlwaysWaits,
bool isLight = false) bool isLight = false)
{ {
_api = api; _api = api;
@@ -73,6 +75,7 @@ namespace Ryujinx.Graphics.Vulkan
_queue = queue; _queue = queue;
_queueLock = queueLock; _queueLock = queueLock;
_concurrentFenceWaitUnsupported = concurrentFenceWaitUnsupported; _concurrentFenceWaitUnsupported = concurrentFenceWaitUnsupported;
_fenceAlwaysWaits = fenceAlwaysWaits;
_owner = Thread.CurrentThread; _owner = Thread.CurrentThread;
CommandPoolCreateInfo commandPoolCreateInfo = new() CommandPoolCreateInfo commandPoolCreateInfo = new()
@@ -207,7 +210,7 @@ namespace Ryujinx.Graphics.Vulkan
ref ReservedCommandBuffer entry = ref _commandBuffers[index]; ref ReservedCommandBuffer entry = ref _commandBuffers[index];
if (wait || !entry.InConsumption || entry.Fence.IsSignaled()) if (wait || !entry.InConsumption || entry.Fence.IsSignaledLazy())
{ {
WaitAndDecrementRef(index); WaitAndDecrementRef(index);
@@ -349,7 +352,7 @@ namespace Ryujinx.Graphics.Vulkan
if (refreshFence) if (refreshFence)
{ {
entry.Fence = new FenceHolder(_api, _device, _concurrentFenceWaitUnsupported); entry.Fence = new FenceHolder(_api, _device, _concurrentFenceWaitUnsupported, _fenceAlwaysWaits);
} }
else else
{ {
+13 -1
View File
@@ -12,13 +12,15 @@ namespace Ryujinx.Graphics.Vulkan
private int _referenceCount; private int _referenceCount;
private int _lock; private int _lock;
private readonly bool _concurrentWaitUnsupported; private readonly bool _concurrentWaitUnsupported;
private readonly bool _alwaysWaits;
private bool _disposed; private bool _disposed;
public unsafe FenceHolder(Vk api, Device device, bool concurrentWaitUnsupported) public unsafe FenceHolder(Vk api, Device device, bool concurrentWaitUnsupported, bool alwaysWaits)
{ {
_api = api; _api = api;
_device = device; _device = device;
_concurrentWaitUnsupported = concurrentWaitUnsupported; _concurrentWaitUnsupported = concurrentWaitUnsupported;
_alwaysWaits = alwaysWaits;
FenceCreateInfo fenceCreateInfo = new() FenceCreateInfo fenceCreateInfo = new()
{ {
@@ -123,6 +125,16 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
public bool IsSignaledLazy()
{
if (_alwaysWaits)
{
return false;
}
return IsSignaled();
}
public bool IsSignaled() public bool IsSignaled()
{ {
if (_concurrentWaitUnsupported) if (_concurrentWaitUnsupported)
+1 -1
View File
@@ -266,7 +266,7 @@ namespace Ryujinx.Graphics.Vulkan
public void FreeCompleted() public void FreeCompleted()
{ {
FenceHolder signalledFence = null; FenceHolder signalledFence = null;
while (_pendingCopies.TryPeek(out PendingCopy pc) && pc.Fence != null && (pc.Fence == signalledFence || pc.Fence.IsSignaled())) while (_pendingCopies.TryPeek(out PendingCopy pc) && pc.Fence != null && (pc.Fence == signalledFence || pc.Fence.IsSignaledLazy()))
{ {
signalledFence = pc.Fence; // Already checked - don't need to do it again. signalledFence = pc.Fence; // Already checked - don't need to do it again.
PendingCopy dequeued = _pendingCopies.Dequeue(); PendingCopy dequeued = _pendingCopies.Dequeue();
@@ -106,6 +106,7 @@ namespace Ryujinx.Graphics.Vulkan
internal bool IsNvidiaPreTuring { get; private set; } internal bool IsNvidiaPreTuring { get; private set; }
internal bool IsIntelArc { get; private set; } internal bool IsIntelArc { get; private set; }
internal bool IsQualcommProprietary { get; private set; } internal bool IsQualcommProprietary { get; private set; }
internal bool IsTurnip { get; private set; }
internal bool IsMoltenVk { get; private set; } internal bool IsMoltenVk { get; private set; }
internal bool IsTBDR { get; private set; } internal bool IsTBDR { get; private set; }
internal bool IsSharedMemory { get; private set; } internal bool IsSharedMemory { get; private set; }
@@ -393,6 +394,8 @@ namespace Ryujinx.Graphics.Vulkan
IsFeedbackLoopDevice = IsAmdRdna3 || IsAdreno6xx || IsAdreno7xx; IsFeedbackLoopDevice = IsAmdRdna3 || IsAdreno6xx || IsAdreno7xx;
IsTurnip = GpuRenderer.StartsWith("Turnip");
if (Vendor == Vendor.Nvidia) if (Vendor == Vendor.Nvidia)
{ {
Match match = VendorUtils.NvidiaConsumerClassRegex().Match(GpuRenderer); Match match = VendorUtils.NvidiaConsumerClassRegex().Match(GpuRenderer);
@@ -473,7 +476,7 @@ namespace Ryujinx.Graphics.Vulkan
Api.TryGetDeviceExtension(_instance.Instance, _device, out ExtExternalMemoryHost hostMemoryApi); Api.TryGetDeviceExtension(_instance.Instance, _device, out ExtExternalMemoryHost hostMemoryApi);
HostMemoryAllocator = new HostMemoryAllocator(MemoryAllocator, Api, hostMemoryApi, _device); HostMemoryAllocator = new HostMemoryAllocator(MemoryAllocator, Api, hostMemoryApi, _device);
CommandBufferPool = new CommandBufferPool(Api, _device, Queue, QueueLock, queueFamilyIndex, IsQualcommProprietary); CommandBufferPool = new CommandBufferPool(Api, _device, Queue, QueueLock, queueFamilyIndex, IsQualcommProprietary, IsTurnip);
PipelineLayoutCache = new PipelineLayoutCache(); PipelineLayoutCache = new PipelineLayoutCache();