Mesa (master): freedreno: deferred flush support

Rob Clark robclark at kemper.freedesktop.org
Sun Dec 3 19:53:37 UTC 2017


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

Author: Rob Clark <robdclark at gmail.com>
Date:   Sun Nov 19 11:42:25 2017 -0500

freedreno: deferred flush support

Signed-off-by: Rob Clark <robdclark at gmail.com>

---

 src/gallium/drivers/freedreno/freedreno_batch.c    |  8 ++++----
 src/gallium/drivers/freedreno/freedreno_batch.h    |  1 +
 .../drivers/freedreno/freedreno_batch_cache.c      | 24 ++++++++++++++++++++++
 .../drivers/freedreno/freedreno_batch_cache.h      |  1 +
 src/gallium/drivers/freedreno/freedreno_context.c  |  2 ++
 5 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/freedreno/freedreno_batch.c b/src/gallium/drivers/freedreno/freedreno_batch.c
index 2b7e19a633..eff5e8dc35 100644
--- a/src/gallium/drivers/freedreno/freedreno_batch.c
+++ b/src/gallium/drivers/freedreno/freedreno_batch.c
@@ -350,8 +350,8 @@ batch_depends_on(struct fd_batch *batch, struct fd_batch *other)
 	return false;
 }
 
-static void
-batch_add_dep(struct fd_batch *batch, struct fd_batch *dep)
+void
+fd_batch_add_dep(struct fd_batch *batch, struct fd_batch *dep)
 {
 	if (batch->dependents_mask & (1 << dep->idx))
 		return;
@@ -398,7 +398,7 @@ fd_batch_resource_used(struct fd_batch *batch, struct fd_resource *rsc, bool wri
 				 * fd_bc_invalidate_batch()
 				 */
 				fd_batch_reference(&b, dep);
-				batch_add_dep(batch, b);
+				fd_batch_add_dep(batch, b);
 				fd_bc_invalidate_batch(b, false);
 				fd_batch_reference_locked(&b, NULL);
 			}
@@ -406,7 +406,7 @@ fd_batch_resource_used(struct fd_batch *batch, struct fd_resource *rsc, bool wri
 		fd_batch_reference_locked(&rsc->write_batch, batch);
 	} else {
 		if (rsc->write_batch) {
-			batch_add_dep(batch, rsc->write_batch);
+			fd_batch_add_dep(batch, rsc->write_batch);
 			fd_bc_invalidate_batch(rsc->write_batch, false);
 		}
 	}
diff --git a/src/gallium/drivers/freedreno/freedreno_batch.h b/src/gallium/drivers/freedreno/freedreno_batch.h
index a5fa6ce5a2..d69ff6f80b 100644
--- a/src/gallium/drivers/freedreno/freedreno_batch.h
+++ b/src/gallium/drivers/freedreno/freedreno_batch.h
@@ -207,6 +207,7 @@ struct fd_batch * fd_batch_create(struct fd_context *ctx);
 void fd_batch_reset(struct fd_batch *batch);
 void fd_batch_sync(struct fd_batch *batch);
 void fd_batch_flush(struct fd_batch *batch, bool sync, bool force);
+void fd_batch_add_dep(struct fd_batch *batch, struct fd_batch *dep);
 void fd_batch_resource_used(struct fd_batch *batch, struct fd_resource *rsc, bool write);
 void fd_batch_check_size(struct fd_batch *batch);
 
diff --git a/src/gallium/drivers/freedreno/freedreno_batch_cache.c b/src/gallium/drivers/freedreno/freedreno_batch_cache.c
index 470aca4f38..def1328513 100644
--- a/src/gallium/drivers/freedreno/freedreno_batch_cache.c
+++ b/src/gallium/drivers/freedreno/freedreno_batch_cache.c
@@ -153,6 +153,30 @@ fd_bc_flush(struct fd_batch_cache *cache, struct fd_context *ctx)
 	}
 }
 
+/* deferred flush doesn't actually flush, but it marks every other
+ * batch associated with the context as dependent on the current
+ * batch.  So when the current batch gets flushed, all other batches
+ * that came before also get flushed.
+ */
+void
+fd_bc_flush_deferred(struct fd_batch_cache *cache, struct fd_context *ctx)
+{
+	struct fd_batch *current_batch = ctx->batch;
+	struct hash_entry *entry;
+
+	mtx_lock(&ctx->screen->lock);
+
+	hash_table_foreach(cache->ht, entry) {
+		struct fd_batch *batch = entry->data;
+		if (batch == current_batch)
+			continue;
+		if (batch->ctx == ctx)
+			fd_batch_add_dep(current_batch, batch);
+	}
+
+	mtx_unlock(&ctx->screen->lock);
+}
+
 void
 fd_bc_invalidate_context(struct fd_context *ctx)
 {
diff --git a/src/gallium/drivers/freedreno/freedreno_batch_cache.h b/src/gallium/drivers/freedreno/freedreno_batch_cache.h
index 44c66b58f3..348418e187 100644
--- a/src/gallium/drivers/freedreno/freedreno_batch_cache.h
+++ b/src/gallium/drivers/freedreno/freedreno_batch_cache.h
@@ -63,6 +63,7 @@ void fd_bc_init(struct fd_batch_cache *cache);
 void fd_bc_fini(struct fd_batch_cache *cache);
 
 void fd_bc_flush(struct fd_batch_cache *cache, struct fd_context *ctx);
+void fd_bc_flush_deferred(struct fd_batch_cache *cache, struct fd_context *ctx);
 
 void fd_bc_invalidate_context(struct fd_context *ctx);
 void fd_bc_invalidate_batch(struct fd_batch *batch, bool destroy);
diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c
index e138ac94ae..0ec81f882d 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.c
+++ b/src/gallium/drivers/freedreno/freedreno_context.c
@@ -54,6 +54,8 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep,
 
 	if (!ctx->screen->reorder) {
 		fd_batch_flush(ctx->batch, true, false);
+	} else if (flags & PIPE_FLUSH_DEFERRED) {
+		fd_bc_flush_deferred(&ctx->screen->batch_cache, ctx);
 	} else {
 		fd_bc_flush(&ctx->screen->batch_cache, ctx);
 	}




More information about the mesa-commit mailing list