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 <lars-ivar.simonsen@arm.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41081>
This commit is contained in:
Marc Alcala Prieto 2026-04-17 15:28:51 +02:00 committed by Marge Bot
parent 9421888623
commit af35fc44a7
4 changed files with 141 additions and 48 deletions

View file

@ -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);
}
}

View file

@ -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

View file

@ -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;
}

View file

@ -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,