iris: Don't check other batches for our batch BO
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 2 Jan 2019 10:45:00 +0000 (02:45 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:11 +0000 (10:26 -0800)
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).

src/gallium/drivers/iris/iris_batch.c

index 5a507655b230b347c4c985aeb68ad11a24d6accb..66ed3c36278573a77215a2227b111a14c15f6aa7 100644 (file)
@@ -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);
+         }
       }
    }