libs/vkd3d: Make GPU VA allocator thread-safe.

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-15 13:49:05 +01:00 committed by Alexandre Julliard
parent db2e1d402e
commit d18e986b27
2 changed files with 59 additions and 11 deletions

View File

@ -920,19 +920,31 @@ static void d3d12_device_init_pipeline_cache(struct d3d12_device *device)
} }
} }
/* FIXME: Allocator should be thread-safe. */
D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_allocator *allocator,
size_t size, void *ptr) size_t size, void *ptr)
{ {
D3D12_GPU_VIRTUAL_ADDRESS ceiling = ~(D3D12_GPU_VIRTUAL_ADDRESS)0; D3D12_GPU_VIRTUAL_ADDRESS ceiling = ~(D3D12_GPU_VIRTUAL_ADDRESS)0;
struct vkd3d_gpu_va_allocation *allocation; struct vkd3d_gpu_va_allocation *allocation;
int rc;
if ((rc = pthread_mutex_lock(&allocator->mutex)))
{
ERR("Failed to lock mutex, error %d.\n", rc);
return 0;
}
if (!vkd3d_array_reserve((void **)&allocator->allocations, &allocator->allocations_size, if (!vkd3d_array_reserve((void **)&allocator->allocations, &allocator->allocations_size,
allocator->allocation_count + 1, sizeof(*allocator->allocations))) allocator->allocation_count + 1, sizeof(*allocator->allocations)))
{
pthread_mutex_unlock(&allocator->mutex);
return 0; return 0;
}
if (size > ceiling || ceiling - size < allocator->floor) if (size > ceiling || ceiling - size < allocator->floor)
{
pthread_mutex_unlock(&allocator->mutex);
return 0; return 0;
}
allocation = &allocator->allocations[allocator->allocation_count++]; allocation = &allocator->allocations[allocator->allocation_count++];
allocation->base = allocator->floor; allocation->base = allocator->floor;
@ -941,6 +953,8 @@ D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_al
allocator->floor += size; allocator->floor += size;
pthread_mutex_unlock(&allocator->mutex);
return allocation->base; return allocation->base;
} }
@ -959,35 +973,69 @@ static int vkd3d_gpu_va_allocation_compare(const void *k, const void *e)
void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address) void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address)
{ {
struct vkd3d_gpu_va_allocation *allocation; struct vkd3d_gpu_va_allocation *allocation;
int rc;
if (!(allocation = bsearch(&address, allocator->allocations, allocator->allocation_count, if ((rc = pthread_mutex_lock(&allocator->mutex)))
sizeof(*allocation), vkd3d_gpu_va_allocation_compare))) {
ERR("Failed to lock mutex, error %d.\n", rc);
return NULL; return NULL;
}
return allocation->ptr; allocation = bsearch(&address, allocator->allocations, allocator->allocation_count,
sizeof(*allocation), vkd3d_gpu_va_allocation_compare);
pthread_mutex_unlock(&allocator->mutex);
return allocation ? allocation->ptr : NULL;
} }
void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address) void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address)
{ {
struct vkd3d_gpu_va_allocation *allocation; struct vkd3d_gpu_va_allocation *allocation;
int rc;
if (!(allocation = bsearch(&address, allocator->allocations, allocator->allocation_count, if ((rc = pthread_mutex_lock(&allocator->mutex)))
sizeof(*allocation), vkd3d_gpu_va_allocation_compare))) {
ERR("Failed to lock mutex, error %d.\n", rc);
return; return;
}
if (allocation->base == address) allocation = bsearch(&address, allocator->allocations, allocator->allocation_count,
sizeof(*allocation), vkd3d_gpu_va_allocation_compare);
if (allocation && allocation->base == address)
allocation->ptr = NULL; allocation->ptr = NULL;
pthread_mutex_unlock(&allocator->mutex);
} }
void vkd3d_gpu_va_allocator_init(struct vkd3d_gpu_va_allocator *allocator) static bool vkd3d_gpu_va_allocator_init(struct vkd3d_gpu_va_allocator *allocator)
{ {
int rc;
memset(allocator, 0, sizeof(*allocator)); memset(allocator, 0, sizeof(*allocator));
allocator->floor = 0x1000; allocator->floor = 0x1000;
if ((rc = pthread_mutex_init(&allocator->mutex, NULL)))
{
ERR("Failed to initialize mutex, error %d.\n", rc);
return false;
}
return true;
} }
void vkd3d_gpu_va_allocator_cleanup(struct vkd3d_gpu_va_allocator *allocator) static void vkd3d_gpu_va_allocator_cleanup(struct vkd3d_gpu_va_allocator *allocator)
{ {
int rc;
if ((rc = pthread_mutex_lock(&allocator->mutex)))
{
ERR("Failed to lock mutex, error %d.\n", rc);
return;
}
vkd3d_free(allocator->allocations); vkd3d_free(allocator->allocations);
pthread_mutex_unlock(&allocator->mutex);
pthread_mutex_destroy(&allocator->mutex);
} }
/* ID3D12Device */ /* ID3D12Device */

View File

@ -122,6 +122,8 @@ HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker,
struct vkd3d_gpu_va_allocator struct vkd3d_gpu_va_allocator
{ {
pthread_mutex_t mutex;
D3D12_GPU_VIRTUAL_ADDRESS floor; D3D12_GPU_VIRTUAL_ADDRESS floor;
struct vkd3d_gpu_va_allocation struct vkd3d_gpu_va_allocation
@ -136,12 +138,10 @@ struct vkd3d_gpu_va_allocator
D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_allocator *allocator,
size_t size, void *ptr) DECLSPEC_HIDDEN; size_t size, void *ptr) DECLSPEC_HIDDEN;
void vkd3d_gpu_va_allocator_cleanup(struct vkd3d_gpu_va_allocator *allocator) DECLSPEC_HIDDEN;
void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocator, void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocator,
D3D12_GPU_VIRTUAL_ADDRESS address) DECLSPEC_HIDDEN; D3D12_GPU_VIRTUAL_ADDRESS address) DECLSPEC_HIDDEN;
void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator, void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator,
D3D12_GPU_VIRTUAL_ADDRESS address) DECLSPEC_HIDDEN; D3D12_GPU_VIRTUAL_ADDRESS address) DECLSPEC_HIDDEN;
void vkd3d_gpu_va_allocator_init(struct vkd3d_gpu_va_allocator *allocator) DECLSPEC_HIDDEN;
/* ID3D12Fence */ /* ID3D12Fence */
struct d3d12_fence struct d3d12_fence