[PATCH vkd3d 03/12] libs/vkd3d: Allow library user to create internal threads.

Józef Kucia joseph.kucia at gmail.com
Thu Jan 11 10:03:46 CST 2018


From: Józef Kucia <jkucia at codeweavers.com>

We want to create Win32 threads when running under Wine.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 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 f6872c3b6d6f..c4d1a2ade034 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 1d0bde1dd882..1964df15efb1 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 cda3c1ffb8bf..f7d1699e3958 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 bbc87bac259b..51edd3660fb7 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 9e0d6ae0eba4..ed636b562445 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,
-- 
2.13.6




More information about the wine-devel mailing list