From: Józef Kucia jkucia@codeweavers.com
An application uses the following pattern:
Wait(queue, fence, value); ExecuteCommandLists(queue, count, lists); Wait(queue, fence, value); ExecuteCommandLists(queue, count2, lists2);
In this case, we don't need to wait for the fence again.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d/command.c | 41 ++++++++++++++++++++++++++------------ libs/vkd3d/vkd3d_private.h | 3 +++ 2 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 07de716faa04..606c5bb78a50 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -5471,11 +5471,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface); const struct vkd3d_vk_device_procs *vk_procs; struct vkd3d_signaled_semaphore *semaphore; - VkQueue vk_queue = VK_NULL_HANDLE; uint64_t completed_value = 0; struct vkd3d_queue *queue; struct d3d12_fence *fence; VkSubmitInfo submit_info; + VkQueue vk_queue; VkResult vr; HRESULT hr;
@@ -5486,18 +5486,34 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if
fence = unsafe_impl_from_ID3D12Fence(fence_iface);
- if (!(semaphore = d3d12_fence_acquire_vk_semaphore(fence, value, &completed_value))) + semaphore = d3d12_fence_acquire_vk_semaphore(fence, value, &completed_value); + if (!semaphore && completed_value >= value) + { + /* We don't get a Vulkan semaphore if the fence was signaled on CPU. */ + TRACE("Already signaled %p, value %#"PRIx64".\n", fence, completed_value); + return S_OK; + } + + if (!(vk_queue = vkd3d_queue_acquire(queue))) + { + ERR("Failed to acquire queue %p.\n", queue); + hr = E_FAIL; + goto fail; + } + + if (!semaphore) { - if (completed_value >= value) + if (command_queue->last_waited_fence == fence && command_queue->last_waited_fence_value >= value) { - TRACE("Already signaled %p, value %#"PRIx64".\n", fence, completed_value); + WARN("Already waited on fence %p, value %#"PRIx64".\n", fence, value); } else { - FIXME("Failed to acquire Vulkan semaphore for fence %p, value %#"PRIx64", completed value %#"PRIx64".\n", - fence, value, completed_value); + FIXME("Failed to acquire Vulkan semaphore for fence %p, value %#"PRIx64 + ", completed value %#"PRIx64".\n", fence, value, completed_value); }
+ vkd3d_queue_release(queue); return S_OK; }
@@ -5511,13 +5527,6 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if submit_info.signalSemaphoreCount = 0; submit_info.pSignalSemaphores = NULL;
- if (!(vk_queue = vkd3d_queue_acquire(queue))) - { - ERR("Failed to acquire queue %p.\n", queue); - hr = E_FAIL; - goto fail; - } - if (!vkd3d_array_reserve((void **)&queue->semaphores, &queue->semaphores_size, queue->semaphore_count + 1, sizeof(*queue->semaphores))) { @@ -5532,6 +5541,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if queue->semaphores[queue->semaphore_count].vk_semaphore = semaphore->vk_semaphore; queue->semaphores[queue->semaphore_count].sequence_number = queue->submitted_sequence_number + 1; ++queue->semaphore_count; + + command_queue->last_waited_fence = fence; + command_queue->last_waited_fence_value = value; }
vkd3d_queue_release(queue); @@ -5632,6 +5644,9 @@ static HRESULT d3d12_command_queue_init(struct d3d12_command_queue *queue, if (!(queue->vkd3d_queue = d3d12_device_get_vkd3d_queue(device, desc->Type))) return E_NOTIMPL;
+ queue->last_waited_fence = NULL; + queue->last_waited_fence_value = 0; + if (desc->Priority == D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME) { FIXME("Global realtime priority is not implemented.\n"); diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index b5beffaf5d5e..402ac0aaa791 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -924,6 +924,9 @@ struct d3d12_command_queue
struct vkd3d_queue *vkd3d_queue;
+ const struct d3d12_fence *last_waited_fence; + uint64_t last_waited_fence_value; + struct d3d12_device *device;
struct vkd3d_private_store private_store;