Module: Mesa
Branch: main
Commit: 3cd283354991852d0e9b37226fd5d0682550cabe
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=3cd283354991852d0e9b37226fd5d0682550cabe

Author: Alyssa Rosenzweig <[email protected]>
Date:   Mon Feb 21 19:29:16 2022 -0500

asahi: Generate IOGPU attachments dynamically

Take a pipe_framebuffer_state and go from there. We need some care to
handle separate stencil, but the logic is largely routine.

Signed-off-by: Alyssa Rosenzweig <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15482>

---

 src/gallium/drivers/asahi/agx_pipe.c |   5 +-
 src/gallium/drivers/asahi/magic.c    | 121 ++++++++++++++++++++++++++++++-----
 src/gallium/drivers/asahi/magic.h    |   3 +-
 3 files changed, 108 insertions(+), 21 deletions(-)

diff --git a/src/gallium/drivers/asahi/agx_pipe.c 
b/src/gallium/drivers/asahi/agx_pipe.c
index 3c2bec2412f..b750265cdf1 100644
--- a/src/gallium/drivers/asahi/agx_pipe.c
+++ b/src/gallium/drivers/asahi/agx_pipe.c
@@ -524,16 +524,13 @@ agx_flush(struct pipe_context *pctx,
    unsigned cmdbuf_size = demo_cmdbuf(dev->cmdbuf.ptr.cpu,
                dev->cmdbuf.size,
                &ctx->batch->pool,
+               &ctx->framebuffer,
                ctx->batch->encoder->ptr.gpu,
                encoder_id,
                ctx->batch->scissor.bo->ptr.gpu,
-               ctx->batch->width,
-               ctx->batch->height,
-               util_format_get_blocksize(rt0->base.format),
                pipeline_null.gpu,
                pipeline_clear,
                pipeline_store,
-               rt0->bo->ptr.gpu,
                clear_pipeline_textures);
 
    /* Generate the mapping table from the BO list */
diff --git a/src/gallium/drivers/asahi/magic.c 
b/src/gallium/drivers/asahi/magic.c
index dde2504932f..1961a71e124 100644
--- a/src/gallium/drivers/asahi/magic.c
+++ b/src/gallium/drivers/asahi/magic.c
@@ -50,17 +50,113 @@ demo_zero(struct agx_pool *pool, unsigned count)
    return ptr.gpu;
 }
 
+static size_t
+asahi_size_resource(struct pipe_resource *prsrc, unsigned level)
+{
+   struct agx_resource *rsrc = agx_resource(prsrc);
+   size_t size = rsrc->slices[level].size;
+
+   if (rsrc->separate_stencil)
+      size += asahi_size_resource(&rsrc->separate_stencil->base, level);
+
+   return size;
+}
+
+static size_t
+asahi_size_surface(struct pipe_surface *surf)
+{
+   return asahi_size_resource(surf->texture, surf->u.tex.level);
+}
+
+static size_t
+asahi_size_attachments(struct pipe_framebuffer_state *framebuffer)
+{
+   size_t sum = 0;
+
+   for (unsigned i = 0; i < framebuffer->nr_cbufs; ++i)
+      sum += asahi_size_surface(framebuffer->cbufs[i]);
+
+   if (framebuffer->zsbuf)
+      sum += asahi_size_surface(framebuffer->zsbuf);
+
+   return sum;
+}
+
+static enum agx_iogpu_attachment_type
+asahi_classify_attachment(enum pipe_format format)
+{
+   const struct util_format_description *desc = 
util_format_description(format);
+
+   if (util_format_has_depth(desc))
+      return AGX_IOGPU_ATTACHMENT_TYPE_DEPTH;
+   else if (util_format_has_stencil(desc))
+      return AGX_IOGPU_ATTACHMENT_TYPE_STENCIL;
+   else
+      return AGX_IOGPU_ATTACHMENT_TYPE_COLOUR;
+}
+
+static void
+asahi_pack_iogpu_attachment(void *out, struct agx_resource *rsrc,
+                            struct pipe_surface *surf,
+                            unsigned total_size)
+{
+   /* We don't support layered rendering yet */
+   assert(surf->u.tex.first_layer == surf->u.tex.last_layer);
+
+   agx_pack(out, IOGPU_ATTACHMENT, cfg) {
+      cfg.type = asahi_classify_attachment(rsrc->base.format);
+
+      cfg.address = agx_map_texture_gpu(rsrc, surf->u.tex.level,
+                                              surf->u.tex.first_layer);
+
+      cfg.size = rsrc->slices[surf->u.tex.level].size;
+
+      cfg.percent = (100 * cfg.size) / total_size;
+   }
+}
+
+static unsigned
+asahi_pack_iogpu_attachments(void *out, struct pipe_framebuffer_state 
*framebuffer)
+{
+   unsigned total_attachment_size = asahi_size_attachments(framebuffer);
+   struct agx_iogpu_attachment_packed *attachments = out;
+   unsigned nr = 0;
+
+   for (unsigned i = 0; i < framebuffer->nr_cbufs; ++i) {
+      asahi_pack_iogpu_attachment(attachments + (nr++),
+                                  agx_resource(framebuffer->cbufs[i]->texture),
+                                  framebuffer->cbufs[i],
+                                  total_attachment_size);
+   }
+
+   if (framebuffer->zsbuf) {
+         struct agx_resource *rsrc = agx_resource(framebuffer->zsbuf->texture);
+
+         asahi_pack_iogpu_attachment(attachments + (nr++),
+                                     rsrc, framebuffer->zsbuf,
+                                     total_attachment_size);
+
+         if (rsrc->separate_stencil) {
+            asahi_pack_iogpu_attachment(attachments + (nr++),
+                                        rsrc->separate_stencil,
+                                        framebuffer->zsbuf,
+                                        total_attachment_size);
+         }
+   }
+
+   return nr;
+}
+
 unsigned
 demo_cmdbuf(uint64_t *buf, size_t size,
             struct agx_pool *pool,
+            struct pipe_framebuffer_state *framebuffer,
             uint64_t encoder_ptr,
             uint64_t encoder_id,
             uint64_t scissor_ptr,
-            unsigned width, unsigned height, unsigned bpp,
             uint32_t pipeline_null,
             uint32_t pipeline_clear,
             uint32_t pipeline_store,
-            uint64_t rt0,
             bool clear_pipeline_textures)
 {
    uint32_t *map = (uint32_t *) buf;
@@ -89,8 +185,8 @@ demo_cmdbuf(uint64_t *buf, size_t size,
    }
 
    agx_pack(map + 220, IOGPU_AUX_FRAMEBUFFER, cfg) {
-      cfg.width = width;
-      cfg.height = height;
+      cfg.width = framebuffer->width;
+      cfg.height = framebuffer->height;
       cfg.z16_unorm_attachment = false;
       cfg.pointer = unk_buffer_2;
    }
@@ -113,23 +209,18 @@ demo_cmdbuf(uint64_t *buf, size_t size,
    agx_pack(map + 344, IOGPU_MISC, cfg) {
       cfg.encoder_id = encoder_id;
       cfg.unknown_buffer = demo_unk6(pool);
-      cfg.width = width;
-      cfg.height = height;
+      cfg.width = framebuffer->width;
+      cfg.height = framebuffer->height;
    }
 
    unsigned offset_unk = (458 * 4);
    unsigned offset_attachments = (470 * 4);
-   unsigned nr_attachments = 1;
 
-   map[473] = nr_attachments;
+   unsigned nr_attachments =
+      asahi_pack_iogpu_attachments(map + (offset_attachments / 4) + 4,
+                                   framebuffer);
 
-   /* A single attachment follows, depth/stencil have their own attachments */
-   agx_pack((map + (offset_attachments / 4) + 4), IOGPU_ATTACHMENT, cfg) {
-      cfg.address = rt0;
-      cfg.type = AGX_IOGPU_ATTACHMENT_TYPE_COLOUR;
-      cfg.size = width * height * 4;
-      cfg.percent = 100;
-   }
+   map[(offset_attachments / 4) + 3] = nr_attachments;
 
    unsigned total_size = offset_attachments + (AGX_IOGPU_ATTACHMENT_LENGTH * 
nr_attachments) + 16;
 
diff --git a/src/gallium/drivers/asahi/magic.h 
b/src/gallium/drivers/asahi/magic.h
index aa3aad6a666..506784b8e1b 100644
--- a/src/gallium/drivers/asahi/magic.h
+++ b/src/gallium/drivers/asahi/magic.h
@@ -27,14 +27,13 @@
 unsigned
 demo_cmdbuf(uint64_t *buf, size_t size,
             struct agx_pool *pool,
+            struct pipe_framebuffer_state *framebuffer,
             uint64_t encoder_ptr,
             uint64_t encoder_id,
             uint64_t scissor_ptr,
-            unsigned width, unsigned height, unsigned bpp,
             uint32_t pipeline_null,
             uint32_t pipeline_clear,
             uint32_t pipeline_store,
-            uint64_t rt0,
             bool clear_pipeline_textures);
 
 void

Reply via email to