From 30d7bebc8a032378103c14fa3382f539bf861895 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 19 Nov 2018 21:49:56 -0800 Subject: [PATCH] iris: Avoid cross-batch synchronization on read/reads This avoids flushing batches just because e.g. both are reading the same dynamic state streaming buffer, or shader assembly buffer. --- src/gallium/drivers/iris/iris_batch.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/iris/iris_batch.c b/src/gallium/drivers/iris/iris_batch.c index cab4e843c67..065c05ae808 100644 --- a/src/gallium/drivers/iris/iris_batch.c +++ b/src/gallium/drivers/iris/iris_batch.c @@ -238,15 +238,30 @@ iris_use_pinned_bo(struct iris_batch *batch, } /* This is the first time our batch has seen this BO. Before we use it, - * we need to see if other batches reference it - if so, we should flush - * those first. + * we may need to flush and synchronize with other batches. */ for (int b = 0; b < ARRAY_SIZE(batch->other_batches); b++) { - // XXX: this is bad, we use the same state / instruction buffers for - // both batches, and if both of them are reading some dynamic state, - // we flush all the time. check for writes vs. reads? - if (iris_batch_references(batch->other_batches[b], bo)) + struct drm_i915_gem_exec_object2 *other_entry = + find_validation_entry(batch->other_batches[b], bo); + + /* If the buffer is referenced by another batch, and either batch + * intends to write it, then flush the other batch and synchronize. + * + * Consider these cases: + * + * 1. They read, we read => No synchronization required. + * 2. They read, we write => Synchronize (they need the old value) + * 3. They write, we read => Synchronize (we need their new value) + * 4. They write, we write => Synchronize (order writes) + * + * The read/read case is very common, as multiple batches usually + * share a streaming state buffer or shader assembly buffer, and + * we want to avoid synchronizing in this case. + */ + if (other_entry && + ((other_entry->flags & EXEC_OBJECT_WRITE) || writable)) { iris_batch_flush(batch->other_batches[b]); + } } /* Now, take a reference and add it to the validation list. */ -- 2.30.2