pan/crc: Store CRC state in a struct

Add the pan_crc_state structure and use it to store CRC state. The
struct only has a valid boolean for now but will be extended
later. This removes some explicit dereferencing, allows to wrap
state handling inside functions and helps readability.

Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
This commit is contained in:
Loïc Molinari 2026-02-11 09:13:15 +01:00
parent 9960843c13
commit c566aaed2e
5 changed files with 26 additions and 16 deletions

View file

@ -531,7 +531,7 @@ panfrost_batch_to_fb_info(const struct panfrost_batch *batch,
rts[i].nr_samples =
surf->nr_samples ?: MAX2(surf->texture->nr_samples, 1);
memcpy(rts[i].swizzle, id_swz, sizeof(rts[i].swizzle));
fb->rts[i].crc_valid = &prsrc->valid.crc;
fb->rts[i].crc_state = &prsrc->crc_state;
fb->rts[i].view = &rts[i];
/* Preload if the RT is read or updated */

View file

@ -2206,7 +2206,7 @@ pan_resource_afbcp_commit(struct panfrost_context *ctx,
prsrc->plane.layout.data_size_B = prsrc->afbcp->size;
prsrc->plane.base = prsrc->afbcp->packed_bo->ptr.gpu;
prsrc->image.props.crc = false;
prsrc->valid.crc = false;
pan_crc_state_invalidate(&prsrc->crc_state);
for (unsigned level = 0; level <= prsrc->base.last_level; ++level)
prsrc->plane.layout.slices[level] =
@ -2305,7 +2305,7 @@ panfrost_ptr_unmap(struct pipe_context *pctx, struct pipe_transfer *transfer)
struct panfrost_device *dev = pan_device(pctx->screen);
if (transfer->usage & PIPE_MAP_WRITE)
prsrc->valid.crc = false;
pan_crc_state_invalidate(&prsrc->crc_state);
/* AFBC/AFRC will use a staging resource. `initialized` will be set when
* the fragment job is created; this is deferred to prevent useless surface

View file

@ -76,10 +76,6 @@ struct panfrost_resource {
struct panfrost_bo *bo;
struct {
/* Is the checksum for this image valid? Implicitly refers to
* the first slice; we only checksum non-mipmapped 2D images */
bool crc;
/* Has anything been written to this slice? */
BITSET_DECLARE(data, PAN_MAX_MIP_LEVELS);
} valid;
@ -102,6 +98,9 @@ struct panfrost_resource {
/* Whether the resource owns the backing BO's label */
bool owns_label;
/* CRC state */
struct pan_crc_state crc_state;
/* AFBC-P state */
struct pan_afbcp *afbcp;
};

View file

@ -1022,7 +1022,7 @@ pan_fb_color_attachment_should_crc(const struct pan_fb_color_attachment *rt,
uint64_t mod;
struct pan_image_block_size renderblk_sz;
if (!rt->view || rt->discard || !rt->crc_valid ||
if (!rt->view || rt->discard || !rt->crc_state ||
!pan_image_view_has_crc(rt->view))
return false;
@ -1059,7 +1059,7 @@ pan_select_crc_rt(const struct pan_fb_info *fb)
continue;
/* Select the first RT with a valid CRC buffer. */
if (*fb->rts[i].crc_valid) {
if (fb->rts[i].crc_state->valid) {
best_rt = i;
break;
}
@ -1083,7 +1083,7 @@ pan_crc_enable(struct pan_crc *crc)
* forcefully writing back all the tiles and flush the CRC values. Drawback
* is it only works on full frames. */
static void
pan_crc_maybe_enable_flushed(struct pan_crc *crc,
pan_crc_maybe_enable_flushed(struct pan_crc *crc, struct pan_crc_state *state,
const struct pan_fb_info *fb)
{
if (!pan_fb_info_is_fully_covered(fb))
@ -1091,6 +1091,7 @@ pan_crc_maybe_enable_flushed(struct pan_crc *crc,
crc->write = true;
crc->force_clean_tile_write = true;
state->valid = true;
}
static struct pan_crc
@ -1116,18 +1117,17 @@ pan_get_crc_info(const struct pan_fb_info *fb)
rt = &fb->rts[crc.index];
/* Transaction Elimination. */
if (*rt->crc_valid) {
if (rt->crc_state->valid) {
pan_crc_enable(&crc);
} else {
pan_crc_maybe_enable_flushed(&crc, fb);
*rt->crc_valid = true;
pan_crc_maybe_enable_flushed(&crc, rt->crc_state, fb);
}
skip:
/* Flag CRC buffer states of unselected RTs as invalid. */
for (unsigned i = 0; i < fb->rt_count; i++)
if (i != crc.index && fb->rts[i].crc_valid)
*fb->rts[i].crc_valid = false;
if (i != crc.index && fb->rts[i].crc_state)
fb->rts[i].crc_state->valid = false;
return crc;
}

View file

@ -28,7 +28,7 @@ struct pan_compute_dim {
struct pan_fb_color_attachment {
const struct pan_image_view *view;
bool *crc_valid;
struct pan_crc_state *crc_state;
bool clear;
bool preload;
bool discard;
@ -166,6 +166,11 @@ struct pan_crc {
bool force_clean_tile_write : 1;
};
struct pan_crc_state {
/* Is the CRC buffer valid? Implicitly refers to the first slice. */
bool valid;
};
struct pan_clean_tile {
/* clean_tile_write_enable mask on the 8 color attachments. */
uint8_t write_rt_mask;
@ -189,6 +194,12 @@ pan_crc_is_enabled(struct pan_crc *crc)
return crc->index != -1;
}
static inline void
pan_crc_state_invalidate(struct pan_crc_state *state)
{
state->valid = false;
}
static inline bool
pan_clean_tile_write_rt_enabled(struct pan_clean_tile clean_tile,
unsigned index)