Add single queue support

Multiqueue seems to be a bit more responsive on NVIDIA. Should fix texture flush on intel. AMD has been forced to single queue for an experiment.
This commit is contained in:
riperiperi 2021-12-23 03:13:48 +00:00
parent dc0d0f49b1
commit 4d94b03622
7 changed files with 31 additions and 43 deletions

View file

@ -23,7 +23,14 @@ namespace Ryujinx.Graphics.Vulkan
{ {
if (_pool == null) if (_pool == null)
{ {
_pool = new CommandBufferPool(_gd.Api, _device, _gd.BackgroundQueue, _gd.QueueFamilyIndex, isLight: true); bool useBackground = _gd.BackgroundQueue.Handle != 0 && _gd.Vendor != Vendor.Amd;
Queue queue = useBackground ? _gd.BackgroundQueue : _gd.Queue;
object queueLock = useBackground ? _gd.BackgroundQueueLock : _gd.QueueLock;
lock (queueLock)
{
_pool = new CommandBufferPool(_gd.Api, _device, queue, queueLock, _gd.QueueFamilyIndex, isLight: true);
}
} }
return _pool; return _pool;

View file

@ -143,16 +143,9 @@ namespace Ryujinx.Graphics.Vulkan
return resource.GetFlushBuffer().GetBufferData(_gd.CommandBufferPool, this, offset, size); return resource.GetFlushBuffer().GetBufferData(_gd.CommandBufferPool, this, offset, size);
} }
else if (_gd.BackgroundQueue.Handle != 0)
{
lock (_gd.BackgroundQueueLock)
{
return resource.GetFlushBuffer().GetBufferData(resource.GetPool(), this, offset, size);
}
}
else else
{ {
return new byte[size]; return resource.GetFlushBuffer().GetBufferData(resource.GetPool(), this, offset, size);
} }
} }
} }

View file

@ -16,6 +16,7 @@ namespace Ryujinx.Graphics.Vulkan
private readonly Vk _api; private readonly Vk _api;
private readonly Device _device; private readonly Device _device;
private readonly Queue _queue; private readonly Queue _queue;
private readonly object _queueLock;
private readonly CommandPool _pool; private readonly CommandPool _pool;
private readonly Thread _owner; private readonly Thread _owner;
@ -58,11 +59,12 @@ namespace Ryujinx.Graphics.Vulkan
private int _cursor; private int _cursor;
public unsafe CommandBufferPool(Vk api, Device device, Queue queue, uint queueFamilyIndex, bool isLight = false) public unsafe CommandBufferPool(Vk api, Device device, Queue queue, object queueLock, uint queueFamilyIndex, bool isLight = false)
{ {
_api = api; _api = api;
_device = device; _device = device;
_queue = queue; _queue = queue;
_queueLock = queueLock;
_owner = Thread.CurrentThread; _owner = Thread.CurrentThread;
var commandPoolCreateInfo = new CommandPoolCreateInfo() var commandPoolCreateInfo = new CommandPoolCreateInfo()
@ -272,7 +274,10 @@ namespace Ryujinx.Graphics.Vulkan
PSignalSemaphores = pSignalSemaphores PSignalSemaphores = pSignalSemaphores
}; };
_api.QueueSubmit(_queue, 1, sInfo, entry.Fence.GetUnsafe()); lock (_queueLock)
{
_api.QueueSubmit(_queue, 1, sInfo, entry.Fence.GetUnsafe());
}
} }
} }
// _api.QueueWaitIdle(_queue); // _api.QueueWaitIdle(_queue);

View file

@ -233,20 +233,13 @@ namespace Ryujinx.Graphics.Vulkan
CopyToImpl(cbs, dst, srcRegion, dstRegion, linearFilter); CopyToImpl(cbs, dst, srcRegion, dstRegion, linearFilter);
} }
else if (_gd.BackgroundQueue.Handle != 0)
{
lock (_gd.BackgroundQueueLock)
{
var cbp = _gd.BackgroundResources.Get().GetPool();
using var cbs = cbp.Rent();
CopyToImpl(cbs, dst, srcRegion, dstRegion, linearFilter);
}
}
else else
{ {
// TODO... var cbp = _gd.BackgroundResources.Get().GetPool();
using var cbs = cbp.Rent();
CopyToImpl(cbs, dst, srcRegion, dstRegion, linearFilter);
} }
} }
@ -678,24 +671,9 @@ namespace Ryujinx.Graphics.Vulkan
return GetData(_gd.CommandBufferPool, resources.GetFlushBuffer()); return GetData(_gd.CommandBufferPool, resources.GetFlushBuffer());
} }
else if (_gd.BackgroundQueue.Handle != 0)
{
lock (_gd.BackgroundQueueLock)
{
return GetData(resources.GetPool(), resources.GetFlushBuffer());
}
}
else else
{ {
// TODO: Flush when the device only supports one queue. return GetData(resources.GetPool(), resources.GetFlushBuffer());
int size = 0;
for (int level = 0; level < Info.Levels; level++)
{
size += Info.GetMipSize(level);
}
return new byte[size];
} }
} }

View file

@ -44,6 +44,7 @@ namespace Ryujinx.Graphics.Vulkan
internal Queue Queue { get; private set; } internal Queue Queue { get; private set; }
internal Queue BackgroundQueue { get; private set; } internal Queue BackgroundQueue { get; private set; }
internal object BackgroundQueueLock { get; private set; } internal object BackgroundQueueLock { get; private set; }
internal object QueueLock { get; private set; }
internal MemoryAllocator MemoryAllocator { get; private set; } internal MemoryAllocator MemoryAllocator { get; private set; }
internal CommandBufferPool CommandBufferPool { get; private set; } internal CommandBufferPool CommandBufferPool { get; private set; }
@ -153,6 +154,7 @@ namespace Ryujinx.Graphics.Vulkan
api.GetDeviceQueue(_device, queueFamilyIndex, 0, out var queue); api.GetDeviceQueue(_device, queueFamilyIndex, 0, out var queue);
Queue = queue; Queue = queue;
QueueLock = new object();
if (maxQueueCount >= 2) if (maxQueueCount >= 2)
{ {
@ -165,7 +167,7 @@ namespace Ryujinx.Graphics.Vulkan
MemoryAllocator = new MemoryAllocator(api, _device, properties.Limits.MaxMemoryAllocationCount); MemoryAllocator = new MemoryAllocator(api, _device, properties.Limits.MaxMemoryAllocationCount);
CommandBufferPool = VulkanInitialization.CreateCommandBufferPool(api, _device, queue, queueFamilyIndex); CommandBufferPool = VulkanInitialization.CreateCommandBufferPool(api, _device, queue, QueueLock, queueFamilyIndex);
DescriptorSetManager = new DescriptorSetManager(_device); DescriptorSetManager = new DescriptorSetManager(_device);

View file

@ -418,9 +418,9 @@ namespace Ryujinx.Graphics.Vulkan
return extensionProperties.Select(x => Marshal.PtrToStringAnsi((IntPtr)x.ExtensionName)).ToArray(); return extensionProperties.Select(x => Marshal.PtrToStringAnsi((IntPtr)x.ExtensionName)).ToArray();
} }
public static CommandBufferPool CreateCommandBufferPool(Vk api, Device device, Queue queue, uint queueFamilyIndex) public static CommandBufferPool CreateCommandBufferPool(Vk api, Device device, Queue queue, object queueLock, uint queueFamilyIndex)
{ {
return new CommandBufferPool(api, device, queue, queueFamilyIndex); return new CommandBufferPool(api, device, queue, queueLock, queueFamilyIndex);
} }
} }
} }

View file

@ -352,7 +352,10 @@ namespace Ryujinx.Graphics.Vulkan
PResults = &result PResults = &result
}; };
_gd.SwapchainApi.QueuePresent(_gd.Queue, presentInfo); lock (_gd.QueueLock)
{
_gd.SwapchainApi.QueuePresent(_gd.Queue, presentInfo);
}
} }
private unsafe void Transition( private unsafe void Transition(