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>
This commit is contained in:
Józef Kucia 2018-01-11 17:03:46 +01:00 committed by Alexandre Julliard
parent 38f2d893b1
commit 604056daf4
5 changed files with 58 additions and 8 deletions

View File

@ -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;
};

View File

@ -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);

View File

@ -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);

View File

@ -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)))

View File

@ -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,