nvk: Allocate upload buffers from the command pool

Instead of the growing BO thing

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
Faith Ekstrand 2023-01-30 20:11:59 -06:00 committed by Marge Bot
parent c1b92bdf71
commit 4998896ae8
3 changed files with 37 additions and 92 deletions

View file

@ -16,45 +16,17 @@
#include "nvk_cl90b5.h"
#include "nvk_cla0c0.h"
static void
nvk_cmd_buffer_upload_init(struct nvk_cmd_buffer_upload *upload)
{
memset(upload, 0, sizeof(*upload));
list_inithead(&upload->list);
}
static void
nvk_cmd_buffer_upload_reset(struct nvk_cmd_buffer_upload *upload)
{
list_for_each_entry_safe(struct nvk_cmd_buffer_upload, child,
&upload->list, list) {
nouveau_ws_bo_unmap(child->upload_bo, child->map);
nouveau_ws_bo_destroy(child->upload_bo);
free(child);
}
list_inithead(&upload->list);
upload->offset = 0;
}
static void
nvk_cmd_buffer_upload_finish(struct nvk_cmd_buffer_upload *upload)
{
nvk_cmd_buffer_upload_reset(upload);
if (upload->upload_bo)
nouveau_ws_bo_destroy(upload->upload_bo);
}
static void
nvk_destroy_cmd_buffer(struct vk_command_buffer *vk_cmd_buffer)
{
struct nvk_cmd_buffer *cmd =
container_of(vk_cmd_buffer, struct nvk_cmd_buffer, vk);
struct nvk_cmd_pool *pool = nvk_cmd_buffer_pool(cmd);
nvk_cmd_buffer_upload_finish(&cmd->upload);
nvk_cmd_pool_free_bo_list(pool, &cmd->bos);
nouveau_ws_push_destroy(cmd->push);
vk_command_buffer_finish(&cmd->vk);
vk_free(&cmd->vk.pool->alloc, cmd);
vk_free(&pool->vk.alloc, cmd);
}
static VkResult
@ -81,8 +53,8 @@ nvk_create_cmd_buffer(struct vk_command_pool *vk_pool,
cmd->vk.dynamic_graphics_state.vi =
&cmd->state.gfx._dynamic_vi;
list_inithead(&cmd->bos);
cmd->push = nouveau_ws_push_new(device->pdev->dev, NVK_CMD_BUF_SIZE);
nvk_cmd_buffer_upload_init(&cmd->upload);
*cmd_buffer_out = &cmd->vk;
@ -95,11 +67,13 @@ nvk_reset_cmd_buffer(struct vk_command_buffer *vk_cmd_buffer,
{
struct nvk_cmd_buffer *cmd =
container_of(vk_cmd_buffer, struct nvk_cmd_buffer, vk);
struct nvk_cmd_pool *pool = nvk_cmd_buffer_pool(cmd);
vk_command_buffer_reset(&cmd->vk);
nvk_cmd_pool_free_bo_list(pool, &cmd->bos);
cmd->upload_bo = NULL;
nouveau_ws_push_reset(cmd->push);
nvk_cmd_buffer_upload_reset(&cmd->upload);
memset(&cmd->state, 0, sizeof(cmd->state));
}
@ -109,69 +83,34 @@ const struct vk_command_buffer_ops nvk_cmd_buffer_ops = {
.destroy = nvk_destroy_cmd_buffer,
};
static bool
nvk_cmd_buffer_resize_upload_buf(struct nvk_cmd_buffer *cmd,
uint64_t min_needed)
{
struct nvk_device *device = nvk_cmd_buffer_device(cmd);
uint64_t new_size;
struct nouveau_ws_bo *bo = NULL;
struct nvk_cmd_buffer_upload *upload;
new_size = MAX2(min_needed, 16 * 1024);
new_size = MAX2(new_size, 2 * cmd->upload.size);
uint32_t flags = NOUVEAU_WS_BO_GART | NOUVEAU_WS_BO_MAP;
bo = nouveau_ws_bo_new(device->pdev->dev, new_size, 0, flags);
nvk_cmd_buffer_ref_bo(cmd, bo);
if (cmd->upload.upload_bo) {
upload = malloc(sizeof(*upload));
if (!upload) {
vk_command_buffer_set_error(&cmd->vk, VK_ERROR_OUT_OF_HOST_MEMORY);
nouveau_ws_bo_destroy(bo);
return false;
}
memcpy(upload, &cmd->upload, sizeof(*upload));
list_add(&upload->list, &cmd->upload.list);
}
cmd->upload.upload_bo = bo;
cmd->upload.size = new_size;
cmd->upload.offset = 0;
cmd->upload.map = nouveau_ws_bo_map(cmd->upload.upload_bo, NOUVEAU_WS_BO_WR);
if (!cmd->upload.map) {
vk_command_buffer_set_error(&cmd->vk, VK_ERROR_OUT_OF_DEVICE_MEMORY);
return false;
}
return true;
}
VkResult
nvk_cmd_buffer_upload_alloc(struct nvk_cmd_buffer *cmd,
uint32_t size, uint32_t alignment,
uint64_t *addr, void **ptr)
{
assert(size % 4 == 0);
assert(size < NVK_CMD_BO_SIZE);
uint32_t offset = cmd->upload.offset;
uint32_t offset = cmd->upload_offset;
if (align > 0)
offset = align(offset, alignment);
if (offset + size > cmd->upload.size) {
if (!nvk_cmd_buffer_resize_upload_buf(cmd, size))
return vk_error(cmd, VK_ERROR_OUT_OF_DEVICE_MEMORY);
assert(offset <= NVK_CMD_BO_SIZE);
if (cmd->upload_bo == NULL || size > NVK_CMD_BO_SIZE - offset) {
struct nvk_cmd_bo *bo;
VkResult result = nvk_cmd_pool_alloc_bo(nvk_cmd_buffer_pool(cmd), &bo);
if (unlikely(result != VK_SUCCESS))
return result;
nvk_cmd_buffer_ref_bo(cmd, bo->bo);
cmd->upload_bo = bo;
offset = 0;
}
*addr = cmd->upload.upload_bo->offset + offset;
*ptr = cmd->upload.map + offset;
*addr = cmd->upload_bo->bo->offset + offset;
*ptr = (char *)cmd->upload_bo->map + offset;
cmd->upload.offset = offset + size;
cmd->upload_offset = offset + size;
return VK_SUCCESS;
}

View file

@ -8,6 +8,7 @@
#include "vk_command_buffer.h"
struct nvk_cmd_pool;
struct nvk_image_view;
#define NVK_CMD_BUF_SIZE 64*1024
@ -82,14 +83,6 @@ struct nvk_compute_state {
struct nvk_descriptor_state descriptors;
};
struct nvk_cmd_buffer_upload {
uint8_t *map;
unsigned offset;
uint64_t size;
struct nouveau_ws_bo *upload_bo;
struct list_head list;
};
struct nvk_cmd_buffer {
struct vk_command_buffer vk;
@ -98,9 +91,13 @@ struct nvk_cmd_buffer {
struct nvk_compute_state cs;
} state;
struct nouveau_ws_push *push;
/** List of nvk_cmd_bo */
struct list_head bos;
struct nvk_cmd_buffer_upload upload;
struct nvk_cmd_bo *upload_bo;
uint32_t upload_offset;
struct nouveau_ws_push *push;
uint64_t tls_space_needed;
};
@ -116,6 +113,11 @@ nvk_cmd_buffer_device(struct nvk_cmd_buffer *cmd)
return (struct nvk_device *)cmd->vk.base.device;
}
static inline struct nvk_cmd_pool *
nvk_cmd_buffer_pool(struct nvk_cmd_buffer *cmd)
{
return (struct nvk_cmd_pool *)cmd->vk.pool;
}
static inline struct nv_push *
nvk_cmd_buffer_push(struct nvk_cmd_buffer *cmd, uint32_t dw_count)

View file

@ -2,6 +2,7 @@
#include "nvk_bo_sync.h"
#include "nvk_cmd_buffer.h"
#include "nvk_cmd_pool.h"
#include "nvk_device.h"
#include "nvk_device_memory.h"
#include "nvk_physical_device.h"
@ -177,6 +178,9 @@ nvk_queue_submit_drm_nouveau(struct vk_queue *vk_queue,
struct nvk_cmd_buffer *cmd =
container_of(submit->command_buffers[i], struct nvk_cmd_buffer, vk);
list_for_each_entry_safe(struct nvk_cmd_bo, bo, &cmd->bos, link)
push_add_bo(&pb, bo->bo, NOUVEAU_WS_BO_RD);
push_add_ws_push(&pb, cmd->push);
}
}