[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