Module: vkd3d Branch: master Commit: 604056daf4cad525ce3a1166a0598f4a9b788ebc URL: https://source.winehq.org/git/vkd3d.git/?a=commit;h=604056daf4cad525ce3a1166...
Author: Józef Kucia jkucia@codeweavers.com Date: Thu Jan 11 17:03:46 2018 +0100
libs/vkd3d: Allow library user to create internal threads.
We want to create Win32 threads when running under Wine.
Signed-off-by: Józef Kucia jkucia@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
include/vkd3d.h | 7 +++++++ libs/vkd3d-utils/vkd3d_utils_main.c | 2 ++ libs/vkd3d/command.c | 35 ++++++++++++++++++++++++++++++----- libs/vkd3d/device.c | 10 +++++++++- libs/vkd3d/vkd3d_private.h | 12 ++++++++++-- 5 files changed, 58 insertions(+), 8 deletions(-)
diff --git a/include/vkd3d.h b/include/vkd3d.h index f6872c3..c4d1a2a 100644 --- a/include/vkd3d.h +++ b/include/vkd3d.h @@ -33,10 +33,17 @@ extern "C" {
typedef bool (*vkd3d_signal_event_pfn)(HANDLE event);
+typedef void * (*vkd3d_thread_pfn)(void *data); + +typedef void * (*vkd3d_create_thread_pfn)(vkd3d_thread_pfn thread_main, void *data); +typedef bool (*vkd3d_join_thread_pfn)(void *thread); + struct vkd3d_device_create_info { D3D_FEATURE_LEVEL minimum_feature_level; vkd3d_signal_event_pfn signal_event_pfn; + vkd3d_create_thread_pfn create_thread_pfn; + vkd3d_join_thread_pfn join_thread_pfn; size_t wchar_size; };
diff --git a/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d-utils/vkd3d_utils_main.c index 1d0bde1..1964df1 100644 --- a/libs/vkd3d-utils/vkd3d_utils_main.c +++ b/libs/vkd3d-utils/vkd3d_utils_main.c @@ -38,6 +38,8 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter,
create_info.minimum_feature_level = minimum_feature_level; create_info.signal_event_pfn = vkd3d_signal_event; + create_info.create_thread_pfn = NULL; + create_info.join_thread_pfn = NULL; create_info.wchar_size = sizeof(WCHAR);
return vkd3d_create_device(&create_info, riid, device); diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index cda3c1f..f7d1699 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -204,7 +204,20 @@ HRESULT vkd3d_fence_worker_start(struct vkd3d_fence_worker *worker, return E_FAIL; }
- if ((rc = pthread_create(&worker->thread, NULL, vkd3d_fence_worker_main, worker))) + if (device->create_thread) + { + if (!(worker->u.handle = device->create_thread(vkd3d_fence_worker_main, worker))) + { + ERR("Failed to create fence worker thread.\n"); + pthread_mutex_destroy(&worker->mutex); + pthread_cond_destroy(&worker->cond); + return E_FAIL; + } + + return S_OK; + } + + if ((rc = pthread_create(&worker->u.thread, NULL, vkd3d_fence_worker_main, worker))) { ERR("Failed to create fence worker thread, error %d.\n", rc); pthread_mutex_destroy(&worker->mutex); @@ -215,7 +228,8 @@ HRESULT vkd3d_fence_worker_start(struct vkd3d_fence_worker *worker, return S_OK; }
-HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker) +HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker, + struct d3d12_device *device) { int rc;
@@ -232,10 +246,21 @@ HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker)
pthread_mutex_unlock(&worker->mutex);
- if ((rc = pthread_join(worker->thread, NULL))) + if (device->join_thread) { - ERR("Failed to join fence worker thread, error %d.\n", rc); - return E_FAIL; + if (!device->join_thread(worker->u.handle)) + { + ERR("Failed to join fence worker thread.\n"); + return E_FAIL; + } + } + else + { + if ((rc = pthread_join(worker->u.thread, NULL))) + { + ERR("Failed to join fence worker thread, error %d.\n", rc); + return E_FAIL; + } }
pthread_mutex_destroy(&worker->mutex); diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index bbc87ba..51edd36 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -919,7 +919,7 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface) const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
vkd3d_gpu_va_allocator_cleanup(&device->gpu_va_allocator); - vkd3d_fence_worker_stop(&device->fence_worker); + vkd3d_fence_worker_stop(&device->fence_worker, device); VK_CALL(vkDestroySampler(device->vk_device, device->vk_default_sampler, NULL)); if (device->vk_pipeline_cache) VK_CALL(vkDestroyPipelineCache(device->vk_device, device->vk_pipeline_cache, NULL)); @@ -1813,6 +1813,12 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, { HRESULT hr;
+ if (!create_info->create_thread_pfn != !create_info->join_thread_pfn) + { + ERR("Invalid create/join thread function pointers.\n"); + return E_INVALIDARG; + } + device->ID3D12Device_iface.lpVtbl = &d3d12_device_vtbl; device->refcount = 1;
@@ -1828,6 +1834,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, }
device->signal_event = create_info->signal_event_pfn; + device->create_thread = create_info->create_thread_pfn; + device->join_thread = create_info->join_thread_pfn; device->wchar_size = create_info->wchar_size;
if (FAILED(hr = d3d12_device_create_default_sampler(device))) diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 9e0d6ae..ed636b5 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -73,7 +73,11 @@ struct vkd3d_instance
struct vkd3d_fence_worker { - pthread_t thread; + union + { + pthread_t thread; + void *handle; + } u; pthread_mutex_t mutex; pthread_cond_t cond; bool should_exit; @@ -93,7 +97,8 @@ struct vkd3d_fence_worker
HRESULT vkd3d_fence_worker_start(struct vkd3d_fence_worker *worker, struct d3d12_device *device) DECLSPEC_HIDDEN; -HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker) DECLSPEC_HIDDEN; +HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker, + struct d3d12_device *device) DECLSPEC_HIDDEN;
struct vkd3d_gpu_va_allocator { @@ -628,6 +633,9 @@ struct d3d12_device struct vkd3d_vulkan_info vk_info;
struct vkd3d_instance vkd3d_instance; + + vkd3d_create_thread_pfn create_thread; + vkd3d_join_thread_pfn join_thread; };
HRESULT d3d12_device_create(const struct vkd3d_device_create_info *create_info,