summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIcecream95 <ixn@disroot.org>2020-11-09 23:13:21 +1300
committerMarge Bot <eric+marge@anholt.net>2021-01-20 23:43:39 +0000
commit2e97d7c8350385dbf962a1d6caa5acae667d1c95 (patch)
treeadb2565d13ed5f13504265e7dfe7cf951001a1d1
parent7707ccf286eff5e918387bb3a4dd9f2423eb0766 (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.c34
-rw-r--r--src/gallium/drivers/panfrost/pan_resource.c3
-rw-r--r--src/panfrost/lib/pan_texture.h3
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 {