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++)
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;
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
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);
}
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);
}
#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. */
/* 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;
/* Within the topmost transient BO, how much has been used? */
unsigned transient_offset;
-
};
static inline struct panvk_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);
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,