mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07:00
libs/vkd3d: Create fence worker thread per device.
This commit is contained in:
@@ -23,6 +23,100 @@
|
|||||||
|
|
||||||
#include "vkd3d_private.h"
|
#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 */
|
/* ID3D12Fence */
|
||||||
static struct d3d12_fence *impl_from_ID3D12Fence(ID3D12Fence *iface)
|
static struct d3d12_fence *impl_from_ID3D12Fence(ID3D12Fence *iface)
|
||||||
{
|
{
|
||||||
|
@@ -496,6 +496,7 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface)
|
|||||||
{
|
{
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
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));
|
VK_CALL(vkDestroyDevice(device->vk_device, NULL));
|
||||||
vkd3d_instance_destroy(&device->vkd3d_instance);
|
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;
|
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;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -51,6 +51,17 @@ struct vkd3d_waiting_event
|
|||||||
HANDLE 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 */
|
/* ID3D12Fence */
|
||||||
struct d3d12_fence
|
struct d3d12_fence
|
||||||
{
|
{
|
||||||
@@ -240,6 +251,8 @@ struct d3d12_device
|
|||||||
struct vkd3d_vk_device_procs vk_procs;
|
struct vkd3d_vk_device_procs vk_procs;
|
||||||
vkd3d_signal_event_pfn signal_event;
|
vkd3d_signal_event_pfn signal_event;
|
||||||
|
|
||||||
|
struct vkd3d_fence_worker fence_worker;
|
||||||
|
|
||||||
unsigned int direct_queue_family_index;
|
unsigned int direct_queue_family_index;
|
||||||
unsigned int copy_queue_family_index;
|
unsigned int copy_queue_family_index;
|
||||||
VkPhysicalDeviceMemoryProperties memory_properties;
|
VkPhysicalDeviceMemoryProperties memory_properties;
|
||||||
|
Reference in New Issue
Block a user