nvk: Use a VMA heap for descriptor memory

Reviewed-by: M Henning <drawoc@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28482>
This commit is contained in:
Faith Ekstrand 2024-03-29 17:34:12 -05:00 committed by Marge Bot
parent 6cbd3a18d4
commit 5c1683c9b9
2 changed files with 53 additions and 20 deletions

View file

@ -363,6 +363,10 @@ nvk_push_descriptor_set_update(struct nvk_push_descriptor_set *push_set,
}
}
static void
nvk_descriptor_pool_free(struct nvk_descriptor_pool *pool,
uint64_t addr, uint64_t size);
static void
nvk_descriptor_set_destroy(struct nvk_device *dev,
struct nvk_descriptor_pool *pool,
@ -377,11 +381,10 @@ nvk_descriptor_set_destroy(struct nvk_device *dev,
break;
}
}
if (pool->entry_count == 0)
pool->current_offset = 0;
}
if (set->size > 0)
nvk_descriptor_pool_free(pool, set->addr, set->size);
vk_descriptor_set_layout_unref(&dev->vk, &set->layout->vk);
vk_object_free(&dev->vk, NULL, set);
@ -396,6 +399,8 @@ nvk_destroy_descriptor_pool(struct nvk_device *dev,
nvk_descriptor_set_destroy(dev, pool, pool->entries[i].set, false);
}
util_vma_heap_finish(&pool->heap);
if (pool->bo) {
nouveau_ws_bo_unmap(pool->bo, pool->mapped_ptr);
nouveau_ws_bo_destroy(pool->bo);
@ -481,16 +486,47 @@ nvk_CreateDescriptorPool(VkDevice _device,
* make that extra space available to the client.
*/
assert(pool->bo->size >= bo_size);
bo_size = pool->bo->size;
util_vma_heap_init(&pool->heap, pool->bo->offset, pool->bo->size);
} else {
util_vma_heap_init(&pool->heap, 0, 0);
}
pool->size = bo_size;
pool->max_entry_count = pCreateInfo->maxSets;
*pDescriptorPool = nvk_descriptor_pool_to_handle(pool);
return VK_SUCCESS;
}
static VkResult
nvk_descriptor_pool_alloc(struct nvk_descriptor_pool *pool,
uint64_t size, uint64_t alignment,
uint64_t *addr_out, void **map_out)
{
assert(size > 0);
uint64_t addr = util_vma_heap_alloc(&pool->heap, size, alignment);
if (addr == 0)
return VK_ERROR_OUT_OF_POOL_MEMORY;
assert(addr >= pool->bo->offset);
assert(addr + size <= pool->bo->offset + pool->bo->size);
uint64_t offset = addr - pool->bo->offset;
*addr_out = addr;
*map_out = pool->mapped_ptr + offset;
return VK_SUCCESS;
}
static void
nvk_descriptor_pool_free(struct nvk_descriptor_pool *pool,
uint64_t addr, uint64_t size)
{
assert(size > 0);
assert(addr >= pool->bo->offset);
assert(addr + size <= pool->bo->offset + pool->bo->size);
util_vma_heap_free(&pool->heap, addr, size);
}
static VkResult
nvk_descriptor_set_create(struct nvk_device *dev,
struct nvk_descriptor_pool *pool,
@ -500,6 +536,7 @@ nvk_descriptor_set_create(struct nvk_device *dev,
{
struct nvk_physical_device *pdev = nvk_device_physical(dev);
struct nvk_descriptor_set *set;
VkResult result;
uint32_t mem_size = sizeof(struct nvk_descriptor_set) +
layout->dynamic_buffer_count * sizeof(struct nvk_buffer_address);
@ -521,21 +558,19 @@ nvk_descriptor_set_create(struct nvk_device *dev,
set->size += stride * variable_count;
}
set->size = align64(set->size, nvk_min_cbuf_alignment(&pdev->info));
uint32_t alignment = nvk_min_cbuf_alignment(&pdev->info);
set->size = align64(set->size, alignment);
if (set->size > 0) {
if (pool->current_offset + set->size > pool->size)
return VK_ERROR_OUT_OF_POOL_MEMORY;
set->mapped_ptr = (uint32_t *)(pool->mapped_ptr + pool->current_offset);
set->addr = pool->bo->offset + pool->current_offset;
result = nvk_descriptor_pool_alloc(pool, set->size, alignment,
&set->addr, &set->mapped_ptr);
if (result != VK_SUCCESS) {
vk_object_free(&dev->vk, NULL, set);
return result;
}
}
assert(pool->current_offset % nvk_min_cbuf_alignment(&pdev->info) == 0);
pool->entries[pool->entry_count].offset = pool->current_offset;
pool->entries[pool->entry_count].size = set->size;
pool->entries[pool->entry_count].set = set;
pool->current_offset += set->size;
pool->entry_count++;
vk_descriptor_set_layout_ref(&layout->vk);
@ -654,7 +689,6 @@ nvk_ResetDescriptorPool(VkDevice device,
nvk_descriptor_set_destroy(dev, pool, pool->entries[i].set, false);
}
pool->entry_count = 0;
pool->current_offset = 0;
return VK_SUCCESS;
}

View file

@ -12,6 +12,8 @@
#include "vk_object.h"
#include "vk_descriptor_update_template.h"
#include "util/vma.h"
struct nvk_descriptor_set_layout;
#define NVK_IMAGE_DESCRIPTOR_IMAGE_INDEX_MASK 0x000fffff
@ -48,8 +50,6 @@ struct nvk_buffer_address {
};
struct nvk_descriptor_pool_entry {
uint32_t offset;
uint32_t size;
struct nvk_descriptor_set *set;
};
@ -57,8 +57,7 @@ struct nvk_descriptor_pool {
struct vk_object_base base;
struct nouveau_ws_bo *bo;
uint8_t *mapped_ptr;
uint64_t current_offset;
uint64_t size;
struct util_vma_heap heap;
uint32_t entry_count;
uint32_t max_entry_count;
struct nvk_descriptor_pool_entry entries[0];