nvk: add command stream upload buffer.

This is an upload buffer that is kept beside the command buffer.

It can be used to allocate any per command buffer gpu state that
doesn't fit in the cmd stream.

compute dispatches will go in here for now.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
Dave Airlie 2022-06-06 13:53:17 +10:00 committed by Marge Bot
parent c8805f4544
commit 0870cd8719
2 changed files with 82 additions and 0 deletions

View file

@ -59,6 +59,75 @@ nvk_reset_cmd_buffer(struct nvk_cmd_buffer *cmd_buffer)
return cmd_buffer->record_result;
}
static bool
nvk_cmd_buffer_resize_upload_buf(struct nvk_cmd_buffer *cmd_buffer, uint64_t min_needed)
{
uint64_t new_size;
struct nouveau_ws_bo *bo = NULL;
struct nvk_cmd_buffer_upload *upload;
struct nvk_device *device = (struct nvk_device *)cmd_buffer->vk.base.device;
new_size = MAX2(min_needed, 16 * 1024);
new_size = MAX2(new_size, 2 * cmd_buffer->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);
nouveau_ws_push_ref(cmd_buffer->push, bo, NOUVEAU_WS_BO_RD);
if (cmd_buffer->upload.upload_bo) {
upload = malloc(sizeof(*upload));
if (!upload) {
cmd_buffer->record_result = VK_ERROR_OUT_OF_HOST_MEMORY;
nouveau_ws_bo_destroy(bo);
return false;
}
memcpy(upload, &cmd_buffer->upload, sizeof(*upload));
list_add(&upload->list, &cmd_buffer->upload.list);
}
cmd_buffer->upload.upload_bo = bo;
cmd_buffer->upload.size = new_size;
cmd_buffer->upload.offset = 0;
cmd_buffer->upload.map = nouveau_ws_bo_map(cmd_buffer->upload.upload_bo, NOUVEAU_WS_BO_WR);
if (!cmd_buffer->upload.map) {
cmd_buffer->record_result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
return false;
}
return true;
}
bool
nvk_cmd_buffer_upload_alloc(struct nvk_cmd_buffer *cmd_buffer, unsigned size,
uint64_t *addr, void **ptr)
{
assert(size % 4 == 0);
/* Align to the scalar cache line size if it results in this allocation
* being placed in less of them.
*/
unsigned offset = cmd_buffer->upload.offset;
unsigned line_size = 256;//for compute dispatches
unsigned gap = align(offset, line_size) - offset;
if ((size & ~(line_size - 1)) > gap)
offset = align(offset, line_size);
if (offset + size > cmd_buffer->upload.size) {
if (!nvk_cmd_buffer_resize_upload_buf(cmd_buffer, size))
return false;
offset = 0;
}
*addr = cmd_buffer->upload.upload_bo->offset + offset;
*ptr = cmd_buffer->upload.map + offset;
cmd_buffer->upload.offset = offset + size;
return true;
}
VKAPI_ATTR VkResult VKAPI_CALL
nvk_CreateCommandPool(VkDevice _device,
const VkCommandPoolCreateInfo *pCreateInfo,

View file

@ -40,6 +40,14 @@ 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;
@ -54,6 +62,8 @@ struct nvk_cmd_buffer {
bool reset_on_submit;
VkResult record_result;
struct nvk_cmd_buffer_upload upload;
uint64_t tls_space_needed;
};
@ -74,4 +84,7 @@ nvk_get_descriptors_state(struct nvk_cmd_buffer *cmd,
}
};
bool
nvk_cmd_buffer_upload_alloc(struct nvk_cmd_buffer *cmd_buffer, unsigned size,
uint64_t *addr, void **ptr);
#endif