aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Ava/Ui/Backend/Vulkan/VulkanCommandBufferPool.cs
diff options
context:
space:
mode:
authorEmmanuel Hansen <emmausssss@gmail.com>2022-08-16 16:32:37 +0000
committerGitHub <noreply@github.com>2022-08-16 16:32:37 +0000
commitc8f9292babd5aa6021ce1bd6a977130baebb7de3 (patch)
treee6e62d79d08726129485476078732f9b89f6ab5c /Ryujinx.Ava/Ui/Backend/Vulkan/VulkanCommandBufferPool.cs
parent0ec933a6152ebb7724da1e3a05a5ae1c2ea07b2f (diff)
Avalonia - Couple fixes and improvements to vulkan (#3483)1.1.219
* drop split devices, rebase * add fallback to opengl if vulkan is not available * addressed review * ensure present image references are incremented and decremented when necessary * allow changing vsync for vulkan * fix screenshot on avalonia vulkan * save favorite when toggled * improve sync between popups * use separate devices for each new window * fix crash when closing window * addressed review * don't create the main window with immediate mode * change skia vk delegate to method * update vulkan throwonerror * addressed review
Diffstat (limited to 'Ryujinx.Ava/Ui/Backend/Vulkan/VulkanCommandBufferPool.cs')
-rw-r--r--Ryujinx.Ava/Ui/Backend/Vulkan/VulkanCommandBufferPool.cs51
1 files changed, 42 insertions, 9 deletions
diff --git a/Ryujinx.Ava/Ui/Backend/Vulkan/VulkanCommandBufferPool.cs b/Ryujinx.Ava/Ui/Backend/Vulkan/VulkanCommandBufferPool.cs
index 240035ca..a00ecf2b 100644
--- a/Ryujinx.Ava/Ui/Backend/Vulkan/VulkanCommandBufferPool.cs
+++ b/Ryujinx.Ava/Ui/Backend/Vulkan/VulkanCommandBufferPool.cs
@@ -10,6 +10,7 @@ namespace Ryujinx.Ava.Ui.Vulkan
private readonly CommandPool _commandPool;
private readonly List<VulkanCommandBuffer> _usedCommandBuffers = new();
+ private readonly object _lock = new object();
public unsafe VulkanCommandBufferPool(VulkanDevice device, VulkanPhysicalDevice physicalDevice)
{
@@ -36,9 +37,12 @@ namespace Ryujinx.Ava.Ui.Vulkan
Level = CommandBufferLevel.Primary
};
- _device.Api.AllocateCommandBuffers(_device.InternalHandle, commandBufferAllocateInfo, out var commandBuffer);
+ lock (_lock)
+ {
+ _device.Api.AllocateCommandBuffers(_device.InternalHandle, commandBufferAllocateInfo, out var commandBuffer);
- return commandBuffer;
+ return commandBuffer;
+ }
}
public VulkanCommandBuffer CreateCommandBuffer()
@@ -48,7 +52,7 @@ namespace Ryujinx.Ava.Ui.Vulkan
public void FreeUsedCommandBuffers()
{
- lock (_usedCommandBuffers)
+ lock (_lock)
{
foreach (var usedCommandBuffer in _usedCommandBuffers)
{
@@ -61,7 +65,7 @@ namespace Ryujinx.Ava.Ui.Vulkan
private void DisposeCommandBuffer(VulkanCommandBuffer commandBuffer)
{
- lock (_usedCommandBuffers)
+ lock (_lock)
{
_usedCommandBuffers.Add(commandBuffer);
}
@@ -69,8 +73,11 @@ namespace Ryujinx.Ava.Ui.Vulkan
public void Dispose()
{
- FreeUsedCommandBuffers();
- _device.Api.DestroyCommandPool(_device.InternalHandle, _commandPool, Span<AllocationCallbacks>.Empty);
+ lock (_lock)
+ {
+ FreeUsedCommandBuffers();
+ _device.Api.DestroyCommandPool(_device.InternalHandle, _commandPool, Span<AllocationCallbacks>.Empty);
+ }
}
public class VulkanCommandBuffer : IDisposable
@@ -80,6 +87,8 @@ namespace Ryujinx.Ava.Ui.Vulkan
private readonly Fence _fence;
private bool _hasEnded;
private bool _hasStarted;
+ private bool _isDisposed;
+ private object _lock = new object();
public IntPtr Handle => InternalHandle.Handle;
@@ -101,6 +110,22 @@ namespace Ryujinx.Ava.Ui.Vulkan
device.Api.CreateFence(device.InternalHandle, fenceCreateInfo, null, out _fence);
}
+ public void WaitForFence()
+ {
+ if (_isDisposed)
+ {
+ return;
+ }
+
+ lock (_lock)
+ {
+ if (!_isDisposed)
+ {
+ _device.Api.WaitForFences(_device.InternalHandle, 1, _fence, true, ulong.MaxValue);
+ }
+ }
+ }
+
public void BeginRecording()
{
if (!_hasStarted)
@@ -173,9 +198,17 @@ namespace Ryujinx.Ava.Ui.Vulkan
public void Dispose()
{
- _device.Api.WaitForFences(_device.InternalHandle, 1, _fence, true, ulong.MaxValue);
- _device.Api.FreeCommandBuffers(_device.InternalHandle, _commandBufferPool._commandPool, 1, InternalHandle);
- _device.Api.DestroyFence(_device.InternalHandle, _fence, Span<AllocationCallbacks>.Empty);
+ lock (_lock)
+ {
+ if (!_isDisposed)
+ {
+ _isDisposed = true;
+
+ _device.Api.WaitForFences(_device.InternalHandle, 1, _fence, true, ulong.MaxValue);
+ _device.Api.FreeCommandBuffers(_device.InternalHandle, _commandBufferPool._commandPool, 1, InternalHandle);
+ _device.Api.DestroyFence(_device.InternalHandle, _fence, Span<AllocationCallbacks>.Empty);
+ }
+ }
}
}
}