From 4d94b036220a9678e13043f34eb193f727eee0d1 Mon Sep 17 00:00:00 2001 From: riperiperi Date: Thu, 23 Dec 2021 03:13:48 +0000 Subject: [PATCH] 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. --- .../BackgroundResources.cs | 9 ++++- Ryujinx.Graphics.Vulkan/BufferHolder.cs | 9 +---- Ryujinx.Graphics.Vulkan/CommandBufferPool.cs | 9 +++-- Ryujinx.Graphics.Vulkan/TextureView.cs | 34 ++++--------------- .../VulkanGraphicsDevice.cs | 4 ++- .../VulkanInitialization.cs | 4 +-- Ryujinx.Graphics.Vulkan/Window.cs | 5 ++- 7 files changed, 31 insertions(+), 43 deletions(-) diff --git a/Ryujinx.Graphics.Vulkan/BackgroundResources.cs b/Ryujinx.Graphics.Vulkan/BackgroundResources.cs index cd9c91b14..e60e48451 100644 --- a/Ryujinx.Graphics.Vulkan/BackgroundResources.cs +++ b/Ryujinx.Graphics.Vulkan/BackgroundResources.cs @@ -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; diff --git a/Ryujinx.Graphics.Vulkan/BufferHolder.cs b/Ryujinx.Graphics.Vulkan/BufferHolder.cs index 78468bb6c..0d3a7c5e0 100644 --- a/Ryujinx.Graphics.Vulkan/BufferHolder.cs +++ b/Ryujinx.Graphics.Vulkan/BufferHolder.cs @@ -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); } } } diff --git a/Ryujinx.Graphics.Vulkan/CommandBufferPool.cs b/Ryujinx.Graphics.Vulkan/CommandBufferPool.cs index 752d6392f..042c020f5 100644 --- a/Ryujinx.Graphics.Vulkan/CommandBufferPool.cs +++ b/Ryujinx.Graphics.Vulkan/CommandBufferPool.cs @@ -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); diff --git a/Ryujinx.Graphics.Vulkan/TextureView.cs b/Ryujinx.Graphics.Vulkan/TextureView.cs index d5c414761..38b334486 100644 --- a/Ryujinx.Graphics.Vulkan/TextureView.cs +++ b/Ryujinx.Graphics.Vulkan/TextureView.cs @@ -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()); } } diff --git a/Ryujinx.Graphics.Vulkan/VulkanGraphicsDevice.cs b/Ryujinx.Graphics.Vulkan/VulkanGraphicsDevice.cs index 1d47cd386..36f7ff6f6 100644 --- a/Ryujinx.Graphics.Vulkan/VulkanGraphicsDevice.cs +++ b/Ryujinx.Graphics.Vulkan/VulkanGraphicsDevice.cs @@ -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); diff --git a/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs b/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs index 8c47172f8..5c64e76ec 100644 --- a/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs +++ b/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs @@ -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); } } } diff --git a/Ryujinx.Graphics.Vulkan/Window.cs b/Ryujinx.Graphics.Vulkan/Window.cs index 668d2adad..fafc3206a 100644 --- a/Ryujinx.Graphics.Vulkan/Window.cs +++ b/Ryujinx.Graphics.Vulkan/Window.cs @@ -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(