From 2f76260857a643503f6c57a9f64b04dfb7e586a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Sat, 8 Oct 2016 14:31:57 +0200 Subject: [PATCH] libs/vkd3d: Create fence worker thread per device. --- libs/vkd3d/command.c | 94 ++++++++++++++++++++++++++++++++++++++ libs/vkd3d/device.c | 9 ++++ libs/vkd3d/vkd3d_private.h | 13 ++++++ 3 files changed, 116 insertions(+) diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index cac89500..77f2f58f 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -23,6 +23,100 @@ #include "vkd3d_private.h" +/* Fence worker thread */ +static void *vkd3d_fence_worker_main(void *arg) +{ + struct vkd3d_fence_worker *worker = arg; + int rc; + + for (;;) + { + if ((rc = pthread_mutex_lock(&worker->mutex))) + { + ERR("Failed to lock mutex, error %d.\n", rc); + return NULL; + } + + if (worker->should_exit) + { + pthread_mutex_unlock(&worker->mutex); + break; + } + + if ((rc = pthread_cond_wait(&worker->cond, &worker->mutex))) + { + ERR("Failed to wait on condition variable, error %d.\n", rc); + pthread_mutex_unlock(&worker->mutex); + return NULL; + } + + pthread_mutex_unlock(&worker->mutex); + } + + return NULL; +} + +HRESULT vkd3d_start_fence_worker(struct vkd3d_fence_worker *worker) +{ + int rc; + + TRACE("worker %p.\n", worker); + + worker->should_exit = false; + + if ((rc = pthread_mutex_init(&worker->mutex, NULL))) + { + ERR("Failed to initialize mutex, error %d.\n", rc); + return E_FAIL; + } + + if ((rc = pthread_cond_init(&worker->cond, NULL))) + { + ERR("Failed to initialize condition variable, error %d.\n", rc); + pthread_mutex_destroy(&worker->mutex); + return E_FAIL; + } + + if ((rc = pthread_create(&worker->thread, NULL, vkd3d_fence_worker_main, worker))) + { + ERR("Failed to create fence worker thread, error %d.\n", rc); + pthread_mutex_destroy(&worker->mutex); + pthread_cond_destroy(&worker->cond); + return E_FAIL; + } + + return S_OK; +} + +HRESULT vkd3d_stop_fence_worker(struct vkd3d_fence_worker *worker) +{ + int rc; + + TRACE("worker %p.\n", worker); + + if ((rc = pthread_mutex_lock(&worker->mutex))) + { + ERR("Failed to lock mutex, error %d.\n", rc); + return E_FAIL; + } + + worker->should_exit = true; + pthread_cond_signal(&worker->cond); + + pthread_mutex_unlock(&worker->mutex); + + if ((rc = pthread_join(worker->thread, NULL))) + { + ERR("Failed to join fence worker thread, error %d.\n", rc); + return E_FAIL; + } + + pthread_mutex_destroy(&worker->mutex); + pthread_cond_destroy(&worker->cond); + + return S_OK; +} + /* ID3D12Fence */ static struct d3d12_fence *impl_from_ID3D12Fence(ID3D12Fence *iface) { diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index f78ae2b4..2bcb98bb 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -496,6 +496,7 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + vkd3d_stop_fence_worker(&device->fence_worker); VK_CALL(vkDestroyDevice(device->vk_device, NULL)); vkd3d_instance_destroy(&device->vkd3d_instance); @@ -1090,6 +1091,14 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, device->signal_event = create_info->signal_event_pfn; + if (FAILED(hr = vkd3d_start_fence_worker(&device->fence_worker))) + { + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VK_CALL(vkDestroyDevice(device->vk_device, NULL)); + vkd3d_instance_destroy(&device->vkd3d_instance); + return hr; + } + return S_OK; } diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 4ecb98b9..5d6ef5fd 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -51,6 +51,17 @@ struct vkd3d_waiting_event HANDLE event; }; +struct vkd3d_fence_worker +{ + pthread_t thread; + pthread_mutex_t mutex; + pthread_cond_t cond; + bool should_exit; +}; + +HRESULT vkd3d_start_fence_worker(struct vkd3d_fence_worker *worker) DECLSPEC_HIDDEN; +HRESULT vkd3d_stop_fence_worker(struct vkd3d_fence_worker *worker) DECLSPEC_HIDDEN; + /* ID3D12Fence */ struct d3d12_fence { @@ -240,6 +251,8 @@ struct d3d12_device struct vkd3d_vk_device_procs vk_procs; vkd3d_signal_event_pfn signal_event; + struct vkd3d_fence_worker fence_worker; + unsigned int direct_queue_family_index; unsigned int copy_queue_family_index; VkPhysicalDeviceMemoryProperties memory_properties;