Mesa (master): freedreno/a6xx: Avoid stalling for occlusion queries

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu May 21 00:46:50 UTC 2020


Module: Mesa
Branch: master
Commit: 13fc03f4c0e709f6d1a8d811f9bc8a0c8c42943c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=13fc03f4c0e709f6d1a8d811f9bc8a0c8c42943c

Author: Kristian H. Kristensen <hoegsberg at google.com>
Date:   Fri May 15 12:23:18 2020 -0700

freedreno/a6xx: Avoid stalling for occlusion queries

If we postpone computing the counter delta until after each tile (or
sysmem pass), we don't have to stall in the middle of the draw stream.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5064>

---

 src/gallium/drivers/freedreno/a6xx/fd6_gmem.c   |  6 ++++++
 src/gallium/drivers/freedreno/a6xx/fd6_query.c  | 23 +++++++++++------------
 src/gallium/drivers/freedreno/freedreno_batch.c |  5 +++++
 src/gallium/drivers/freedreno/freedreno_batch.h | 13 +++++++++++++
 4 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
index 0e053d62ce3..b71c77ddc6c 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
@@ -1377,6 +1377,9 @@ fd6_emit_tile_fini(struct fd_batch *batch)
 {
 	struct fd_ringbuffer *ring = batch->gmem;
 
+	if (batch->epilogue)
+		fd6_emit_ib(batch->gmem, batch->epilogue);
+
 	OUT_PKT4(ring, REG_A6XX_GRAS_LRZ_CNTL, 1);
 	OUT_RING(ring, A6XX_GRAS_LRZ_CNTL_ENABLE | A6XX_GRAS_LRZ_CNTL_UNK3);
 
@@ -1527,6 +1530,9 @@ fd6_emit_sysmem_fini(struct fd_batch *batch)
 {
 	struct fd_ringbuffer *ring = batch->gmem;
 
+	if (batch->epilogue)
+		fd6_emit_ib(batch->gmem, batch->epilogue);
+
 	OUT_PKT7(ring, CP_SKIP_IB2_ENABLE_GLOBAL, 1);
 	OUT_RING(ring, 0x0);
 
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_query.c b/src/gallium/drivers/freedreno/a6xx/fd6_query.c
index 8258760e2e6..a23b02f4e0b 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_query.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_query.c
@@ -95,21 +95,20 @@ occlusion_pause(struct fd_acc_query *aq, struct fd_batch *batch)
 
 	fd6_event_write(batch, ring, ZPASS_DONE, false);
 
-	OUT_PKT7(ring, CP_WAIT_REG_MEM, 6);
-	OUT_RING(ring, 0x00000014);   // XXX
-	OUT_RELOC(ring, query_sample(aq, stop));
-	OUT_RING(ring, 0xffffffff);
-	OUT_RING(ring, 0xffffffff);
-	OUT_RING(ring, 0x00000010);   // XXX
+	/* To avoid stalling in the draw buffer, emit code the code to compute the
+	 * counter delta in the epilogue ring.
+	 */
+	struct fd_ringbuffer *epilogue = fd_batch_get_epilogue(batch);
+	fd_wfi(batch, epilogue);
 
 	/* result += stop - start: */
-	OUT_PKT7(ring, CP_MEM_TO_MEM, 9);
-	OUT_RING(ring, CP_MEM_TO_MEM_0_DOUBLE |
+	OUT_PKT7(epilogue, CP_MEM_TO_MEM, 9);
+	OUT_RING(epilogue, CP_MEM_TO_MEM_0_DOUBLE |
 			CP_MEM_TO_MEM_0_NEG_C);
-	OUT_RELOC(ring, query_sample(aq, result));     /* dst */
-	OUT_RELOC(ring, query_sample(aq, result));      /* srcA */
-	OUT_RELOC(ring, query_sample(aq, stop));        /* srcB */
-	OUT_RELOC(ring, query_sample(aq, start));       /* srcC */
+	OUT_RELOC(epilogue, query_sample(aq, result));     /* dst */
+	OUT_RELOC(epilogue, query_sample(aq, result));      /* srcA */
+	OUT_RELOC(epilogue, query_sample(aq, stop));        /* srcB */
+	OUT_RELOC(epilogue, query_sample(aq, start));       /* srcC */
 
 	fd6_context(batch->ctx)->samples_passed_queries--;
 }
diff --git a/src/gallium/drivers/freedreno/freedreno_batch.c b/src/gallium/drivers/freedreno/freedreno_batch.c
index 288f3307ad3..b31dd2c02c8 100644
--- a/src/gallium/drivers/freedreno/freedreno_batch.c
+++ b/src/gallium/drivers/freedreno/freedreno_batch.c
@@ -161,6 +161,11 @@ batch_fini(struct fd_batch *batch)
 		batch->lrz_clear = NULL;
 	}
 
+	if (batch->epilogue) {
+		fd_ringbuffer_del(batch->epilogue);
+		batch->epilogue = NULL;
+	}
+
 	if (batch->tile_setup) {
 		fd_ringbuffer_del(batch->tile_setup);
 		batch->tile_setup = NULL;
diff --git a/src/gallium/drivers/freedreno/freedreno_batch.h b/src/gallium/drivers/freedreno/freedreno_batch.h
index 6a48c3435ac..e64d9061b6b 100644
--- a/src/gallium/drivers/freedreno/freedreno_batch.h
+++ b/src/gallium/drivers/freedreno/freedreno_batch.h
@@ -184,6 +184,9 @@ struct fd_batch {
 	/** tiling/gmem (IB0) cmdstream: */
 	struct fd_ringbuffer *gmem;
 
+	/** epilogue cmdstream: */
+	struct fd_ringbuffer *epilogue;
+
 	// TODO maybe more generically split out clear and clear_binning rings?
 	struct fd_ringbuffer *lrz_clear;
 	struct fd_ringbuffer *tile_setup;
@@ -336,4 +339,14 @@ fd_event_write(struct fd_batch *batch, struct fd_ringbuffer *ring,
 	fd_reset_wfi(batch);
 }
 
+static inline struct fd_ringbuffer *
+fd_batch_get_epilogue(struct fd_batch *batch)
+{
+	if (batch->epilogue == NULL)
+		batch->epilogue = fd_submit_new_ringbuffer(batch->submit, 0x1000, 0);
+
+	return batch->epilogue;
+}
+
+
 #endif /* FREEDRENO_BATCH_H_ */



More information about the mesa-commit mailing list