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

Author: Rob Clark <[email protected]>
Date:   Tue Jul 17 10:02:51 2018 -0400

freedreno: flush immediately when reading a pending batch

Instead of the reading batch setting a dependency on the writing batch,
simply flush the writing batch immediately.  This avoids situations
where we have to flush the context's current batch later.

Signed-off-by: Rob Clark <[email protected]>

---

 src/gallium/drivers/freedreno/freedreno_batch.c   | 60 +++++++++++------------
 src/gallium/drivers/freedreno/freedreno_context.c |  2 +
 2 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/src/gallium/drivers/freedreno/freedreno_batch.c 
b/src/gallium/drivers/freedreno/freedreno_batch.c
index 6244e3bcc2..b6f030ac90 100644
--- a/src/gallium/drivers/freedreno/freedreno_batch.c
+++ b/src/gallium/drivers/freedreno/freedreno_batch.c
@@ -362,20 +362,27 @@ fd_batch_add_dep(struct fd_batch *batch, struct fd_batch 
*dep)
        if (batch->dependents_mask & (1 << dep->idx))
                return;
 
-       /* if the new depedency already depends on us, we need to flush
-        * to avoid a loop in the dependency graph.
-        */
-       if (batch_depends_on(dep, batch)) {
-               DBG("%p: flush forced on %p!", batch, dep);
-               mtx_unlock(&batch->ctx->screen->lock);
-               fd_batch_flush(dep, false, false);
-               mtx_lock(&batch->ctx->screen->lock);
-       } else {
-               struct fd_batch *other = NULL;
-               fd_batch_reference_locked(&other, dep);
-               batch->dependents_mask |= (1 << dep->idx);
-               DBG("%p: added dependency on %p", batch, dep);
-       }
+       /* a loop should not be possible */
+       debug_assert(!batch_depends_on(dep, batch));
+
+       struct fd_batch *other = NULL;
+       fd_batch_reference_locked(&other, dep);
+       batch->dependents_mask |= (1 << dep->idx);
+       DBG("%p: added dependency on %p", batch, dep);
+}
+
+static void
+flush_write_batch(struct fd_resource *rsc)
+{
+       struct fd_batch *b = NULL;
+       fd_batch_reference(&b, rsc->write_batch);
+
+       mtx_unlock(&b->ctx->screen->lock);
+       fd_batch_flush(b, true, false);
+       mtx_lock(&b->ctx->screen->lock);
+
+       fd_bc_invalidate_batch(b, false);
+       fd_batch_reference_locked(&b, NULL);
 }
 
 void
@@ -397,21 +404,12 @@ fd_batch_resource_used(struct fd_batch *batch, struct 
fd_resource *rsc, bool wri
 
        if (write) {
                /* if we are pending read or write by any other batch: */
-               if (rsc->batch_mask != (1 << batch->idx)) {
+               if (rsc->batch_mask & ~(1 << batch->idx)) {
                        struct fd_batch_cache *cache = 
&batch->ctx->screen->batch_cache;
                        struct fd_batch *dep;
 
-                       if (rsc->write_batch && rsc->write_batch != batch) {
-                               struct fd_batch *b = NULL;
-                               fd_batch_reference(&b, rsc->write_batch);
-
-                               mtx_unlock(&batch->ctx->screen->lock);
-                               fd_batch_flush(b, true, false);
-                               mtx_lock(&batch->ctx->screen->lock);
-
-                               fd_bc_invalidate_batch(b, false);
-                               fd_batch_reference_locked(&b, NULL);
-                       }
+                       if (rsc->write_batch && rsc->write_batch != batch)
+                               flush_write_batch(rsc);
 
                        foreach_batch(dep, cache, rsc->batch_mask) {
                                struct fd_batch *b = NULL;
@@ -429,10 +427,12 @@ 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) {
-                       fd_batch_add_dep(batch, rsc->write_batch);
-                       fd_bc_invalidate_batch(rsc->write_batch, false);
-               }
+               /* If reading a resource pending a write, go ahead and flush the
+                * writer.  This avoids situations where we end up having to
+                * flush the current batch in _resource_used()
+                */
+               if (rsc->write_batch && rsc->write_batch != batch)
+                       flush_write_batch(rsc);
        }
 
        if (rsc->batch_mask & (1 << batch->idx))
diff --git a/src/gallium/drivers/freedreno/freedreno_context.c 
b/src/gallium/drivers/freedreno/freedreno_context.c
index 9c6a21ca5b..e1324e8c0a 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.c
+++ b/src/gallium/drivers/freedreno/freedreno_context.c
@@ -101,6 +101,8 @@ fd_emit_string_marker(struct pipe_context *pctx, const char 
*string, int len)
        if (!ctx->batch)
                return;
 
+       ctx->batch->needs_flush = true;
+
        ring = ctx->batch->draw;
 
        /* max packet size is 0x3fff dwords: */

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to