From: Kenneth Graunke Date: Wed, 2 Jan 2019 10:45:00 +0000 (-0800) Subject: iris: Don't check other batches for our batch BO X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=572fad1e8435e11640fe5f51bfbae58e0fad619f;p=mesa.git iris: Don't check other batches for our batch BO This is an awkward corner case. We create batches in order, each of which creates and pins a BO. The other batches may not be set up yet, so it may not be safe to ask whether they reference a BO. Just avoid this for now. We could avoid it for other context-local BOs too, but we currently don't have a flag for that (and I'm not certain whether it's worth it). --- diff --git a/src/gallium/drivers/iris/iris_batch.c b/src/gallium/drivers/iris/iris_batch.c index 5a507655b23..66ed3c36278 100644 --- a/src/gallium/drivers/iris/iris_batch.c +++ b/src/gallium/drivers/iris/iris_batch.c @@ -274,32 +274,34 @@ iris_use_pinned_bo(struct iris_batch *batch, return; } - /* This is the first time our batch has seen this BO. Before we use it, - * we may need to flush and synchronize with other batches. - */ - for (int b = 0; b < ARRAY_SIZE(batch->other_batches); b++) { - 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 (bo != batch->bo) { + /* This is the first time our batch has seen this BO. Before we use it, + * we may need to flush and synchronize with other batches. */ - if (other_entry && - ((other_entry->flags & EXEC_OBJECT_WRITE) || writable)) { - iris_batch_flush(batch->other_batches[b]); - iris_batch_add_syncpt(batch, batch->other_batches[b]->last_syncpt, - I915_EXEC_FENCE_WAIT); + for (int b = 0; b < ARRAY_SIZE(batch->other_batches); b++) { + 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]); + iris_batch_add_syncpt(batch, batch->other_batches[b]->last_syncpt, + I915_EXEC_FENCE_WAIT); + } } }