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

Reply via email to