From e16b1f37a7d4496d0680a1d43154cc39b1dae7a9 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Mon, 30 Jan 2023 20:12:00 -0600 Subject: [PATCH] nvk: Handle large command buffer uploads better Change our assertion from a < to a <=. Also, if the size of the upload is greater than the amount of space we have left in the old BO, don't set cmd->upload_bo to point to the new thing. Instead, let the next upload carry on with the old buffer since it has more room. Part-of: --- src/nouveau/vulkan/nvk_cmd_buffer.c | 38 ++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/nouveau/vulkan/nvk_cmd_buffer.c b/src/nouveau/vulkan/nvk_cmd_buffer.c index 7191a62990a..a88d2837458 100644 --- a/src/nouveau/vulkan/nvk_cmd_buffer.c +++ b/src/nouveau/vulkan/nvk_cmd_buffer.c @@ -130,28 +130,42 @@ nvk_cmd_buffer_upload_alloc(struct nvk_cmd_buffer *cmd, uint64_t *addr, void **ptr) { assert(size % 4 == 0); - assert(size < NVK_CMD_BO_SIZE); + assert(size <= NVK_CMD_BO_SIZE); uint32_t offset = cmd->upload_offset; if (align > 0) offset = align(offset, alignment); 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; + if (cmd->upload_bo != NULL && size <= NVK_CMD_BO_SIZE - offset) { + *addr = cmd->upload_bo->bo->offset + offset; + *ptr = (char *)cmd->upload_bo->map + offset; - nvk_cmd_buffer_ref_bo(cmd, bo->bo); - cmd->upload_bo = bo; - offset = 0; + cmd->upload_offset = offset + size; + + return VK_SUCCESS; } - *addr = cmd->upload_bo->bo->offset + offset; - *ptr = (char *)cmd->upload_bo->map + 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; - cmd->upload_offset = offset + size; + nvk_cmd_buffer_ref_bo(cmd, bo->bo); + + *addr = bo->bo->offset; + *ptr = bo->map; + + /* Pick whichever of the current upload BO and the new BO will have more + * room left to be the BO for the next upload. If our upload size is + * bigger than the old offset, we're better off burning the whole new + * upload BO on this one allocation and continuing on the current upload + * BO. + */ + if (size < cmd->upload_offset) { + cmd->upload_bo = bo; + cmd->upload_offset = size; + } return VK_SUCCESS; }