nvk: Use nvk_cmd_bo for push bufs

This allows us to recycle them.  It also makes implementing secondary
command buffers tractable.

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 4998896ae8
commit 40eedabd4a
3 changed files with 107 additions and 22 deletions
+49 -3
View File
@@ -24,7 +24,8 @@ nvk_destroy_cmd_buffer(struct vk_command_buffer *vk_cmd_buffer)
struct nvk_cmd_pool *pool = nvk_cmd_buffer_pool(cmd);
nvk_cmd_pool_free_bo_list(pool, &cmd->bos);
nouveau_ws_push_destroy(cmd->push);
util_dynarray_fini(&cmd->pushes);
util_dynarray_fini(&cmd->bo_refs);
vk_command_buffer_finish(&cmd->vk);
vk_free(&pool->vk.alloc, cmd);
}
@@ -54,7 +55,8 @@ nvk_create_cmd_buffer(struct vk_command_pool *vk_pool,
&cmd->state.gfx._dynamic_vi;
list_inithead(&cmd->bos);
cmd->push = nouveau_ws_push_new(device->pdev->dev, NVK_CMD_BUF_SIZE);
util_dynarray_init(&cmd->pushes, NULL);
util_dynarray_init(&cmd->bo_refs, NULL);
*cmd_buffer_out = &cmd->vk;
@@ -73,7 +75,13 @@ nvk_reset_cmd_buffer(struct vk_command_buffer *vk_cmd_buffer,
nvk_cmd_pool_free_bo_list(pool, &cmd->bos);
cmd->upload_bo = NULL;
nouveau_ws_push_reset(cmd->push);
cmd->push_bo = NULL;
cmd->push_bo_limit = NULL;
cmd->push = (struct nv_push) {0};
util_dynarray_clear(&cmd->pushes);
util_dynarray_clear(&cmd->bo_refs);
memset(&cmd->state, 0, sizeof(cmd->state));
}
@@ -83,6 +91,41 @@ const struct vk_command_buffer_ops nvk_cmd_buffer_ops = {
.destroy = nvk_destroy_cmd_buffer,
};
/* If we ever fail to allocate a push, we use this */
static uint32_t push_runout[NVK_CMD_BUFFER_MAX_PUSH];
void
nvk_cmd_buffer_new_push(struct nvk_cmd_buffer *cmd)
{
struct nvk_cmd_pool *pool = nvk_cmd_buffer_pool(cmd);
VkResult result;
result = nvk_cmd_pool_alloc_bo(pool, &cmd->push_bo);
if (unlikely(result != VK_SUCCESS)) {
STATIC_ASSERT(NVK_CMD_BUFFER_MAX_PUSH <= NVK_CMD_BO_SIZE / 4);
cmd->push_bo = NULL;
nv_push_init(&cmd->push, push_runout, 0);
cmd->push_bo_limit = &push_runout[NVK_CMD_BUFFER_MAX_PUSH];
} else {
nv_push_init(&cmd->push, cmd->push_bo->map, 0);
cmd->push_bo_limit =
(uint32_t *)((char *)cmd->push_bo->map + NVK_CMD_BO_SIZE);
}
}
static void
nvk_cmd_buffer_flush_push(struct nvk_cmd_buffer *cmd)
{
struct nvk_cmd_push push = {
.bo = cmd->push_bo,
.start_dw = cmd->push.start - (uint32_t *)cmd->push_bo->map,
.dw_count = nv_push_dw_count(&cmd->push),
};
util_dynarray_append(&cmd->pushes, struct nvk_cmd_push, push);
cmd->push.start = cmd->push.end;
}
VkResult
nvk_cmd_buffer_upload_alloc(struct nvk_cmd_buffer *cmd,
uint32_t size, uint32_t alignment,
@@ -155,6 +198,9 @@ VKAPI_ATTR VkResult VKAPI_CALL
nvk_EndCommandBuffer(VkCommandBuffer commandBuffer)
{
VK_FROM_HANDLE(nvk_cmd_buffer, cmd, commandBuffer);
nvk_cmd_buffer_flush_push(cmd);
return vk_command_buffer_get_record_result(&cmd->vk);
}
+53 -7
View File
@@ -3,16 +3,18 @@
#include "nvk_private.h"
#include "nouveau_push.h"
#include "nv_push.h"
#include "nvk_cmd_pool.h"
#include "nvk_descriptor_set.h"
#include "util/u_dynarray.h"
#include "vk_command_buffer.h"
struct nvk_cmd_bo;
struct nvk_cmd_pool;
struct nvk_image_view;
#define NVK_CMD_BUF_SIZE 64*1024
/** Root descriptor table. This gets pushed to the GPU directly */
struct nvk_root_descriptor_table {
union {
@@ -83,6 +85,16 @@ struct nvk_compute_state {
struct nvk_descriptor_state descriptors;
};
struct nvk_cmd_push {
struct nvk_cmd_bo *bo;
uint32_t start_dw;
uint32_t dw_count;
};
struct nvk_cmd_bo_ref {
struct nouveau_ws_bo *bo;
};
struct nvk_cmd_buffer {
struct vk_command_buffer vk;
@@ -91,13 +103,34 @@ struct nvk_cmd_buffer {
struct nvk_compute_state cs;
} state;
/** List of nvk_cmd_bo */
/** List of nvk_cmd_bo
*
* This list exists entirely for ownership tracking. Everything in here
* must also be in pushes or bo_refs if it is to be referenced by this
* command buffer.
*/
struct list_head bos;
struct nvk_cmd_bo *upload_bo;
uint32_t upload_offset;
struct nouveau_ws_push *push;
struct nvk_cmd_bo *push_bo;
uint32_t *push_bo_limit;
struct nv_push push;
/** Array of struct nvk_cmd_push
*
* This acts both as a BO reference as well as provides a range in the
* buffer to use as a pushbuf.
*/
struct util_dynarray pushes;
/** Array of struct nvk_cmd_bo_ref
*
* This is for any internal allocations which we want to reference which
* aren't push buffers.
*/
struct util_dynarray bo_refs;
uint64_t tls_space_needed;
};
@@ -119,17 +152,30 @@ nvk_cmd_buffer_pool(struct nvk_cmd_buffer *cmd)
return (struct nvk_cmd_pool *)cmd->vk.pool;
}
void nvk_cmd_buffer_new_push(struct nvk_cmd_buffer *cmd);
#define NVK_CMD_BUFFER_MAX_PUSH 256
static inline struct nv_push *
nvk_cmd_buffer_push(struct nvk_cmd_buffer *cmd, uint32_t dw_count)
{
return P_SPACE(cmd->push, dw_count);
assert(dw_count <= NVK_CMD_BUFFER_MAX_PUSH);
/* Compare to the actual limit on our push bo */
if (unlikely(cmd->push.end + dw_count > cmd->push_bo_limit))
nvk_cmd_buffer_new_push(cmd);
cmd->push.limit = cmd->push.end + dw_count;
return &cmd->push;
}
static inline void
nvk_cmd_buffer_ref_bo(struct nvk_cmd_buffer *cmd,
struct nouveau_ws_bo *bo)
{
nouveau_ws_push_ref(cmd->push, bo, NOUVEAU_WS_BO_RDWR);
struct nvk_cmd_bo_ref ref = { .bo = bo };
util_dynarray_append(&cmd->bo_refs, struct nvk_cmd_bo_ref, ref);
}
void nvk_cmd_buffer_begin_graphics(struct nvk_cmd_buffer *cmd,
+5 -12
View File
@@ -8,7 +8,6 @@
#include "nvk_physical_device.h"
#include "nouveau_context.h"
#include "nouveau_push.h"
#include <nouveau_drm.h>
#include <xf86drm.h>
@@ -84,16 +83,6 @@ push_add_push(struct push_builder *pb, struct nouveau_ws_bo *bo,
};
}
static void
push_add_ws_push(struct push_builder *pb, struct nouveau_ws_push *push)
{
util_dynarray_foreach(&push->bos, struct nouveau_ws_push_bo, push_bo)
push_add_bo(pb, push_bo->bo, push_bo->flags);
util_dynarray_foreach(&push->pushs, struct nouveau_ws_push_buffer, buf)
push_add_push(pb, buf->bo, 0, nv_push_dw_count(&buf->push));
}
static VkResult
push_submit(struct push_builder *pb, struct nvk_queue *queue)
{
@@ -181,7 +170,11 @@ nvk_queue_submit_drm_nouveau(struct vk_queue *vk_queue,
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);
util_dynarray_foreach(&cmd->pushes, struct nvk_cmd_push, push)
push_add_push(&pb, push->bo->bo, push->start_dw, push->dw_count);
util_dynarray_foreach(&cmd->bo_refs, struct nvk_cmd_bo_ref, ref)
push_add_bo(&pb, ref->bo, NOUVEAU_WS_BO_RDWR);
}
}