From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d/command.c | 109 +++++++++++++++++++++++-------------- libs/vkd3d/vkd3d_private.h | 6 +- 2 files changed, 71 insertions(+), 44 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index b9deffe33328..6c9b145fc522 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -19,6 +19,8 @@
#include "vkd3d_private.h"
+static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkFence vk_fence); + HRESULT vkd3d_queue_create(struct d3d12_device *device, uint32_t family_index, const VkQueueFamilyProperties *properties, struct vkd3d_queue **queue) { @@ -80,7 +82,7 @@ void vkd3d_queue_release(struct vkd3d_queue *queue)
/* Fence worker thread */ static HRESULT vkd3d_enqueue_gpu_fence(struct vkd3d_fence_worker *worker, - VkFence vk_fence, ID3D12Fence *fence, UINT64 value) + VkFence vk_fence, struct d3d12_fence *fence, uint64_t value) { int rc;
@@ -118,7 +120,7 @@ static HRESULT vkd3d_enqueue_gpu_fence(struct vkd3d_fence_worker *worker, return S_OK; }
-static void vkd3d_fence_worker_remove_fence(struct vkd3d_fence_worker *worker, ID3D12Fence *fence) +static void vkd3d_fence_worker_remove_fence(struct vkd3d_fence_worker *worker, struct d3d12_fence *fence) { struct d3d12_device *device = worker->device; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; @@ -156,6 +158,7 @@ static void vkd3d_wait_for_gpu_fences(struct vkd3d_fence_worker *worker) struct d3d12_device *device = worker->device; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; unsigned int i, j; + VkFence vk_fence; HRESULT hr; int vr;
@@ -174,12 +177,13 @@ static void vkd3d_wait_for_gpu_fences(struct vkd3d_fence_worker *worker)
for (i = 0, j = 0; i < worker->fence_count; ++i) { - if (!(vr = VK_CALL(vkGetFenceStatus(device->vk_device, worker->vk_fences[i])))) + vk_fence = worker->vk_fences[i]; + if (!(vr = VK_CALL(vkGetFenceStatus(device->vk_device, vk_fence)))) { struct vkd3d_waiting_fence *current = &worker->fences[i]; - if (FAILED(hr = ID3D12Fence_Signal(current->fence, current->value))) - ERR("Failed to signal D3D12 fence, hr %d.\n", hr); - VK_CALL(vkDestroyFence(device->vk_device, worker->vk_fences[i], NULL)); + TRACE("Signaling fence %p value %#"PRIx64".\n", current->fence, current->value); + if (FAILED(hr = d3d12_fence_signal(current->fence, current->value, vk_fence))) + ERR("Failed to signal D3D12 fence, hr %#x.\n", hr); continue; }
@@ -373,6 +377,48 @@ static struct d3d12_fence *impl_from_ID3D12Fence(ID3D12Fence *iface) return CONTAINING_RECORD(iface, struct d3d12_fence, ID3D12Fence_iface); }
+static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkFence vk_fence) +{ + struct d3d12_device *device = fence->device; + unsigned int i, j; + int rc; + + if (vk_fence) + { + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VK_CALL(vkDestroyFence(device->vk_device, vk_fence, NULL)); + } + + if ((rc = pthread_mutex_lock(&fence->mutex))) + { + ERR("Failed to lock mutex, error %d.\n", rc); + return hresult_from_errno(rc); + } + + fence->value = value; + + for (i = 0, j = 0; i < fence->event_count; ++i) + { + struct vkd3d_waiting_event *current = &fence->events[i]; + + if (current->value <= value) + { + fence->device->signal_event(current->event); + } + else + { + if (i != j) + fence->events[j] = *current; + ++j; + } + } + fence->event_count = j; + + pthread_mutex_unlock(&fence->mutex); + + return S_OK; +} + static HRESULT STDMETHODCALLTYPE d3d12_fence_QueryInterface(ID3D12Fence *iface, REFIID riid, void **object) { @@ -419,7 +465,7 @@ static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence *iface)
vkd3d_private_store_destroy(&fence->private_store);
- vkd3d_fence_worker_remove_fence(&device->fence_worker, iface); + vkd3d_fence_worker_remove_fence(&device->fence_worker, fence);
vkd3d_free(fence->events); if ((rc = pthread_mutex_destroy(&fence->mutex))) @@ -554,39 +600,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence *i static HRESULT STDMETHODCALLTYPE d3d12_fence_Signal(ID3D12Fence *iface, UINT64 value) { struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); - unsigned int i, j; - int rc;
TRACE("iface %p, value %#"PRIx64".\n", iface, value);
- if ((rc = pthread_mutex_lock(&fence->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return hresult_from_errno(rc); - } - - fence->value = value; - - for (i = 0, j = 0; i < fence->event_count; ++i) - { - struct vkd3d_waiting_event *current = &fence->events[i]; - - if (current->value <= value) - { - fence->device->signal_event(current->event); - } - else - { - if (i != j) - fence->events[j] = *current; - ++j; - } - } - fence->event_count = j; - - pthread_mutex_unlock(&fence->mutex); - - return S_OK; + return d3d12_fence_signal(fence, value, VK_NULL_HANDLE); }
static const struct ID3D12FenceVtbl d3d12_fence_vtbl = @@ -608,6 +625,14 @@ static const struct ID3D12FenceVtbl d3d12_fence_vtbl = d3d12_fence_Signal, };
+static struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d12_fence_vtbl); + return impl_from_ID3D12Fence(iface); +} + static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *device, UINT64 initial_value, D3D12_FENCE_FLAGS flags) { @@ -4886,21 +4911,24 @@ static void STDMETHODCALLTYPE d3d12_command_queue_EndEvent(ID3D12CommandQueue *i }
static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Signal(ID3D12CommandQueue *iface, - ID3D12Fence *fence, UINT64 value) + ID3D12Fence *fence_iface, UINT64 value) { struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface); const struct vkd3d_vk_device_procs *vk_procs; VkFenceCreateInfo fence_info; struct d3d12_device *device; + struct d3d12_fence *fence; VkFence vk_fence; VkQueue vk_queue; VkResult vr;
- TRACE("iface %p, fence %p, value %#"PRIx64".\n", iface, fence, value); + TRACE("iface %p, fence %p, value %#"PRIx64".\n", iface, fence_iface, value);
device = command_queue->device; vk_procs = &device->vk_procs;
+ fence = unsafe_impl_from_ID3D12Fence(fence_iface); + fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fence_info.pNext = NULL; fence_info.flags = 0; @@ -4929,8 +4957,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Signal(ID3D12CommandQueue * vr = VK_CALL(vkGetFenceStatus(device->vk_device, vk_fence)); if (vr == VK_SUCCESS) { - VK_CALL(vkDestroyFence(device->vk_device, vk_fence, NULL)); - return d3d12_fence_Signal(fence, value); + return d3d12_fence_signal(fence, value, vk_fence); } if (vr != VK_NOT_READY) { diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 76fec700f82e..68a51c0d85d6 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -147,7 +147,7 @@ struct vkd3d_fence_worker size_t vk_fences_size; struct vkd3d_waiting_fence { - ID3D12Fence *fence; + struct d3d12_fence *fence; UINT64 value; } *fences; size_t fences_size; @@ -249,12 +249,12 @@ struct d3d12_fence ID3D12Fence ID3D12Fence_iface; LONG refcount;
- UINT64 value; + uint64_t value; pthread_mutex_t mutex;
struct vkd3d_waiting_event { - UINT64 value; + uint64_t value; HANDLE event; } *events; size_t events_size;