Simplifies the preservation of fence objects until worker threads are done with them, and will be needed when threaded queue submission is added.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d/command.c | 72 ++++++++++++-------------------------- libs/vkd3d/vkd3d_private.h | 4 +-- 2 files changed, 24 insertions(+), 52 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 09171fe4..7a373b34 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -20,6 +20,8 @@
#include "vkd3d_private.h"
+static void d3d12_fence_incref(struct d3d12_fence *fence); +static void d3d12_fence_decref(struct d3d12_fence *fence); static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkFence vk_fence);
HRESULT vkd3d_queue_create(struct d3d12_device *device, @@ -295,7 +297,7 @@ static HRESULT vkd3d_enqueue_gpu_fence(struct vkd3d_fence_worker *worker, waiting_fence->queue_sequence_number = queue_sequence_number; ++worker->enqueued_fence_count;
- InterlockedIncrement(&fence->pending_worker_operation_count); + d3d12_fence_incref(fence);
vkd3d_cond_signal(&worker->cond); vkd3d_mutex_unlock(&worker->mutex); @@ -303,37 +305,6 @@ 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, struct d3d12_fence *fence) -{ - LONG count; - int rc; - - if (!(count = InterlockedAdd(&fence->pending_worker_operation_count, 0))) - return; - - WARN("Waiting for %u pending fence operations (fence %p).\n", count, fence); - - if ((rc = vkd3d_mutex_lock(&worker->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return; - } - - while ((count = InterlockedAdd(&fence->pending_worker_operation_count, 0))) - { - TRACE("Still waiting for %u pending fence operations (fence %p).\n", count, fence); - - worker->pending_fence_destruction = true; - vkd3d_cond_signal(&worker->cond); - - vkd3d_cond_wait(&worker->fence_destruction_cond, &worker->mutex); - } - - TRACE("Removed fence %p.\n", fence); - - vkd3d_mutex_unlock(&worker->mutex); -} - static void vkd3d_fence_worker_move_enqueued_fences_locked(struct vkd3d_fence_worker *worker) { unsigned int i; @@ -432,7 +403,7 @@ static void vkd3d_wait_for_gpu_timeline_semaphores(struct vkd3d_fence_worker *wo if (FAILED(hr = d3d12_fence_signal(current->fence, counter_value, VK_NULL_HANDLE))) ERR("Failed to signal D3D12 fence, hr %#x.\n", hr);
- InterlockedDecrement(¤t->fence->pending_worker_operation_count); + d3d12_fence_decref(current->fence); continue; }
@@ -480,7 +451,7 @@ static void vkd3d_wait_for_gpu_fences(struct vkd3d_fence_worker *worker) if (FAILED(hr = d3d12_fence_signal(current->fence, current->value, vk_fence))) ERR("Failed to signal D3D12 fence, hr %#x.\n", hr);
- InterlockedDecrement(¤t->fence->pending_worker_operation_count); + d3d12_fence_decref(current->fence);
vkd3d_queue_update_sequence_number(current->queue, current->queue_sequence_number, device); continue; @@ -518,12 +489,6 @@ static void *vkd3d_fence_worker_main(void *arg) break; }
- if (worker->pending_fence_destruction) - { - vkd3d_cond_broadcast(&worker->fence_destruction_cond); - worker->pending_fence_destruction = false; - } - if (worker->enqueued_fence_count) { vkd3d_fence_worker_move_enqueued_fences_locked(worker); @@ -560,7 +525,6 @@ HRESULT vkd3d_fence_worker_start(struct vkd3d_fence_worker *worker, TRACE("worker %p.\n", worker);
worker->should_exit = false; - worker->pending_fence_destruction = false; worker->device = device;
worker->enqueued_fence_count = 0; @@ -1026,22 +990,35 @@ static ULONG STDMETHODCALLTYPE d3d12_fence_AddRef(ID3D12Fence *iface) return refcount; }
+static void d3d12_fence_incref(struct d3d12_fence *fence) +{ + InterlockedIncrement(&fence->internal_refcount); +} + static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence *iface) { struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); ULONG refcount = InterlockedDecrement(&fence->refcount); - int rc;
TRACE("%p decreasing refcount to %u.\n", fence, refcount);
if (!refcount) + d3d12_fence_decref(fence); + + return refcount; +} + +static void d3d12_fence_decref(struct d3d12_fence *fence) +{ + ULONG internal_refcount = InterlockedDecrement(&fence->internal_refcount); + int rc; + + if (!internal_refcount) { struct d3d12_device *device = fence->device;
vkd3d_private_store_destroy(&fence->private_store);
- vkd3d_fence_worker_remove_fence(&device->fence_worker, fence); - d3d12_fence_destroy_vk_objects(fence);
vkd3d_free(fence->events); @@ -1052,8 +1029,6 @@ static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence *iface)
d3d12_device_release(device); } - - return refcount; }
static HRESULT STDMETHODCALLTYPE d3d12_fence_GetPrivateData(ID3D12Fence *iface, @@ -1380,6 +1355,7 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device * int rc;
fence->ID3D12Fence_iface.lpVtbl = &d3d12_fence_vtbl; + fence->internal_refcount = 1; fence->refcount = 1;
fence->value = initial_value; @@ -1419,8 +1395,6 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *
memset(fence->old_vk_fences, 0, sizeof(fence->old_vk_fences));
- fence->pending_worker_operation_count = 0; - if (FAILED(hr = vkd3d_private_store_init(&fence->private_store))) { vkd3d_mutex_destroy(&fence->mutex); @@ -6496,7 +6470,7 @@ static HRESULT vkd3d_enqueue_timeline_semaphore(struct vkd3d_fence_worker *worke waiting_fence->queue = queue; ++worker->enqueued_fence_count;
- InterlockedIncrement(&fence->pending_worker_operation_count); + d3d12_fence_incref(fence);
vkd3d_cond_signal(&worker->cond); vkd3d_mutex_unlock(&worker->mutex); diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 56060b6d..a0163c8d 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -346,7 +346,6 @@ struct vkd3d_fence_worker struct vkd3d_cond cond; struct vkd3d_cond fence_destruction_cond; bool should_exit; - bool pending_fence_destruction;
LONG enqueued_fence_count; struct vkd3d_enqueued_fence @@ -532,6 +531,7 @@ struct vkd3d_pending_fence_wait struct d3d12_fence { ID3D12Fence ID3D12Fence_iface; + LONG internal_refcount; LONG refcount;
uint64_t value; @@ -555,8 +555,6 @@ struct d3d12_fence struct list semaphores; unsigned int semaphore_count;
- LONG pending_worker_operation_count; - VkFence old_vk_fences[VKD3D_MAX_VK_SYNC_OBJECTS];
struct d3d12_device *device;