nvk: Add a descriptor table data structure

This will be used for image and sampler descriptors

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
Faith Ekstrand 2023-01-30 20:11:48 -06:00 committed by Marge Bot
parent 2ec2ce44f3
commit 108c9dc655
3 changed files with 169 additions and 0 deletions

View file

@ -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',

View file

@ -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);
}

View file

@ -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