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
