panfrost: Subdivide fixed-size transient slabs
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 12 Jul 2019 20:59:35 +0000 (13:59 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 12 Jul 2019 22:31:48 +0000 (15:31 -0700)
The whole purpose of the transient memory model is to make subdivision
stupidly easy, so let's handle that.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/gallium/drivers/panfrost/pan_allocate.c
src/gallium/drivers/panfrost/pan_job.c
src/gallium/drivers/panfrost/pan_job.h

index a0a96c15b946ab0ff289dd4380bef85b6b735278..a07eba8b8f6a7e6a9639177da21626d3e847291a 100644 (file)
@@ -96,8 +96,21 @@ panfrost_allocate_transient(struct panfrost_context *ctx, size_t sz)
         unsigned offset = 0;
         bool update_offset = false;
 
-        if (sz < TRANSIENT_SLAB_SIZE) {
-                /* First, look for a free slot */
+        bool has_current = batch->transient_indices.size;
+        bool fits_in_current = (batch->transient_offset + sz) < TRANSIENT_SLAB_SIZE;
+
+        if (likely(has_current && fits_in_current)) {
+                /* We can reuse the topmost BO, so get it */
+                unsigned idx = util_dynarray_top(&batch->transient_indices, unsigned);
+                bo = pan_bo_for_index(screen, idx);
+
+                /* Use the specified offset */
+                offset = batch->transient_offset;
+                update_offset = true;
+        } else if (sz < TRANSIENT_SLAB_SIZE) {
+                /* We can't reuse the topmost BO, but we can get a new one.
+                 * First, look for a free slot */
+
                 unsigned count = util_dynarray_num_elements(&screen->transient_bo, void *);
                 unsigned index = 0;
 
@@ -134,9 +147,8 @@ panfrost_allocate_transient(struct panfrost_context *ctx, size_t sz)
                 .gpu = bo->gpu + offset,
         };
 
-        if (update_offset) {
-                /* TODO: Update the offset */
-        }
+        if (update_offset)
+                batch->transient_offset = offset + sz;
 
         return ret;
 
index 0faefe2157a1ddc8f2e8d45d32de979ef6806f49..6339b39d29a01eb7e69881227672fd66161a43a7 100644 (file)
@@ -42,6 +42,7 @@ panfrost_create_job(struct panfrost_context *ctx)
 
         job->minx = job->miny = ~0;
         job->maxx = job->maxy = 0;
+        job->transient_offset = 0;
 
         util_dynarray_init(&job->headers, job);
         util_dynarray_init(&job->gpu_headers, job);
index 9dce1e69415ebebf76622e435c928831f8c1fed9..c6ae2a4eb9f4039ed149d69fb6b64f2baadf4dff 100644 (file)
@@ -109,6 +109,9 @@ struct panfrost_job {
 
         /* Indices of transient BOs referenced */
         struct util_dynarray transient_indices;
+
+        /* Within the topmost transient BO, how much has been used? */
+        unsigned transient_offset;
 };
 
 /* Functions for managing the above */