From db2e0c7587570d36e34af405c7fcc7471944d2a9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Feb 2021 17:36:19 +0100 Subject: [PATCH] vkd3d: Remove vkd3d_gpu_va_allocator. Signed-off-by: Philip Rebohle --- libs/vkd3d/device.c | 283 ------------------------------------- libs/vkd3d/vkd3d_private.h | 21 --- 2 files changed, 304 deletions(-) diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 08dbf575..42b4768e 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -2020,287 +2020,6 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device, return hr; } -#define VKD3D_VA_FALLBACK_BASE 0x8000000000000000ull -#define VKD3D_VA_SLAB_BASE 0x0000001000000000ull -#define VKD3D_VA_SLAB_SIZE_SHIFT 32 -#define VKD3D_VA_SLAB_SIZE (1ull << VKD3D_VA_SLAB_SIZE_SHIFT) -#define VKD3D_VA_SLAB_COUNT (64 * 1024) - -static D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate_slab(struct vkd3d_gpu_va_allocator *allocator, - size_t aligned_size, void *ptr) -{ - struct vkd3d_gpu_va_slab *slab; - D3D12_GPU_VIRTUAL_ADDRESS address; - unsigned slab_idx; - - slab = allocator->free_slab; - allocator->free_slab = slab->ptr; - slab->size = aligned_size; - slab->ptr = ptr; - - /* It is critical that the multiplication happens in 64-bit to not - * overflow. */ - slab_idx = slab - allocator->slabs; - address = VKD3D_VA_SLAB_BASE + slab_idx * VKD3D_VA_SLAB_SIZE; - - TRACE("Allocated address %#"PRIx64", slab %u, size %zu.\n", address, slab_idx, aligned_size); - - return address; -} - -static D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate_fallback(struct vkd3d_gpu_va_allocator *allocator, - size_t alignment, size_t aligned_size, void *ptr) -{ - struct vkd3d_gpu_va_allocation *allocation; - D3D12_GPU_VIRTUAL_ADDRESS base, ceiling; - - base = allocator->fallback_floor; - ceiling = ~(D3D12_GPU_VIRTUAL_ADDRESS)0; - ceiling -= alignment - 1; - if (aligned_size > ceiling || ceiling - aligned_size < base) - return 0; - - base = (base + (alignment - 1)) & ~((D3D12_GPU_VIRTUAL_ADDRESS)alignment - 1); - - if (!vkd3d_array_reserve((void **)&allocator->fallback_allocations, &allocator->fallback_allocations_size, - allocator->fallback_allocation_count + 1, sizeof(*allocator->fallback_allocations))) - return 0; - - allocation = &allocator->fallback_allocations[allocator->fallback_allocation_count++]; - allocation->base = base; - allocation->size = aligned_size; - allocation->ptr = ptr; - - /* This pointer is bumped and never lowered on a free. However, this will - * only fail once we have exhausted 63 bits of address space. */ - allocator->fallback_floor = base + aligned_size; - - TRACE("Allocated address %#"PRIx64", size %zu.\n", base, aligned_size); - - return base; -} - -D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_allocator *allocator, - size_t alignment, size_t size, void *ptr) -{ - D3D12_GPU_VIRTUAL_ADDRESS address; - int rc; - - if (size > ~(size_t)0 - (alignment - 1)) - return 0; - size = align(size, alignment); - - if ((rc = pthread_mutex_lock(&allocator->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return 0; - } - - if (size <= VKD3D_VA_SLAB_SIZE && allocator->free_slab) - address = vkd3d_gpu_va_allocator_allocate_slab(allocator, size, ptr); - else - address = vkd3d_gpu_va_allocator_allocate_fallback(allocator, alignment, size, ptr); - - pthread_mutex_unlock(&allocator->mutex); - - return address; -} - -static void *vkd3d_gpu_va_allocator_dereference_slab(struct vkd3d_gpu_va_allocator *allocator, - D3D12_GPU_VIRTUAL_ADDRESS address) -{ - const struct vkd3d_gpu_va_slab *slab; - D3D12_GPU_VIRTUAL_ADDRESS base_offset; - unsigned int slab_idx; - - base_offset = address - VKD3D_VA_SLAB_BASE; - slab_idx = base_offset >> VKD3D_VA_SLAB_SIZE_SHIFT; - - if (slab_idx >= VKD3D_VA_SLAB_COUNT) - { - ERR("Invalid slab index %u for address %#"PRIx64".\n", slab_idx, address); - return NULL; - } - - slab = &allocator->slabs[slab_idx]; - base_offset -= slab_idx * VKD3D_VA_SLAB_SIZE; - if (base_offset >= slab->size) - { - ERR("Address %#"PRIx64" is %#"PRIx64" bytes into slab %u of size %zu.\n", - address, base_offset, slab_idx, slab->size); - return NULL; - } - return slab->ptr; -} - -static int vkd3d_gpu_va_allocation_compare(const void *k, const void *e) -{ - const struct vkd3d_gpu_va_allocation *allocation = e; - const D3D12_GPU_VIRTUAL_ADDRESS *address = k; - - if (*address < allocation->base) - return -1; - if (*address - allocation->base >= allocation->size) - return 1; - return 0; -} - -static void *vkd3d_gpu_va_allocator_dereference_fallback(struct vkd3d_gpu_va_allocator *allocator, - D3D12_GPU_VIRTUAL_ADDRESS address) -{ - struct vkd3d_gpu_va_allocation *allocation; - - allocation = bsearch(&address, allocator->fallback_allocations, allocator->fallback_allocation_count, - sizeof(*allocation), vkd3d_gpu_va_allocation_compare); - - return allocation ? allocation->ptr : NULL; -} - -void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocator, - D3D12_GPU_VIRTUAL_ADDRESS address) -{ - void *ret; - int rc; - - /* If we land in the non-fallback region, dereferencing VA is lock-less. - * The base pointer is immutable, and the only way we can have a data race - * is if some other thread is poking into the - * slab_mem_allocation[base_index] block. This can only happen if someone - * is trying to free the entry while we're dereferencing it, which would - * be a serious application bug. */ - if (address < VKD3D_VA_FALLBACK_BASE) - return vkd3d_gpu_va_allocator_dereference_slab(allocator, address); - - /* Slow fallback. */ - if ((rc = pthread_mutex_lock(&allocator->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return NULL; - } - - ret = vkd3d_gpu_va_allocator_dereference_fallback(allocator, address); - - pthread_mutex_unlock(&allocator->mutex); - - return ret; -} - -static void vkd3d_gpu_va_allocator_free_slab(struct vkd3d_gpu_va_allocator *allocator, - D3D12_GPU_VIRTUAL_ADDRESS address) -{ - D3D12_GPU_VIRTUAL_ADDRESS base_offset; - struct vkd3d_gpu_va_slab *slab; - unsigned int slab_idx; - - base_offset = address - VKD3D_VA_SLAB_BASE; - slab_idx = base_offset >> VKD3D_VA_SLAB_SIZE_SHIFT; - - if (slab_idx >= VKD3D_VA_SLAB_COUNT) - { - ERR("Invalid slab index %u for address %#"PRIx64".\n", slab_idx, address); - return; - } - - TRACE("Freeing address %#"PRIx64", slab %u.\n", address, slab_idx); - - slab = &allocator->slabs[slab_idx]; - slab->size = 0; - slab->ptr = allocator->free_slab; - allocator->free_slab = slab; -} - -static void vkd3d_gpu_va_allocator_free_fallback(struct vkd3d_gpu_va_allocator *allocator, - D3D12_GPU_VIRTUAL_ADDRESS address) -{ - struct vkd3d_gpu_va_allocation *allocation; - unsigned int index; - - allocation = bsearch(&address, allocator->fallback_allocations, allocator->fallback_allocation_count, - sizeof(*allocation), vkd3d_gpu_va_allocation_compare); - - if (!allocation || allocation->base != address) - { - ERR("Address %#"PRIx64" does not match any allocation.\n", address); - return; - } - - index = allocation - allocator->fallback_allocations; - --allocator->fallback_allocation_count; - if (index != allocator->fallback_allocation_count) - memmove(&allocator->fallback_allocations[index], &allocator->fallback_allocations[index + 1], - (allocator->fallback_allocation_count - index) * sizeof(*allocation)); -} - -void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address) -{ - int rc; - - if ((rc = pthread_mutex_lock(&allocator->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return; - } - - if (address < VKD3D_VA_FALLBACK_BASE) - { - vkd3d_gpu_va_allocator_free_slab(allocator, address); - pthread_mutex_unlock(&allocator->mutex); - return; - } - - vkd3d_gpu_va_allocator_free_fallback(allocator, address); - - pthread_mutex_unlock(&allocator->mutex); -} - -static bool vkd3d_gpu_va_allocator_init(struct vkd3d_gpu_va_allocator *allocator) -{ - unsigned int i; - int rc; - - memset(allocator, 0, sizeof(*allocator)); - allocator->fallback_floor = VKD3D_VA_FALLBACK_BASE; - - /* To remain lock-less, we cannot grow the slabs array after the fact. If - * we commit to a maximum number of allocations here, we can dereference - * without taking a lock as the base pointer never changes. We would be - * able to grow more seamlessly using an array of pointers, but that would - * make dereferencing slightly less efficient. */ - if (!(allocator->slabs = vkd3d_calloc(VKD3D_VA_SLAB_COUNT, sizeof(*allocator->slabs)))) - return false; - - /* Mark all slabs as free. */ - allocator->free_slab = &allocator->slabs[0]; - for (i = 0; i < VKD3D_VA_SLAB_COUNT - 1; ++i) - { - allocator->slabs[i].ptr = &allocator->slabs[i + 1]; - } - - if ((rc = pthread_mutex_init(&allocator->mutex, NULL))) - { - ERR("Failed to initialize mutex, error %d.\n", rc); - vkd3d_free(allocator->slabs); - return false; - } - - return true; -} - -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->slabs); - vkd3d_free(allocator->fallback_allocations); - pthread_mutex_unlock(&allocator->mutex); - pthread_mutex_destroy(&allocator->mutex); -} - struct d3d12_device_singleton { struct list entry; @@ -2590,7 +2309,6 @@ static void d3d12_device_destroy(struct d3d12_device *device) vkd3d_meta_ops_cleanup(&device->meta_ops, device); vkd3d_bindless_state_cleanup(&device->bindless_state, device); vkd3d_destroy_null_resources(&device->null_resources, device); - vkd3d_gpu_va_allocator_cleanup(&device->gpu_va_allocator); vkd3d_render_pass_cache_cleanup(&device->render_pass_cache, device); vkd3d_fence_worker_stop(&device->fence_worker, device); d3d12_device_destroy_vkd3d_queues(device); @@ -5105,7 +4823,6 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, goto out_cleanup_meta_ops; vkd3d_render_pass_cache_init(&device->render_pass_cache); - vkd3d_gpu_va_allocator_init(&device->gpu_va_allocator); if ((device->parent = create_info->parent)) IUnknown_AddRef(device->parent); diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 1d80a2d4..06f39008 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -323,26 +323,6 @@ struct vkd3d_gpu_va_slab void *ptr; }; -struct vkd3d_gpu_va_allocator -{ - pthread_mutex_t mutex; - - D3D12_GPU_VIRTUAL_ADDRESS fallback_floor; - struct vkd3d_gpu_va_allocation *fallback_allocations; - size_t fallback_allocations_size; - size_t fallback_allocation_count; - - struct vkd3d_gpu_va_slab *slabs; - struct vkd3d_gpu_va_slab *free_slab; -}; - -D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_allocator *allocator, - size_t alignment, size_t size, void *ptr); -void *vkd3d_gpu_va_allocator_dereference(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_render_pass_key { unsigned int attachment_count; @@ -2319,7 +2299,6 @@ struct d3d12_device struct vkd3d_vk_device_procs vk_procs; PFN_vkd3d_signal_event signal_event; - struct vkd3d_gpu_va_allocator gpu_va_allocator; struct vkd3d_fence_worker fence_worker; pthread_mutex_t mutex;