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)
{
_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;

View file

@ -143,16 +143,9 @@ namespace Ryujinx.Graphics.Vulkan
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
{
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 Device _device;
private readonly Queue _queue;
private readonly object _queueLock;
private readonly CommandPool _pool;
private readonly Thread _owner;
@ -58,11 +59,12 @@ namespace Ryujinx.Graphics.Vulkan
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;
_device = device;
_queue = queue;
_queueLock = queueLock;
_owner = Thread.CurrentThread;
var commandPoolCreateInfo = new CommandPoolCreateInfo()
@ -272,7 +274,10 @@ namespace Ryujinx.Graphics.Vulkan
PSignalSemaphores = pSignalSemaphores
};
_api.QueueSubmit(_queue, 1, sInfo, entry.Fence.GetUnsafe());
lock (_queueLock)
{
_api.QueueSubmit(_queue, 1, sInfo, entry.Fence.GetUnsafe());
}
}
}
// _api.QueueWaitIdle(_queue);

View file

@ -233,20 +233,13 @@ namespace Ryujinx.Graphics.Vulkan
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
{
// 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());
}
else if (_gd.BackgroundQueue.Handle != 0)
{
lock (_gd.BackgroundQueueLock)
{
return GetData(resources.GetPool(), resources.GetFlushBuffer());
}
}
else
{
// TODO: Flush when the device only supports one queue.
int size = 0;
for (int level = 0; level < Info.Levels; level++)
{
size += Info.GetMipSize(level);
}
return new byte[size];
return GetData(resources.GetPool(), resources.GetFlushBuffer());
}
}

View file

@ -44,6 +44,7 @@ namespace Ryujinx.Graphics.Vulkan
internal Queue Queue { get; private set; }
internal Queue BackgroundQueue { get; private set; }
internal object BackgroundQueueLock { get; private set; }
internal object QueueLock { get; private set; }
internal MemoryAllocator MemoryAllocator { 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);
Queue = queue;
QueueLock = new object();
if (maxQueueCount >= 2)
{
@ -165,7 +167,7 @@ namespace Ryujinx.Graphics.Vulkan
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);

View file

@ -418,9 +418,9 @@ namespace Ryujinx.Graphics.Vulkan
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
};
_gd.SwapchainApi.QueuePresent(_gd.Queue, presentInfo);
lock (_gd.QueueLock)
{
_gd.SwapchainApi.QueuePresent(_gd.Queue, presentInfo);
}
}
private unsafe void Transition(