Module: Mesa Branch: main Commit: ecd0cf0b27c66b3f9b4dff4b22d25dc6d00ae9ea URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=ecd0cf0b27c66b3f9b4dff4b22d25dc6d00ae9ea
Author: Alyssa Rosenzweig <[email protected]> Date: Wed May 12 17:06:09 2021 -0400 panfrost: Add unowned mode to pan_pool I would like to reuse pan_pool for persistent uploads (shaders and CSOs) in Gallium. In theory u_upload_mgr is more appropriate, but pan_pool is already a knockoff u_upload_mgr, so might as well finish the job. Signed-off-by: Alyssa Rosenzweig <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10866> --- src/gallium/drivers/panfrost/pan_job.c | 4 ++-- src/panfrost/lib/pan_blitter.c | 6 +++--- src/panfrost/lib/pan_indirect_draw.c | 2 +- src/panfrost/lib/pan_pool.c | 37 ++++++++++++++++++++++++++++------ src/panfrost/lib/pan_pool.h | 13 +++++++----- 5 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c index e5daa77704a..13fbaad9c51 100644 --- a/src/gallium/drivers/panfrost/pan_job.c +++ b/src/gallium/drivers/panfrost/pan_job.c @@ -85,12 +85,12 @@ panfrost_batch_init(struct panfrost_context *ctx, /* Preallocate the main pool, since every batch has at least one job * structure so it will be used */ - panfrost_pool_init(&batch->pool, NULL, dev, 0, true); + panfrost_pool_init(&batch->pool, NULL, dev, 0, true, true); /* Don't preallocate the invisible pool, since not every batch will use * the pre-allocation, particularly if the varyings are larger than the * preallocation and a reallocation is needed after anyway. */ - panfrost_pool_init(&batch->invisible_pool, NULL, dev, PAN_BO_INVISIBLE, false); + panfrost_pool_init(&batch->invisible_pool, NULL, dev, PAN_BO_INVISIBLE, false, true); panfrost_batch_add_fbo_bos(batch); } diff --git a/src/panfrost/lib/pan_blitter.c b/src/panfrost/lib/pan_blitter.c index 22b87b6d932..5322d025c14 100644 --- a/src/panfrost/lib/pan_blitter.c +++ b/src/panfrost/lib/pan_blitter.c @@ -1348,7 +1348,7 @@ pan_blit_ctx_init(struct panfrost_device *dev, struct pan_blit_context *ctx) { memset(ctx, 0, sizeof(*ctx)); - panfrost_pool_init(&ctx->pool, NULL, dev, 0, false); + panfrost_pool_init(&ctx->pool, NULL, dev, 0, false, true); ctx->z_scale = (float)(info->dst.end.z - info->dst.start.z + 1) / (info->src.end.z - info->src.start.z + 1); @@ -1599,11 +1599,11 @@ pan_blitter_init(struct panfrost_device *dev) _mesa_hash_table_create(NULL, pan_blit_blend_shader_key_hash, pan_blit_blend_shader_key_equal); panfrost_pool_init(&dev->blitter.shaders.pool, NULL, dev, - PAN_BO_EXECUTE, false); + PAN_BO_EXECUTE, false, true); pthread_mutex_init(&dev->blitter.shaders.lock, NULL); pan_blitter_prefill_blit_shader_cache(dev); - panfrost_pool_init(&dev->blitter.rsds.pool, NULL, dev, 0, false); + panfrost_pool_init(&dev->blitter.rsds.pool, NULL, dev, 0, false, true); dev->blitter.rsds.rsds = _mesa_hash_table_create(NULL, pan_blit_rsd_key_hash, pan_blit_rsd_key_equal); diff --git a/src/panfrost/lib/pan_indirect_draw.c b/src/panfrost/lib/pan_indirect_draw.c index 5e4d26f9d47..2da1925c778 100644 --- a/src/panfrost/lib/pan_indirect_draw.c +++ b/src/panfrost/lib/pan_indirect_draw.c @@ -1371,7 +1371,7 @@ panfrost_init_indirect_draw_shaders(struct panfrost_device *dev) */ pthread_mutex_init(&dev->indirect_draw_shaders.lock, NULL); panfrost_pool_init(&dev->indirect_draw_shaders.bin_pool, NULL, dev, - PAN_BO_EXECUTE, false); + PAN_BO_EXECUTE, false, true); } void diff --git a/src/panfrost/lib/pan_pool.c b/src/panfrost/lib/pan_pool.c index 8a269c396c2..a4124e0ccea 100644 --- a/src/panfrost/lib/pan_pool.c +++ b/src/panfrost/lib/pan_pool.c @@ -27,9 +27,19 @@ #include "pan_device.h" #include "pan_pool.h" -/* Transient command stream pooling: command stream uploads try to simply copy - * into whereever we left off. If there isn't space, we allocate a new entry - * into the pool and copy there */ +/* Knockoff u_upload_mgr. Uploads whereever we left off, allocating new entries + * when needed. + * + * In "owned" mode, a single parent owns the entire pool, and the pool owns all + * created BOs. All BOs are tracked and addable as + * panfrost_pool_get_bo_handles. Freeing occurs at the level of an entire pool. + * This is useful for streaming uploads, where the batch owns the pool. + * + * In "unowned" mode, the pool is freestanding. It does not track created BOs + * or hold references. Instead, the consumer must manage the created BOs. This + * is more flexible, enabling non-transient CSO state or shader code to be + * packed with conservative lifetime handling. + */ static struct panfrost_bo * panfrost_pool_alloc_backing(struct pan_pool *pool, size_t bo_sz) @@ -43,7 +53,11 @@ panfrost_pool_alloc_backing(struct pan_pool *pool, size_t bo_sz) struct panfrost_bo *bo = panfrost_bo_create(pool->dev, bo_sz, pool->create_flags); - util_dynarray_append(&pool->bos, struct panfrost_bo *, bo); + if (pool->owned) + util_dynarray_append(&pool->bos, struct panfrost_bo *, bo); + else + panfrost_bo_unreference(pool->transient_bo); + pool->transient_bo = bo; pool->transient_offset = 0; @@ -53,12 +67,16 @@ panfrost_pool_alloc_backing(struct pan_pool *pool, size_t bo_sz) void panfrost_pool_init(struct pan_pool *pool, void *memctx, struct panfrost_device *dev, - unsigned create_flags, bool prealloc) + unsigned create_flags, bool prealloc, + bool owned) { memset(pool, 0, sizeof(*pool)); pool->dev = dev; pool->create_flags = create_flags; - util_dynarray_init(&pool->bos, memctx); + pool->owned = owned; + + if (owned) + util_dynarray_init(&pool->bos, memctx); if (prealloc) panfrost_pool_alloc_backing(pool, TRANSIENT_SLAB_SIZE); @@ -67,6 +85,11 @@ panfrost_pool_init(struct pan_pool *pool, void *memctx, void panfrost_pool_cleanup(struct pan_pool *pool) { + if (!pool->owned) { + panfrost_bo_unreference(pool->transient_bo); + return; + } + util_dynarray_foreach(&pool->bos, struct panfrost_bo *, bo) panfrost_bo_unreference(*bo); @@ -76,6 +99,8 @@ panfrost_pool_cleanup(struct pan_pool *pool) void panfrost_pool_get_bo_handles(struct pan_pool *pool, uint32_t *handles) { + assert(pool->owned && "pool does not track BOs in unowned mode"); + unsigned idx = 0; util_dynarray_foreach(&pool->bos, struct panfrost_bo *, bo) { assert((*bo)->gem_handle > 0); diff --git a/src/panfrost/lib/pan_pool.h b/src/panfrost/lib/pan_pool.h index a8d1669d844..84eb170118e 100644 --- a/src/panfrost/lib/pan_pool.h +++ b/src/panfrost/lib/pan_pool.h @@ -31,10 +31,8 @@ #include "util/u_dynarray.h" -/* Represents a pool of memory that can only grow, used to allocate objects - * with the same lifetime as the pool itself. In OpenGL, a pool is owned by the - * batch for transient structures. In Vulkan, it may be owned by e.g. the - * command pool */ +/* Represents grow-only memory. It may be owned by the batch (OpenGL) or + * command pool (Vulkan), or may be unowned for persistent uploads. */ struct pan_pool { /* Parent device for allocation */ @@ -51,12 +49,16 @@ struct pan_pool { /* BO flags to use in the pool */ unsigned create_flags; + + /* Mode of the pool. BO management is in the pool for owned mode, but + * the consumed for unowned mode. */ + bool owned; }; void panfrost_pool_init(struct pan_pool *pool, void *memctx, struct panfrost_device *dev, unsigned create_flags, - bool prealloc); + bool prealloc, bool owned); void panfrost_pool_cleanup(struct pan_pool *pool); @@ -64,6 +66,7 @@ panfrost_pool_cleanup(struct pan_pool *pool); static inline unsigned panfrost_pool_num_bos(struct pan_pool *pool) { + assert(pool->owned && "pool does not track BOs in unowned mode"); return util_dynarray_num_elements(&pool->bos, struct panfrost_bo *); } _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
