From af35fc44a7052d69e72f7457f2f459720fe35ff8 Mon Sep 17 00:00:00 2001 From: Marc Alcala Prieto Date: Fri, 17 Apr 2026 15:28:51 +0200 Subject: [PATCH] pan/desc: Implement pan_emit_fbd for v14+ Also, modify pan_emit_fbd's signature to take a pointer to pan_fbd_descs. Reviewed-by: Lars-Ivar Hesselberg Simonsen Reviewed-by: Boris Brezillon Part-of: --- src/gallium/drivers/panfrost/pan_csf.c | 58 +++++++++++--- src/gallium/drivers/panfrost/pan_jm.c | 19 ++++- src/panfrost/lib/pan_desc.c | 100 ++++++++++++++++--------- src/panfrost/lib/pan_desc.h | 12 ++- 4 files changed, 141 insertions(+), 48 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_csf.c b/src/gallium/drivers/panfrost/pan_csf.c index 2246804b85c..d5a768b94fc 100644 --- a/src/gallium/drivers/panfrost/pan_csf.c +++ b/src/gallium/drivers/panfrost/pan_csf.c @@ -754,11 +754,30 @@ GENX(csf_preload_fb)(struct panfrost_batch *batch, struct pan_fb_info *fb) (&dev->fb_preload_cache, &batch->pool.base, fb, batch->tls.gpu, NULL); } -#define GET_FBD(_ctx, _pass) \ - (_ctx)->fbds[PAN_INCREMENTAL_RENDERING_##_pass##_PASS] -#define EMIT_FBD(_ctx, _pass, _fb, _tls, _tiler_ctx) \ - GET_FBD(_ctx, _pass).gpu |= \ - GENX(pan_emit_fbd)(_fb, 0, _tls, _tiler_ctx, GET_FBD(_ctx, _pass).cpu) +static inline void +emit_ir_fbd(struct pan_csf_tiler_oom_ctx *ctx, enum pan_rendering_pass pass, + const struct pan_fb_info *fb, const struct pan_tls_info *tls, + const struct pan_tiler_context *tiler_ctx, uint32_t fb_sz) +{ + void *desc_addr = ctx->fbds[pass].cpu; + struct pan_fbd_descs ir_descs = {0}; + +#if PAN_ARCH <= 13 + ir_descs.fbd = desc_addr; + desc_addr += fb_sz; +#endif + + const int crc_rt = GENX(pan_select_crc_rt)(fb, fb->tile_size); + const bool has_zs_ext = (fb->zs.view.zs || fb->zs.view.s || crc_rt >= 0); + if (has_zs_ext) { + ir_descs.zs_crc = desc_addr; + desc_addr += pan_size(ZS_CRC_EXTENSION); + } + + ir_descs.rts = desc_addr; + + ctx->fbds[pass].gpu |= GENX(pan_emit_fbd)(fb, 0, tls, tiler_ctx, &ir_descs); +} void GENX(csf_emit_fbds)(struct panfrost_batch *batch, struct pan_fb_info *fb, @@ -769,9 +788,25 @@ GENX(csf_emit_fbds)(struct panfrost_batch *batch, struct pan_fb_info *fb, struct panfrost_device *dev = pan_device(batch->ctx->base.screen); /* Default framebuffer descriptor */ + const int crc_rt = GENX(pan_select_crc_rt)(fb, fb->tile_size); + const bool has_zs_ext = (fb->zs.view.zs || fb->zs.view.s || crc_rt >= 0); +#if PAN_ARCH >= 14 + const unsigned fb_sz = ALIGN_POT(sizeof(struct pan_fb_state), 64); +#else + const unsigned fb_sz = pan_size(FRAMEBUFFER); +#endif + const struct pan_fbd_descs fb_descs = { +#if PAN_ARCH <= 13 + .fbd = batch->framebuffer.cpu, +#endif + .zs_crc = has_zs_ext ? batch->framebuffer.cpu + fb_sz : NULL, + .rts = has_zs_ext + ? batch->framebuffer.cpu + fb_sz + pan_size(ZS_CRC_EXTENSION) + : batch->framebuffer.cpu + fb_sz, + }; batch->framebuffer.gpu |= - GENX(pan_emit_fbd)(fb, 0, tls, &batch->tiler_ctx, batch->framebuffer.cpu); + GENX(pan_emit_fbd)(fb, 0, tls, &batch->tiler_ctx, &fb_descs); if (batch->draw_count == 0) return; @@ -788,7 +823,8 @@ GENX(csf_emit_fbds)(struct panfrost_batch *batch, struct pan_fb_info *fb, alt_fb.zs.discard.z = false; alt_fb.zs.discard.s = false; - EMIT_FBD(tiler_oom_ctx, FIRST, &alt_fb, tls, &batch->tiler_ctx); + emit_ir_fbd(tiler_oom_ctx, PAN_INCREMENTAL_RENDERING_FIRST_PASS, &alt_fb, + tls, &batch->tiler_ctx, fb_sz); /* Subsequent incremental rendering passes: preload old content and don't * discard result */ @@ -825,7 +861,8 @@ GENX(csf_emit_fbds)(struct panfrost_batch *batch, struct pan_fb_info *fb, (&dev->fb_preload_cache, &batch->pool.base, &alt_fb, batch->tls.gpu, NULL); } - EMIT_FBD(tiler_oom_ctx, MIDDLE, &alt_fb, tls, &batch->tiler_ctx); + emit_ir_fbd(tiler_oom_ctx, PAN_INCREMENTAL_RENDERING_MIDDLE_PASS, &alt_fb, + tls, &batch->tiler_ctx, fb_sz); /* Last incremental rendering pass: preload previous content and deal with * results as specified by user */ @@ -835,7 +872,8 @@ GENX(csf_emit_fbds)(struct panfrost_batch *batch, struct pan_fb_info *fb, alt_fb.zs.discard.z = fb->zs.discard.z; alt_fb.zs.discard.s = fb->zs.discard.s; - EMIT_FBD(tiler_oom_ctx, LAST, &alt_fb, tls, &batch->tiler_ctx); + emit_ir_fbd(tiler_oom_ctx, PAN_INCREMENTAL_RENDERING_LAST_PASS, &alt_fb, tls, + &batch->tiler_ctx, fb_sz); } void @@ -872,7 +910,7 @@ GENX(csf_emit_fragment_job)(struct panfrost_batch *batch, cs_wait_slot(b, 0); cs_if(b, MALI_CS_CONDITION_GREATER, counter) { cs_move64_to(b, cs_sr_reg64(b, FRAGMENT, FBD_POINTER), - GET_FBD(oom_ctx, LAST).gpu); + oom_ctx->fbds[PAN_INCREMENTAL_RENDERING_LAST_PASS].gpu); } } diff --git a/src/gallium/drivers/panfrost/pan_jm.c b/src/gallium/drivers/panfrost/pan_jm.c index 845c238853e..6863cf4e001 100644 --- a/src/gallium/drivers/panfrost/pan_jm.c +++ b/src/gallium/drivers/panfrost/pan_jm.c @@ -257,8 +257,23 @@ GENX(jm_emit_fbds)(struct panfrost_batch *batch, struct pan_fb_info *fb, { PAN_TRACE_FUNC(PAN_TRACE_GL_JM); - batch->framebuffer.gpu |= GENX(pan_emit_fbd)( - fb, 0, tls, &batch->tiler_ctx, batch->framebuffer.cpu); +#if PAN_ARCH >= 5 + const int crc_rt = GENX(pan_select_crc_rt)(fb, fb->tile_size); + const bool has_zs_ext = (fb->zs.view.zs || fb->zs.view.s || crc_rt >= 0); +#endif + + const struct pan_fbd_descs fb_descs = { + .fbd = batch->framebuffer.cpu, +#if PAN_ARCH >= 5 + .zs_crc = + has_zs_ext ? batch->framebuffer.cpu + pan_size(FRAMEBUFFER) : NULL, + .rts = has_zs_ext ? batch->framebuffer.cpu + pan_size(FRAMEBUFFER) + + pan_size(ZS_CRC_EXTENSION) + : batch->framebuffer.cpu + pan_size(FRAMEBUFFER), +#endif + }; + batch->framebuffer.gpu |= + GENX(pan_emit_fbd)(fb, 0, tls, &batch->tiler_ctx, &fb_descs); } void diff --git a/src/panfrost/lib/pan_desc.c b/src/panfrost/lib/pan_desc.c index 3df01de0090..9bd9fd182cf 100644 --- a/src/panfrost/lib/pan_desc.c +++ b/src/panfrost/lib/pan_desc.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2021 Collabora, Ltd. + * Copyright (C) 2026 Arm Ltd. * SPDX-License-Identifier: MIT */ @@ -1172,27 +1173,72 @@ check_fb_attachments(const struct pan_fb_info *fb) #endif } +static void +pan_emit_rts(const struct pan_fb_info *fb, unsigned layer_idx, int crc_rt, + struct mali_render_target_packed *rts, + struct pan_clean_tile clean_tile) +{ + const unsigned rt_count = MAX2(fb->rt_count, 1); + unsigned cbuf_offset = 0; + + for (unsigned i = 0; i < rt_count; i++) { + pan_emit_rt(fb, layer_idx, i, cbuf_offset, rts, clean_tile); + rts++; + if (!fb->rts[i].view) + continue; + + cbuf_offset += pan_bytes_per_pixel_tib(fb->rts[i].view->format) * + fb->tile_size * + pan_image_view_get_nr_samples(fb->rts[i].view); + + if (i != crc_rt && fb->rts[i].crc_valid != NULL) + *(fb->rts[i].crc_valid) = false; + } +} + +#if PAN_ARCH >= 14 unsigned GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx, const struct pan_tls_info *tls, - const struct pan_tiler_context *tiler_ctx, void *out) + const struct pan_tiler_context *tiler_ctx, + const struct pan_fbd_descs *out) { PAN_TRACE_FUNC(PAN_TRACE_LIB_DESC); check_fb_attachments(fb); - void *fbd = out; - void *rtd = out + pan_size(FRAMEBUFFER); + const int crc_rt = GENX(pan_select_crc_rt)(fb, fb->tile_size); + const bool has_zs_crc_ext = (fb->zs.view.zs || fb->zs.view.s || crc_rt >= 0); + const struct pan_clean_tile clean_tile = pan_get_clean_tile_info(fb); + + if (has_zs_crc_ext) { + pan_emit_zs_crc_ext(fb, layer_idx, crc_rt, out->zs_crc, clean_tile); + } + + pan_emit_rts(fb, layer_idx, crc_rt, out->rts, clean_tile); + + return 0; +} +#else +unsigned +GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx, + const struct pan_tls_info *tls, + const struct pan_tiler_context *tiler_ctx, + const struct pan_fbd_descs *out) +{ + PAN_TRACE_FUNC(PAN_TRACE_LIB_DESC); + + check_fb_attachments(fb); #if PAN_ARCH <= 5 - GENX(pan_emit_tls)(tls, pan_section_ptr(fbd, FRAMEBUFFER, LOCAL_STORAGE)); + GENX(pan_emit_tls)(tls, pan_section_ptr(out->fbd, FRAMEBUFFER, LOCAL_STORAGE)); #endif int crc_rt = GENX(pan_select_crc_rt)(fb, fb->tile_size); bool has_zs_crc_ext = (fb->zs.view.zs || fb->zs.view.s || crc_rt >= 0); struct pan_clean_tile clean_tile = pan_get_clean_tile_info(fb); - pan_section_pack(fbd, FRAMEBUFFER, PARAMETERS, cfg) { + pan_section_pack(out->fbd, FRAMEBUFFER, PARAMETERS, cfg) { #if PAN_ARCH >= 6 cfg.sample_locations = fb->sample_positions; cfg.pre_frame_0 = pan_fix_frame_shader_mode(fb->bifrost.pre_post.modes[0], @@ -1309,40 +1355,22 @@ GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx, } #if PAN_ARCH >= 6 - pan_section_pack(fbd, FRAMEBUFFER, PADDING, padding) + pan_section_pack(out->fbd, FRAMEBUFFER, PADDING, padding) ; #else pan_emit_midgard_tiler(fb, tiler_ctx, - pan_section_ptr(fbd, FRAMEBUFFER, TILER)); + pan_section_ptr(out->fbd, FRAMEBUFFER, TILER)); /* All weights set to 0, nothing to do here */ - pan_section_pack(fbd, FRAMEBUFFER, TILER_WEIGHTS, w) + pan_section_pack(out->fbd, FRAMEBUFFER, TILER_WEIGHTS, w) ; #endif if (has_zs_crc_ext) { - struct mali_zs_crc_extension_packed *zs_crc_ext = - out + pan_size(FRAMEBUFFER); - - pan_emit_zs_crc_ext(fb, layer_idx, crc_rt, zs_crc_ext, clean_tile); - rtd += pan_size(ZS_CRC_EXTENSION); + pan_emit_zs_crc_ext(fb, layer_idx, crc_rt, out->zs_crc, clean_tile); } - unsigned rt_count = MAX2(fb->rt_count, 1); - unsigned cbuf_offset = 0; - for (unsigned i = 0; i < rt_count; i++) { - pan_emit_rt(fb, layer_idx, i, cbuf_offset, rtd, clean_tile); - rtd += pan_size(RENDER_TARGET); - if (!fb->rts[i].view) - continue; - - cbuf_offset += pan_bytes_per_pixel_tib(fb->rts[i].view->format) * - fb->tile_size * - pan_image_view_get_nr_samples(fb->rts[i].view); - - if (i != crc_rt && fb->rts[i].crc_valid != NULL) - *(fb->rts[i].crc_valid) = false; - } + pan_emit_rts(fb, layer_idx, crc_rt, out->rts, clean_tile); struct mali_framebuffer_pointer_packed tag; pan_pack(&tag, FRAMEBUFFER_POINTER, cfg) { @@ -1351,6 +1379,7 @@ GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx, } return tag.opaque[0]; } +#endif /* PAN_ARCH >= 14 */ #else /* PAN_ARCH == 4 */ static enum mali_color_format pan_sfbd_raw_format(unsigned bits) @@ -1378,14 +1407,15 @@ GENX(pan_select_tile_size)(struct pan_fb_info *fb) unsigned GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx, const struct pan_tls_info *tls, - const struct pan_tiler_context *tiler_ctx, void *fbd) + const struct pan_tiler_context *tiler_ctx, + const struct pan_fbd_descs *out) { PAN_TRACE_FUNC(PAN_TRACE_LIB_DESC); assert(fb->rt_count <= 1); - GENX(pan_emit_tls)(tls, pan_section_ptr(fbd, FRAMEBUFFER, LOCAL_STORAGE)); - pan_section_pack(fbd, FRAMEBUFFER, PARAMETERS, cfg) { + GENX(pan_emit_tls)(tls, pan_section_ptr(out->fbd, FRAMEBUFFER, LOCAL_STORAGE)); + pan_section_pack(out->fbd, FRAMEBUFFER, PARAMETERS, cfg) { cfg.bound_max_x = fb->width - 1; cfg.bound_max_y = fb->height - 1; cfg.dithering_enable = true; @@ -1499,15 +1529,15 @@ GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx, } pan_emit_midgard_tiler(fb, tiler_ctx, - pan_section_ptr(fbd, FRAMEBUFFER, TILER)); + pan_section_ptr(out->fbd, FRAMEBUFFER, TILER)); /* All weights set to 0, nothing to do here */ - pan_section_pack(fbd, FRAMEBUFFER, TILER_WEIGHTS, w) + pan_section_pack(out->fbd, FRAMEBUFFER, TILER_WEIGHTS, w) ; - pan_section_pack(fbd, FRAMEBUFFER, PADDING_1, padding) + pan_section_pack(out->fbd, FRAMEBUFFER, PADDING_1, padding) ; - pan_section_pack(fbd, FRAMEBUFFER, PADDING_2, padding) + pan_section_pack(out->fbd, FRAMEBUFFER, PADDING_2, padding) ; return 0; } diff --git a/src/panfrost/lib/pan_desc.h b/src/panfrost/lib/pan_desc.h index db5b6588ad3..c54f2693d9e 100644 --- a/src/panfrost/lib/pan_desc.h +++ b/src/panfrost/lib/pan_desc.h @@ -338,10 +338,20 @@ void GENX(pan_emit_afrc_color_attachment)(const struct pan_attachment_info *att, void *payload); #endif +struct pan_fbd_descs { +#if PAN_ARCH <= 13 + struct mali_framebuffer_packed *fbd; +#endif +#if PAN_ARCH >= 5 + struct mali_zs_crc_extension_packed *zs_crc; + struct mali_render_target_packed *rts; +#endif +}; + unsigned GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx, const struct pan_tls_info *tls, const struct pan_tiler_context *tiler_ctx, - void *out); + const struct pan_fbd_descs *out); #if PAN_ARCH >= 6 unsigned GENX(pan_select_tiler_hierarchy_mask)(uint32_t width, uint32_t height,