panfrost: Don't CRC mipmapped textures
CRC is intended for final render targets and especially for UI, not the kind of things you'd mipmap. Meanwhile CRC only works for a single level, meaning at any given point, half the CRC buffer would be wasted for a full miptree. "Arm Mali Best Practices Guide" tells developers that the DDK only enables CRC for non-mipmapped resources (at least the Vulkan DDK), so let's do the same, save some memory, and simplify our code. Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11123>
This commit is contained in:
parent
eb82863f8a
commit
d181218238
|
@ -436,6 +436,7 @@ panfrost_should_checksum(const struct panfrost_device *dev, const struct panfros
|
||||||
return pres->base.bind & PIPE_BIND_RENDER_TARGET &&
|
return pres->base.bind & PIPE_BIND_RENDER_TARGET &&
|
||||||
panfrost_is_2d(pres) &&
|
panfrost_is_2d(pres) &&
|
||||||
bytes_per_pixel <= bytes_per_pixel_max &&
|
bytes_per_pixel <= bytes_per_pixel_max &&
|
||||||
|
pres->base.last_level == 0 &&
|
||||||
!(dev->debug & PAN_DBG_NO_CRC);
|
!(dev->debug & PAN_DBG_NO_CRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,7 +1078,7 @@ panfrost_ptr_unmap(struct pipe_context *pctx,
|
||||||
struct panfrost_device *dev = pan_device(pctx->screen);
|
struct panfrost_device *dev = pan_device(pctx->screen);
|
||||||
|
|
||||||
if (transfer->usage & PIPE_MAP_WRITE)
|
if (transfer->usage & PIPE_MAP_WRITE)
|
||||||
prsrc->state.slices[transfer->level].crc_valid = false;
|
prsrc->state.crc_valid = false;
|
||||||
|
|
||||||
/* AFBC will use a staging resource. `initialized` will be set when the
|
/* AFBC will use a staging resource. `initialized` will be set when the
|
||||||
* fragment job is created; this is deferred to prevent useless surface
|
* fragment job is created; this is deferred to prevent useless surface
|
||||||
|
|
|
@ -1248,8 +1248,7 @@ pan_preload_emit_bifrost_pre_frame_dcd(struct pan_pool *desc_pool,
|
||||||
/* If CRC data is currently invalid and this batch will make it valid,
|
/* If CRC data is currently invalid and this batch will make it valid,
|
||||||
* write even clean tiles to make sure CRC data is updated. */
|
* write even clean tiles to make sure CRC data is updated. */
|
||||||
if (crc_rt >= 0) {
|
if (crc_rt >= 0) {
|
||||||
unsigned level = fb->rts[crc_rt].view->first_level;
|
bool valid = fb->rts[crc_rt].state->crc_valid;
|
||||||
bool valid = fb->rts[crc_rt].state->slices[level].crc_valid;
|
|
||||||
bool full = !fb->extent.minx && !fb->extent.miny &&
|
bool full = !fb->extent.minx && !fb->extent.miny &&
|
||||||
fb->extent.maxx == (fb->width - 1) &&
|
fb->extent.maxx == (fb->width - 1) &&
|
||||||
fb->extent.maxy == (fb->height - 1);
|
fb->extent.maxy == (fb->height - 1);
|
||||||
|
|
|
@ -331,8 +331,7 @@ pan_select_crc_rt(const struct panfrost_device *dev, const struct pan_fb_info *f
|
||||||
fb->rts[i].view->image->layout.crc_mode == PAN_IMAGE_CRC_NONE)
|
fb->rts[i].view->image->layout.crc_mode == PAN_IMAGE_CRC_NONE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
unsigned level = fb->rts[i].view->first_level;
|
bool valid = fb->rts[i].state->crc_valid;
|
||||||
bool valid = fb->rts[i].state->slices[level].crc_valid;
|
|
||||||
bool full = !fb->extent.minx && !fb->extent.miny &&
|
bool full = !fb->extent.minx && !fb->extent.miny &&
|
||||||
fb->extent.maxx == (fb->width - 1) &&
|
fb->extent.maxx == (fb->width - 1) &&
|
||||||
fb->extent.maxy == (fb->height - 1);
|
fb->extent.maxy == (fb->height - 1);
|
||||||
|
@ -693,9 +692,6 @@ pan_emit_mfbd(const struct panfrost_device *dev,
|
||||||
unsigned internal_cbuf_size = pan_internal_cbuf_size(fb, &tile_size);
|
unsigned internal_cbuf_size = pan_internal_cbuf_size(fb, &tile_size);
|
||||||
int crc_rt = pan_select_crc_rt(dev, fb);
|
int crc_rt = pan_select_crc_rt(dev, fb);
|
||||||
bool has_zs_crc_ext = pan_fbd_has_zs_crc_ext(dev, fb);
|
bool has_zs_crc_ext = pan_fbd_has_zs_crc_ext(dev, fb);
|
||||||
const struct pan_image_view *crc_view = crc_rt < 0 ? NULL : fb->rts[crc_rt].view;
|
|
||||||
struct pan_image_slice_state *crc_slice =
|
|
||||||
crc_rt < 0 ? NULL : &fb->rts[crc_rt].state->slices[crc_view->first_level];
|
|
||||||
|
|
||||||
pan_section_pack(fbd, MULTI_TARGET_FRAMEBUFFER, PARAMETERS, cfg) {
|
pan_section_pack(fbd, MULTI_TARGET_FRAMEBUFFER, PARAMETERS, cfg) {
|
||||||
cfg.width = fb->width;
|
cfg.width = fb->width;
|
||||||
|
@ -723,8 +719,8 @@ pan_emit_mfbd(const struct panfrost_device *dev,
|
||||||
cfg.s_write_enable = (fb->zs.view.s && !fb->zs.discard.s);
|
cfg.s_write_enable = (fb->zs.view.s && !fb->zs.discard.s);
|
||||||
cfg.has_zs_crc_extension = has_zs_crc_ext;
|
cfg.has_zs_crc_extension = has_zs_crc_ext;
|
||||||
|
|
||||||
if (crc_slice) {
|
if (crc_rt >= 0) {
|
||||||
bool valid = crc_slice->crc_valid;
|
bool valid = fb->rts[crc_rt].state->crc_valid;
|
||||||
bool full = !fb->extent.minx && !fb->extent.miny &&
|
bool full = !fb->extent.minx && !fb->extent.miny &&
|
||||||
fb->extent.maxx == (fb->width - 1) &&
|
fb->extent.maxx == (fb->width - 1) &&
|
||||||
fb->extent.maxy == (fb->height - 1);
|
fb->extent.maxy == (fb->height - 1);
|
||||||
|
@ -736,7 +732,7 @@ pan_emit_mfbd(const struct panfrost_device *dev,
|
||||||
* valid for next time. */
|
* valid for next time. */
|
||||||
cfg.crc_write_enable = valid || full;
|
cfg.crc_write_enable = valid || full;
|
||||||
|
|
||||||
crc_slice->crc_valid = full;
|
fb->rts[crc_rt].state->crc_valid = full;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,9 +759,8 @@ pan_emit_mfbd(const struct panfrost_device *dev,
|
||||||
cbuf_offset += pan_bytes_per_pixel_tib(fb->rts[i].view->format) *
|
cbuf_offset += pan_bytes_per_pixel_tib(fb->rts[i].view->format) *
|
||||||
tile_size * fb->rts[i].view->image->layout.nr_samples;
|
tile_size * fb->rts[i].view->image->layout.nr_samples;
|
||||||
|
|
||||||
unsigned level = fb->rts[i].view->first_level;
|
if (i != crc_rt)
|
||||||
if (crc_slice != &fb->rts[i].state->slices[level])
|
fb->rts[i].state->crc_valid = false;
|
||||||
fb->rts[i].state->slices[level].crc_valid = false;
|
|
||||||
}
|
}
|
||||||
tags |= MALI_POSITIVE(MAX2(fb->rt_count, 1)) << 2;
|
tags |= MALI_POSITIVE(MAX2(fb->rt_count, 1)) << 2;
|
||||||
|
|
||||||
|
|
|
@ -100,14 +100,15 @@ struct pan_image_layout {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pan_image_slice_state {
|
struct pan_image_slice_state {
|
||||||
/* Is the checksum for this slice valid? */
|
|
||||||
bool crc_valid;
|
|
||||||
|
|
||||||
/* Has anything been written to this slice? */
|
/* Has anything been written to this slice? */
|
||||||
bool data_valid;
|
bool data_valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pan_image_state {
|
struct pan_image_state {
|
||||||
|
/* Is the checksum for this image valid? Implicitly refers to the first
|
||||||
|
* slice, as we only checksum non-mipmapped 2D images */
|
||||||
|
bool crc_valid;
|
||||||
|
|
||||||
struct pan_image_slice_state slices[MAX_MIP_LEVELS];
|
struct pan_image_slice_state slices[MAX_MIP_LEVELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue