Conor McCarthy : vkd3d: Delay unlocking the fence until after the blocked command queue op is written.

Alexandre Julliard julliard at winehq.org
Wed Jul 20 15:30:52 CDT 2022


Module: vkd3d
Branch: master
Commit: 3b579f6fe7baa7c3f7e5e857458da7d1fae853bf
URL:    https://gitlab.winehq.org/wine/vkd3d/-/commit/3b579f6fe7baa7c3f7e5e857458da7d1fae853bf

Author: Conor McCarthy <cmccarthy at codeweavers.com>
Date:   Mon Jul 18 13:08:01 2022 +1000

vkd3d: Delay unlocking the fence until after the blocked command queue op is written.

An unblocking Signal() on the CPU must be handled after the blocked op
is written, or the op will not be flushed until the next signal.

The device is locked while the fence is already locked, so the fence must
never be locked after locking the device. Currently this never occurs.

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 libs/vkd3d/command.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index eb163848..e0201d5d 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -6804,8 +6804,6 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if
         goto done;
     }
 
-    vkd3d_mutex_unlock(&fence->mutex);
-
     /* This is the critical part required to support out-of-order signal.
      * Normally we would be able to submit waits and signals out of order, but
      * we don't have virtualized queues in Vulkan, so we need to handle the case
@@ -6814,6 +6812,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if
 
     if (!(op = d3d12_command_queue_require_space_locked(command_queue)))
     {
+        vkd3d_mutex_unlock(&fence->mutex);
         hr = E_OUTOFMEMORY;
         goto done;
     }
@@ -6828,6 +6827,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if
     if (command_queue->ops_count == 1)
         hr = d3d12_device_add_blocked_command_queues(command_queue->device, &command_queue, 1);
 
+    /* The fence must remain locked until the op is created and the queue is added to the blocked list,
+     * because if an unblocking d3d12_fence_Signal() call occurs on another thread before the above
+     * work is done, flushing will be delayed until the next signal, if one occurs at all. */
+    vkd3d_mutex_unlock(&fence->mutex);
+
 done:
     vkd3d_mutex_unlock(&command_queue->op_mutex);
     return hr;




More information about the wine-cvs mailing list