From d181218238e893141bfc058c47f946cb18c5f016 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 8 Jun 2021 20:17:23 -0400 Subject: [PATCH] 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 Part-of: --- src/gallium/drivers/panfrost/pan_resource.c | 3 ++- src/panfrost/lib/pan_blitter.c | 3 +-- src/panfrost/lib/pan_cs.c | 17 ++++++----------- src/panfrost/lib/pan_texture.h | 7 ++++--- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index 91f86eb2d40..cba0a2644a9 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -436,6 +436,7 @@ panfrost_should_checksum(const struct panfrost_device *dev, const struct panfros return pres->base.bind & PIPE_BIND_RENDER_TARGET && panfrost_is_2d(pres) && bytes_per_pixel <= bytes_per_pixel_max && + pres->base.last_level == 0 && !(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); 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 * fragment job is created; this is deferred to prevent useless surface diff --git a/src/panfrost/lib/pan_blitter.c b/src/panfrost/lib/pan_blitter.c index 003fe17f9db..97e3dafc60e 100644 --- a/src/panfrost/lib/pan_blitter.c +++ b/src/panfrost/lib/pan_blitter.c @@ -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, * write even clean tiles to make sure CRC data is updated. */ if (crc_rt >= 0) { - unsigned level = fb->rts[crc_rt].view->first_level; - bool valid = fb->rts[crc_rt].state->slices[level].crc_valid; + bool valid = fb->rts[crc_rt].state->crc_valid; bool full = !fb->extent.minx && !fb->extent.miny && fb->extent.maxx == (fb->width - 1) && fb->extent.maxy == (fb->height - 1); diff --git a/src/panfrost/lib/pan_cs.c b/src/panfrost/lib/pan_cs.c index ac2c76a9c12..423e68c2c03 100644 --- a/src/panfrost/lib/pan_cs.c +++ b/src/panfrost/lib/pan_cs.c @@ -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) continue; - unsigned level = fb->rts[i].view->first_level; - bool valid = fb->rts[i].state->slices[level].crc_valid; + bool valid = fb->rts[i].state->crc_valid; bool full = !fb->extent.minx && !fb->extent.miny && fb->extent.maxx == (fb->width - 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); int crc_rt = pan_select_crc_rt(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) { 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.has_zs_crc_extension = has_zs_crc_ext; - if (crc_slice) { - bool valid = crc_slice->crc_valid; + if (crc_rt >= 0) { + bool valid = fb->rts[crc_rt].state->crc_valid; bool full = !fb->extent.minx && !fb->extent.miny && fb->extent.maxx == (fb->width - 1) && fb->extent.maxy == (fb->height - 1); @@ -736,7 +732,7 @@ pan_emit_mfbd(const struct panfrost_device *dev, * valid for next time. */ 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) * tile_size * fb->rts[i].view->image->layout.nr_samples; - unsigned level = fb->rts[i].view->first_level; - if (crc_slice != &fb->rts[i].state->slices[level]) - fb->rts[i].state->slices[level].crc_valid = false; + if (i != crc_rt) + fb->rts[i].state->crc_valid = false; } tags |= MALI_POSITIVE(MAX2(fb->rt_count, 1)) << 2; diff --git a/src/panfrost/lib/pan_texture.h b/src/panfrost/lib/pan_texture.h index edb53ceaffa..8e88c6dc127 100644 --- a/src/panfrost/lib/pan_texture.h +++ b/src/panfrost/lib/pan_texture.h @@ -100,14 +100,15 @@ struct pan_image_layout { }; struct pan_image_slice_state { - /* Is the checksum for this slice valid? */ - bool crc_valid; - /* Has anything been written to this slice? */ bool data_valid; }; 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]; };