Mesa (master): freedreno/batch: fix dependency loop detection

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Aug 2 17:28:50 UTC 2019


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

Author: Rob Clark <robdclark at chromium.org>
Date:   Wed Jul 31 12:30:24 2019 -0700

freedreno/batch: fix dependency loop detection

We can have a scenario like:

  A -> B
  A -> C -> B

When adding the A->C dependency, it doesn't really matter that C depends
on something that A depends on, that isn't a necessary condition for a
dependency loop.

Instead what we want to know is that nothing C depends on, directly or
indirectly, depends on A.  We can detect this by recursively OR'ing the
dependents_mask of C and all it's dependencies.

Signed-off-by: Rob Clark <robdclark at chromium.org>

---

 src/gallium/drivers/freedreno/freedreno_batch.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/freedreno/freedreno_batch.c b/src/gallium/drivers/freedreno/freedreno_batch.c
index 6bab243453d..52870cd0aa1 100644
--- a/src/gallium/drivers/freedreno/freedreno_batch.c
+++ b/src/gallium/drivers/freedreno/freedreno_batch.c
@@ -401,31 +401,30 @@ fd_batch_flush(struct fd_batch *batch, bool sync)
 	fd_batch_reference(&tmp, NULL);
 }
 
-/* does 'batch' depend directly or indirectly on 'other' ? */
-static bool
-batch_depends_on(struct fd_batch *batch, struct fd_batch *other)
+/* find a batches dependents mask, including recursive dependencies: */
+static uint32_t
+recursive_dependents_mask(struct fd_batch *batch)
 {
 	struct fd_batch_cache *cache = &batch->ctx->screen->batch_cache;
 	struct fd_batch *dep;
+	uint32_t dependents_mask = batch->dependents_mask;
 
-	if (batch->dependents_mask & (1 << other->idx))
-		return true;
+	foreach_batch(dep, cache, batch->dependents_mask)
+		dependents_mask |= recursive_dependents_mask(dep);
 
-	foreach_batch(dep, cache, other->dependents_mask)
-		if (batch_depends_on(batch, dep))
-			return true;
-
-	return false;
+	return dependents_mask;
 }
 
 void
 fd_batch_add_dep(struct fd_batch *batch, struct fd_batch *dep)
 {
+	pipe_mutex_assert_locked(batch->ctx->screen->lock);
+
 	if (batch->dependents_mask & (1 << dep->idx))
 		return;
 
 	/* a loop should not be possible */
-	debug_assert(!batch_depends_on(dep, batch));
+	debug_assert(!((1 << batch->idx) & recursive_dependents_mask(dep)));
 
 	struct fd_batch *other = NULL;
 	fd_batch_reference_locked(&other, dep);




More information about the mesa-commit mailing list