diff options
author | Icecream95 <ixn@disroot.org> | 2020-11-09 23:13:21 +1300 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2021-01-20 23:43:39 +0000 |
commit | 2e97d7c8350385dbf962a1d6caa5acae667d1c95 (patch) | |
tree | adb2565d13ed5f13504265e7dfe7cf951001a1d1 | |
parent | 7707ccf286eff5e918387bb3a4dd9f2423eb0766 (diff) |
panfrost: Transaction elimination support
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7086>
-rw-r--r-- | src/gallium/drivers/panfrost/pan_mfbd.c | 34 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_resource.c | 3 | ||||
-rw-r--r-- | src/panfrost/lib/pan_texture.h | 3 |
3 files changed, 36 insertions, 4 deletions
diff --git a/src/gallium/drivers/panfrost/pan_mfbd.c b/src/gallium/drivers/panfrost/pan_mfbd.c index cbdb75a8015..8932118e1ab 100644 --- a/src/gallium/drivers/panfrost/pan_mfbd.c +++ b/src/gallium/drivers/panfrost/pan_mfbd.c @@ -257,7 +257,8 @@ get_z_internal_format(struct panfrost_batch *batch) static void panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch, - struct MALI_ZS_CRC_EXTENSION *ext) + struct MALI_ZS_CRC_EXTENSION *ext, + struct panfrost_slice **checksum_slice) { struct panfrost_device *dev = pan_device(batch->ctx->base.screen); bool is_bifrost = dev->quirks & IS_BIFROST; @@ -272,6 +273,8 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch, unsigned level = c_surf->u.tex.level; struct panfrost_slice *slice = &rsrc->layout.slices[level]; + *checksum_slice = slice; + ext->crc_row_stride = slice->crc.stride; if (rsrc->checksum_bo) ext->crc_base = rsrc->checksum_bo->ptr.gpu; @@ -397,11 +400,12 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch, } static void -panfrost_mfbd_emit_zs_crc_ext(struct panfrost_batch *batch, void *extp) +panfrost_mfbd_emit_zs_crc_ext(struct panfrost_batch *batch, void *extp, + struct panfrost_slice **checksum_slice) { pan_pack(extp, ZS_CRC_EXTENSION, ext) { ext.zs_clean_pixel_write_enable = true; - panfrost_mfbd_zs_crc_ext_set_bufs(batch, &ext); + panfrost_mfbd_zs_crc_ext_set_bufs(batch, &ext, checksum_slice); } } @@ -564,12 +568,14 @@ panfrost_mfbd_fragment(struct panfrost_batch *batch, bool has_draws) if (panfrost_batch_is_scanout(batch)) batch->requirements &= ~PAN_REQ_DEPTH_WRITE; + struct panfrost_slice *checksum_slice = NULL; + if (zs_crc_ext) { if (batch->key.zsbuf && MAX2(batch->key.zsbuf->nr_samples, batch->key.zsbuf->nr_samples) > 1) batch->requirements |= PAN_REQ_MSAA; - panfrost_mfbd_emit_zs_crc_ext(batch, zs_crc_ext); + panfrost_mfbd_emit_zs_crc_ext(batch, zs_crc_ext, &checksum_slice); } /* We always upload at least one dummy GL_NONE render target */ @@ -598,6 +604,10 @@ panfrost_mfbd_fragment(struct panfrost_batch *batch, bool has_draws) rt_offset += pan_bytes_per_pixel_tib(surf->format) * tib_size * MAX2(samples, 1); + + struct panfrost_resource *prsrc = pan_resource(surf->texture); + if (!checksum_slice) + prsrc->layout.slices[surf->u.tex.level].checksum_valid = false; } } @@ -637,6 +647,22 @@ panfrost_mfbd_fragment(struct panfrost_batch *batch, bool has_draws) } params.has_zs_crc_extension = !!zs_crc_ext; + + if (checksum_slice) { + bool valid = checksum_slice->checksum_valid; + bool full = !batch->minx && !batch->miny && + batch->maxx == batch->key.width && + batch->maxy == batch->key.height; + + params.crc_read_enable = valid; + + /* If the data is currently invalid, still write CRC + * data if we are doing a full write, so that it is + * valid for next time. */ + params.crc_write_enable = valid || full; + + checksum_slice->checksum_valid |= full; + } } if (dev->quirks & IS_BIFROST) diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index 2122d23d56a..f93a3eaa600 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -1156,6 +1156,9 @@ panfrost_ptr_unmap(struct pipe_context *pctx, struct panfrost_resource *prsrc = (struct panfrost_resource *) transfer->resource; struct panfrost_device *dev = pan_device(pctx->screen); + if (transfer->usage & PIPE_MAP_WRITE) + prsrc->layout.slices[transfer->level].checksum_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 * reloads that can cascade into DATA_INVALID_FAULTs due to reading diff --git a/src/panfrost/lib/pan_texture.h b/src/panfrost/lib/pan_texture.h index 1b2f40646ed..ba7d26f93fc 100644 --- a/src/panfrost/lib/pan_texture.h +++ b/src/panfrost/lib/pan_texture.h @@ -72,6 +72,9 @@ struct panfrost_slice { /* Has anything been written to this slice? */ bool initialized; + + /* Is the checksum for this slice valid? */ + bool checksum_valid; }; struct pan_image_layout { |