summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <alyssa@collabora.com>2022-06-10 11:28:09 -0400
committerDylan Baker <dylan.c.baker@intel.com>2022-06-15 16:12:59 -0700
commit7597df42b8d77bb3cadc36779601404cdd5ccecf (patch)
tree3fba18eb2446e0e8c31f2719f611934bc54a0da1
parentd331e4edcdc121f38c7512ea55c22d8652fbae68 (diff)
panfrost: Disable CRC at <16x16 tile sizes
The hardware writes one CRC per (effective) tile, the tile size of the CRC buffer is the same as the configured effective tile size. However, all our CRC infrastructure assumes 16x16 tiles. In case CRC is used with smaller tiles, buffer overflows and incorrect rendering are all possible. Don't use CRC at smaller tile sizes. Note disabling CRC correctly invalidates any bound CRC buffers. Fixes: 2e97d7c8350 ("panfrost: Transaction elimination support") Closes: #6332 Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16983> (cherry picked from commit 44223e5f28c42ff19a5ddba182b403315bbac3ef)
-rw-r--r--.pick_status.json2
-rw-r--r--src/panfrost/lib/pan_blitter.c5
-rw-r--r--src/panfrost/lib/pan_cs.c18
-rw-r--r--src/panfrost/lib/pan_cs.h2
4 files changed, 22 insertions, 5 deletions
diff --git a/.pick_status.json b/.pick_status.json
index 0c9f725c424..4524df8538e 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -166,7 +166,7 @@
"description": "panfrost: Disable CRC at <16x16 tile sizes",
"nominated": true,
"nomination_type": 1,
- "resolution": 0,
+ "resolution": 1,
"main_sha": null,
"because_sha": "2e97d7c8350385dbf962a1d6caa5acae667d1c95"
},
diff --git a/src/panfrost/lib/pan_blitter.c b/src/panfrost/lib/pan_blitter.c
index 60b9fd3aa9d..40e5e762231 100644
--- a/src/panfrost/lib/pan_blitter.c
+++ b/src/panfrost/lib/pan_blitter.c
@@ -1046,7 +1046,10 @@ pan_preload_emit_pre_frame_dcd(struct pan_pool *desc_pool,
void *dcd = fb->bifrost.pre_post.dcds.cpu +
(dcd_idx * pan_size(DRAW));
- int crc_rt = GENX(pan_select_crc_rt)(fb);
+ /* We only use crc_rt to determine whether to force writes for updating
+ * the CRCs, so use a conservative tile size (16x16).
+ */
+ int crc_rt = GENX(pan_select_crc_rt)(fb, 16 * 16);
bool always_write = false;
diff --git a/src/panfrost/lib/pan_cs.c b/src/panfrost/lib/pan_cs.c
index 63b311509c3..41babe5d836 100644
--- a/src/panfrost/lib/pan_cs.c
+++ b/src/panfrost/lib/pan_cs.c
@@ -83,8 +83,22 @@ pan_sample_pattern(unsigned samples)
}
int
-GENX(pan_select_crc_rt)(const struct pan_fb_info *fb)
+GENX(pan_select_crc_rt)(const struct pan_fb_info *fb, unsigned tile_size)
{
+ /* Disable CRC when the tile size is not 16x16. In the hardware, CRC
+ * tiles are the same size as the tiles of the framebuffer. However,
+ * our code only handles 16x16 tiles. Therefore under the current
+ * implementation, we must disable CRC when 16x16 tiles are not used.
+ *
+ * This may hurt performance. However, smaller tile sizes are rare, and
+ * CRCs are more expensive at smaller tile sizes, reducing the benefit.
+ * Restricting CRC to 16x16 should work in practice.
+ */
+ if (tile_size != 16 * 16) {
+ assert(tile_size < 16 * 16);
+ return -1;
+ }
+
#if PAN_ARCH <= 6
if (fb->rt_count == 1 && fb->rts[0].view && !fb->rts[0].discard &&
fb->rts[0].view->image->layout.crc_mode != PAN_IMAGE_CRC_NONE)
@@ -636,7 +650,7 @@ GENX(pan_emit_fbd)(const struct panfrost_device *dev,
unsigned tile_size;
unsigned internal_cbuf_size = pan_internal_cbuf_size(fb, &tile_size);
- int crc_rt = GENX(pan_select_crc_rt)(fb);
+ int crc_rt = GENX(pan_select_crc_rt)(fb, tile_size);
bool has_zs_crc_ext = (fb->zs.view.zs || fb->zs.view.s || crc_rt >= 0);
pan_section_pack(fbd, FRAMEBUFFER, PARAMETERS, cfg) {
diff --git a/src/panfrost/lib/pan_cs.h b/src/panfrost/lib/pan_cs.h
index b6a5cc34321..beee54bee81 100644
--- a/src/panfrost/lib/pan_cs.h
+++ b/src/panfrost/lib/pan_cs.h
@@ -149,7 +149,7 @@ GENX(pan_emit_tls)(const struct pan_tls_info *info,
void *out);
int
-GENX(pan_select_crc_rt)(const struct pan_fb_info *fb);
+GENX(pan_select_crc_rt)(const struct pan_fb_info *fb, unsigned tile_size);
unsigned
GENX(pan_emit_fbd)(const struct panfrost_device *dev,