From d629debaca8955aecf7b4c8d62edb6f8de273ab3 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 2 Jul 2021 11:30:48 +0200 Subject: [PATCH] panvk: Support returning BOs allocated by panvk_pool to a 'free BO' pool So all CommandBuffers in a given CommandPool can reuse BOs for their memory pools. Signed-off-by: Boris Brezillon Reviewed-by: Tomeu Vizoso Part-of: --- src/panfrost/vulkan/panvk_cmd_buffer.c | 20 ++++++++++++-------- src/panfrost/vulkan/panvk_mempool.c | 30 ++++++++++++++++++++++++++---- src/panfrost/vulkan/panvk_mempool.h | 29 ++++++++++++++++++++++++++--- src/panfrost/vulkan/panvk_meta.c | 8 ++++---- 4 files changed, 68 insertions(+), 19 deletions(-) diff --git a/src/panfrost/vulkan/panvk_cmd_buffer.c b/src/panfrost/vulkan/panvk_cmd_buffer.c index b738054..baf8500 100644 --- a/src/panfrost/vulkan/panvk_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_cmd_buffer.c @@ -57,12 +57,14 @@ panvk_reset_cmdbuf(struct panvk_cmd_buffer *cmdbuf) panvk_pool_cleanup(&cmdbuf->tls_pool); panvk_pool_cleanup(&cmdbuf->varying_pool); panvk_pool_init(&cmdbuf->desc_pool, &device->physical_device->pdev, - 0, 64 * 1024, "Command buffer descriptor pool", - true); + NULL, 0, 64 * 1024, + "Command buffer descriptor pool", true); panvk_pool_init(&cmdbuf->tls_pool, &device->physical_device->pdev, - PAN_BO_INVISIBLE, 64 * 1024, "TLS pool", false); + NULL, PAN_BO_INVISIBLE, 64 * 1024, + "TLS pool", false); panvk_pool_init(&cmdbuf->varying_pool, &device->physical_device->pdev, - PAN_BO_INVISIBLE, 64 * 1024, "Varyings pool", false); + NULL, PAN_BO_INVISIBLE, 64 * 1024, + "Varyings pool", false); cmdbuf->status = PANVK_CMD_BUFFER_STATUS_INITIAL; for (unsigned i = 0; i < MAX_BIND_POINTS; i++) @@ -88,12 +90,14 @@ panvk_create_cmdbuf(struct panvk_device *device, cmdbuf->level = level; cmdbuf->pool = pool; panvk_pool_init(&cmdbuf->desc_pool, &device->physical_device->pdev, - 0, 64 * 1024, "Command buffer descriptor pool", - true); + NULL, 0, 64 * 1024, + "Command buffer descriptor pool", true); panvk_pool_init(&cmdbuf->tls_pool, &device->physical_device->pdev, - PAN_BO_INVISIBLE, 64 * 1024, "TLS pool", false); + NULL, PAN_BO_INVISIBLE, 64 * 1024, + "TLS pool", false); panvk_pool_init(&cmdbuf->varying_pool, &device->physical_device->pdev, - PAN_BO_INVISIBLE, 64 * 1024, "Varyings pool", false); + NULL, PAN_BO_INVISIBLE, 64 * 1024, + "Varyings pool", false); list_inithead(&cmdbuf->batches); cmdbuf->status = PANVK_CMD_BUFFER_STATUS_INITIAL; *cmdbuf_out = cmdbuf; diff --git a/src/panfrost/vulkan/panvk_mempool.c b/src/panfrost/vulkan/panvk_mempool.c index f5513ff..0121c14 100644 --- a/src/panfrost/vulkan/panvk_mempool.c +++ b/src/panfrost/vulkan/panvk_mempool.c @@ -43,6 +43,11 @@ static struct panfrost_bo * panvk_pool_alloc_backing(struct panvk_pool *pool, size_t bo_sz) { + /* If there's a free BO in our BO pool, let's pick it. */ + if (pool->bo_pool && + util_dynarray_num_elements(&pool->bo_pool->free_bos, struct panfrost_bo *)) + return util_dynarray_pop(&pool->bo_pool->free_bos, struct panfrost_bo *); + /* We don't know what the BO will be used for, so let's flag it * RW and attach it to both the fragment and vertex/tiler jobs. * TODO: if we want fine grained BO assignment we should pass @@ -89,12 +94,14 @@ panvk_pool_alloc_aligned(struct panvk_pool *pool, size_t sz, unsigned alignment) PAN_POOL_ALLOCATOR(struct panvk_pool, panvk_pool_alloc_aligned) void -panvk_pool_init(struct panvk_pool *pool, struct panfrost_device *dev, +panvk_pool_init(struct panvk_pool *pool, + struct panfrost_device *dev, struct panvk_bo_pool *bo_pool, unsigned create_flags, size_t slab_size, const char *label, bool prealloc) { memset(pool, 0, sizeof(*pool)); pan_pool_init(&pool->base, dev, create_flags, slab_size, label); + pool->bo_pool = bo_pool; util_dynarray_init(&pool->bos, NULL); @@ -103,11 +110,26 @@ panvk_pool_init(struct panvk_pool *pool, struct panfrost_device *dev, } void -panvk_pool_cleanup(struct panvk_pool *pool) +panvk_pool_reset(struct panvk_pool *pool) { - util_dynarray_foreach(&pool->bos, struct panfrost_bo *, bo) - panfrost_bo_unreference(*bo); + if (pool->bo_pool) { + unsigned num_bos = panvk_pool_num_bos(pool); + void *ptr = util_dynarray_grow(&pool->bo_pool->free_bos, + struct panfrost_bo *, num_bos); + memcpy(ptr, util_dynarray_begin(&pool->bos), + num_bos * sizeof(struct panfrost_bo *)); + } else { + util_dynarray_foreach(&pool->bos, struct panfrost_bo *, bo) + panfrost_bo_unreference(*bo); + } + + util_dynarray_clear(&pool->bos); +} +void +panvk_pool_cleanup(struct panvk_pool *pool) +{ + panvk_pool_reset(pool); util_dynarray_fini(&pool->bos); } diff --git a/src/panfrost/vulkan/panvk_mempool.h b/src/panfrost/vulkan/panvk_mempool.h index 3794072..b56c240 100644 --- a/src/panfrost/vulkan/panvk_mempool.h +++ b/src/panfrost/vulkan/panvk_mempool.h @@ -27,6 +27,22 @@ #include "pan_pool.h" +struct panvk_bo_pool { + struct util_dynarray free_bos; +}; + +static inline void panvk_bo_pool_init(struct panvk_bo_pool *bo_pool) +{ + util_dynarray_init(&bo_pool->free_bos, NULL); +} + +static inline void panvk_bo_pool_cleanup(struct panvk_bo_pool *bo_pool) +{ + util_dynarray_foreach(&bo_pool->free_bos, struct panfrost_bo *, bo) + panfrost_bo_unreference(*bo); + util_dynarray_fini(&bo_pool->free_bos); +} + /* Represents grow-only memory. It may be owned by the batch (OpenGL), or may be unowned for persistent uploads. */ @@ -34,6 +50,11 @@ struct panvk_pool { /* Inherit from pan_pool */ struct pan_pool base; + /* Before allocating a new BO, check if the BO pool has free BOs. + * When returning BOs, if bo_pool != NULL, return them to this bo_pool. + */ + struct panvk_bo_pool *bo_pool; + /* BOs allocated by this pool */ struct util_dynarray bos; @@ -42,7 +63,6 @@ struct panvk_pool { /* Within the topmost transient BO, how much has been used? */ unsigned transient_offset; - }; static inline struct panvk_pool * @@ -53,8 +73,11 @@ to_panvk_pool(struct pan_pool *pool) void panvk_pool_init(struct panvk_pool *pool, struct panfrost_device *dev, - unsigned create_flags, size_t slab_size, const char *label, - bool prealloc); + struct panvk_bo_pool *bo_pool, unsigned create_flags, + size_t slab_size, const char *label, bool prealloc); + +void +panvk_pool_reset(struct panvk_pool *pool); void panvk_pool_cleanup(struct panvk_pool *pool); diff --git a/src/panfrost/vulkan/panvk_meta.c b/src/panfrost/vulkan/panvk_meta.c index 6e6b8ee..7c123d1 100644 --- a/src/panfrost/vulkan/panvk_meta.c +++ b/src/panfrost/vulkan/panvk_meta.c @@ -154,14 +154,14 @@ panvk_CmdClearAttachments(VkCommandBuffer commandBuffer, void panvk_meta_init(struct panvk_physical_device *dev) { - panvk_pool_init(&dev->meta.bin_pool, &dev->pdev, PAN_BO_EXECUTE, + panvk_pool_init(&dev->meta.bin_pool, &dev->pdev, NULL, PAN_BO_EXECUTE, 16 * 1024, "panvk_meta binary pool", false); - panvk_pool_init(&dev->meta.desc_pool, &dev->pdev, 0, + panvk_pool_init(&dev->meta.desc_pool, &dev->pdev, NULL, 0, 16 * 1024, "panvk_meta descriptor pool", false); - panvk_pool_init(&dev->meta.blitter.bin_pool, &dev->pdev, + panvk_pool_init(&dev->meta.blitter.bin_pool, &dev->pdev, NULL, PAN_BO_EXECUTE, 16 * 1024, "panvk_meta blitter binary pool", false); - panvk_pool_init(&dev->meta.blitter.desc_pool, &dev->pdev, + panvk_pool_init(&dev->meta.blitter.desc_pool, &dev->pdev, NULL, 0, 16 * 1024, "panvk_meta blitter descriptor pool", false); pan_blitter_init(&dev->pdev, &dev->meta.blitter.bin_pool.base, -- 2.7.4