aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/iris/iris_batch.c
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2018-11-19 21:49:56 -0800
committerKenneth Graunke <[email protected]>2019-02-21 10:26:10 -0800
commit30d7bebc8a032378103c14fa3382f539bf861895 (patch)
treec52727f7c148aaa7d49587f4e8a657e127881cb8 /src/gallium/drivers/iris/iris_batch.c
parentb21e916a6280f9aee5353c0dd4c6bcebb947496d (diff)
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.
Diffstat (limited to 'src/gallium/drivers/iris/iris_batch.c')
-rw-r--r--src/gallium/drivers/iris/iris_batch.c27
1 files 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. */