From 108c9dc65583e7817cabe4a4e0bf49c908d0c5b7 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Mon, 30 Jan 2023 20:11:48 -0600 Subject: [PATCH] nvk: Add a descriptor table data structure This will be used for image and sampler descriptors Part-of: --- src/nouveau/vulkan/meson.build | 2 + src/nouveau/vulkan/nvk_descriptor_table.c | 109 ++++++++++++++++++++++++++++++ src/nouveau/vulkan/nvk_descriptor_table.h | 58 ++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 src/nouveau/vulkan/nvk_descriptor_table.c create mode 100644 src/nouveau/vulkan/nvk_descriptor_table.h diff --git a/src/nouveau/vulkan/meson.build b/src/nouveau/vulkan/meson.build index 971adc5..7c9bc7b 100644 --- a/src/nouveau/vulkan/meson.build +++ b/src/nouveau/vulkan/meson.build @@ -14,6 +14,8 @@ nvk_files = files( 'nvk_descriptor_set.c', 'nvk_descriptor_set_layout.c', 'nvk_descriptor_set_layout.h', + 'nvk_descriptor_table.c', + 'nvk_descriptor_table.h', 'nvk_device.c', 'nvk_device.h', 'nvk_device_memory.c', diff --git a/src/nouveau/vulkan/nvk_descriptor_table.c b/src/nouveau/vulkan/nvk_descriptor_table.c new file mode 100644 index 0000000..21ba49b --- /dev/null +++ b/src/nouveau/vulkan/nvk_descriptor_table.c @@ -0,0 +1,109 @@ +#include "nvk_descriptor_table.h" + +#include "nvk_device.h" +#include "nvk_physical_device.h" + +VkResult +nvk_descriptor_table_init(struct nvk_device *device, + struct nvk_descriptor_table *table, + uint32_t descriptor_size, + uint32_t min_descriptor_count, + uint32_t max_descriptor_count) +{ + struct nvk_physical_device *pdevice = nvk_device_physical(device); + memset(table, 0, sizeof(*table)); + VkResult result; + + simple_mtx_init(&table->mutex, mtx_plain); + + /* TODO: Implement table growing. This requires new uAPI */ + assert(min_descriptor_count == max_descriptor_count); + + table->desc_size = descriptor_size; + table->alloc = min_descriptor_count; + table->next_desc = 0; + table->free_count = 0; + + const uint32_t bo_size = table->alloc * table->desc_size; + table->bo = nouveau_ws_bo_new(pdevice->dev, bo_size, 256, + NOUVEAU_WS_BO_LOCAL | NOUVEAU_WS_BO_MAP); + if (table->bo == NULL) { + result = vk_errorf(device, VK_ERROR_OUT_OF_DEVICE_MEMORY, + "Failed to allocate the image descriptor table"); + goto fail; + } + + table->map = nouveau_ws_bo_map(table->bo, NOUVEAU_WS_BO_WR); + if (table->map == NULL) { + result = vk_errorf(device, VK_ERROR_OUT_OF_DEVICE_MEMORY, + "Failed to map the image descriptor table"); + goto fail; + } + + const size_t free_table_size = table->alloc * sizeof(uint32_t); + table->free_table = vk_alloc(&device->vk.alloc, free_table_size, 4, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (table->free_table == NULL) { + result = vk_errorf(device, VK_ERROR_OUT_OF_HOST_MEMORY, + "Failed to allocate image descriptor free table"); + goto fail; + } + + return VK_SUCCESS; + +fail: + nvk_descriptor_table_finish(device, table); + return result; +} + +void +nvk_descriptor_table_finish(struct nvk_device *device, + struct nvk_descriptor_table *table) +{ + if (table->bo != NULL) + nouveau_ws_bo_destroy(table->bo); + vk_free(&device->vk.alloc, table->free_table); + simple_mtx_destroy(&table->mutex); +} + +#define NVK_IMAGE_DESC_INVALID + +static void * +nvk_descriptor_table_alloc_locked(struct nvk_device *device, + struct nvk_descriptor_table *table, + uint32_t *index_out) +{ + if (table->free_count > 0) { + *index_out = table->free_table[--table->free_count]; + return (char *)table->map + (*index_out * table->desc_size); + } + + if (table->next_desc < table->alloc) { + *index_out = table->next_desc++; + return (char *)table->map + (*index_out * table->desc_size); + } + + return NULL; +} + +void * +nvk_descriptor_table_alloc(struct nvk_device *device, + struct nvk_descriptor_table *table, + uint32_t *index_out) +{ + simple_mtx_lock(&table->mutex); + void *map = nvk_descriptor_table_alloc_locked(device, table, index_out); + simple_mtx_unlock(&table->mutex); + return map; +} + +void +nvk_descriptor_table_free(struct nvk_device *device, + struct nvk_descriptor_table *table, + uint32_t index) +{ + simple_mtx_lock(&table->mutex); + assert(table->free_count < table->alloc); + table->free_table[table->free_count++] = index; + simple_mtx_unlock(&table->mutex); +} diff --git a/src/nouveau/vulkan/nvk_descriptor_table.h b/src/nouveau/vulkan/nvk_descriptor_table.h new file mode 100644 index 0000000..970caef --- /dev/null +++ b/src/nouveau/vulkan/nvk_descriptor_table.h @@ -0,0 +1,58 @@ +#ifndef NVK_DESCRIPTOR_TABLE_H +#define NVK_DESCRIPTOR_TABLE_H 1 + +#include "nvk_private.h" + +#include "nouveau_bo.h" +#include "nouveau_push.h" +#include "util/simple_mtx.h" + +struct nvk_device; + +struct nvk_descriptor_table { + simple_mtx_t mutex; + + uint32_t desc_size; /**< Size of a descriptor */ + uint32_t alloc; /**< Number of descriptors allocated */ + uint32_t next_desc; /**< Next unallocated descriptor */ + uint32_t free_count; /**< Size of free_table */ + + struct nouveau_ws_bo *bo; + void *map; + + /* Stack for free descriptor elements */ + uint32_t *free_table; +}; + +VkResult nvk_descriptor_table_init(struct nvk_device *device, + struct nvk_descriptor_table *table, + uint32_t descriptor_size, + uint32_t min_descriptor_count, + uint32_t max_descriptor_count); + +void nvk_descriptor_table_finish(struct nvk_device *device, + struct nvk_descriptor_table *table); + +void *nvk_descriptor_table_alloc(struct nvk_device *device, + struct nvk_descriptor_table *table, + uint32_t *index_out); + +void nvk_descriptor_table_free(struct nvk_device *device, + struct nvk_descriptor_table *table, + uint32_t index); + +static inline void +nvk_push_descriptor_table_ref(struct nouveau_ws_push *push, + const struct nvk_descriptor_table *table) +{ + if (table->bo) + nouveau_ws_push_ref(push, table->bo, NOUVEAU_WS_BO_RD); +} + +static inline uint64_t +nvk_descriptor_table_base_address(const struct nvk_descriptor_table *table) +{ + return table->bo->offset; +} + +#endif -- 2.7.4