i965: Track last location of bo used for the batch
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 21 Jul 2017 15:36:46 +0000 (16:36 +0100)
committerKenneth Graunke <kenneth@whitecape.org>
Fri, 4 Aug 2017 17:26:37 +0000 (10:26 -0700)
Borrow a trick from anv, and use the last known index for the bo to skip
a search of the batch->exec_bo when adding a new relocation. In defence
against the bo being used in multiple batches simultaneously, we check
that this slot exists and points back to us.

v2: Also update brw_batch_references()
v3: Reset bo->index on creation (Daniel)
v4: Improved explanation of bo->index (Kenneth)

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_bufmgr.c
src/mesa/drivers/dri/i965/brw_bufmgr.h
src/mesa/drivers/dri/i965/intel_batchbuffer.c

index f70365eba2a1a07fcad78d99ea7b9ba735bfd706..e1036f25a4c13813ca72eee82f6c64fb2fbabc71 100644 (file)
@@ -393,6 +393,7 @@ retry:
    p_atomic_set(&bo->refcount, 1);
    bo->reusable = true;
    bo->cache_coherent = bufmgr->has_llc;
+   bo->index = -1;
 
    pthread_mutex_unlock(&bufmgr->lock);
 
index 15d37c04851dcce851a786e8019fc6d7ea31d754..d09bc74c9c258bc0ed688bf77842000f4ee095c1 100644 (file)
@@ -76,6 +76,16 @@ struct brw_bo {
     */
    uint64_t offset64;
 
+   /**
+    * The validation list index for this buffer, or -1 when not in a batch.
+    * Note that a single buffer may be in multiple batches (contexts), and
+    * this is a global field, which refers to the last batch using the BO.
+    * It should not be considered authoritative, but can be used to avoid a
+    * linear walk of the validation list in the common case by guessing that
+    * exec_bos[bo->index] == bo and confirming whether that's the case.
+    */
+   unsigned index;
+
    /**
     * Boolean of whether the GPU is definitely not accessing the buffer.
     *
index fb5ed279c8d33bd9388a164d2f0852e77ea6887e..20651d735afe2d2e531e946f2ffacb49130b4b41 100644 (file)
@@ -509,12 +509,20 @@ throttle(struct brw_context *brw)
    }
 }
 
+#define READ_ONCE(x) (*(volatile __typeof__(x) *)&(x))
+
 static void
 add_exec_bo(struct intel_batchbuffer *batch, struct brw_bo *bo)
 {
    if (bo != batch->bo) {
-      for (int i = 0; i < batch->exec_count; i++) {
-         if (batch->exec_bos[i] == bo)
+      unsigned index = READ_ONCE(bo->index);
+
+      if (index < batch->exec_count && batch->exec_bos[index] == bo)
+         return;
+
+      /* May have been shared between multiple active batches */
+      for (index = 0; index < batch->exec_count; index++) {
+         if (batch->exec_bos[index] == bo)
             return;
       }
 
@@ -547,6 +555,7 @@ add_exec_bo(struct intel_batchbuffer *batch, struct brw_bo *bo)
    validation_entry->rsvd1 = 0;
    validation_entry->rsvd2 = 0;
 
+   bo->index = batch->exec_count;
    batch->exec_bos[batch->exec_count] = bo;
    batch->exec_count++;
    batch->aperture_space += bo->size;
@@ -591,6 +600,7 @@ execbuffer(int fd,
       struct brw_bo *bo = batch->exec_bos[i];
 
       bo->idle = false;
+      bo->index = -1;
 
       /* Update brw_bo::offset64 */
       if (batch->validation_list[i].offset != bo->offset64) {
@@ -736,6 +746,10 @@ brw_batch_has_aperture_space(struct brw_context *brw, unsigned extra_space)
 bool
 brw_batch_references(struct intel_batchbuffer *batch, struct brw_bo *bo)
 {
+   unsigned index = READ_ONCE(bo->index);
+   if (index < batch->exec_count && batch->exec_bos[index] == bo)
+      return true;
+
    for (int i = 0; i < batch->exec_count; i++) {
       if (batch->exec_bos[i] == bo)
          return true;