summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers
diff options
context:
space:
mode:
authorChris Wilson <[email protected]>2017-07-21 16:36:46 +0100
committerKenneth Graunke <[email protected]>2017-08-04 10:26:37 -0700
commit00f822ddfd1230f0291e84e09db6e2dab4698b15 (patch)
tree4977503be6c6623f190347664d6e01aee42bd773 /src/mesa/drivers
parent2410deefff2d1551fabfefa4d0ef48e8d9b73bc2 (diff)
i965: Track last location of bo used for the batch
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 <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/dri/i965/brw_bufmgr.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_bufmgr.h10
-rw-r--r--src/mesa/drivers/dri/i965/intel_batchbuffer.c18
3 files changed, 27 insertions, 2 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.c b/src/mesa/drivers/dri/i965/brw_bufmgr.c
index f70365eba2a..e1036f25a4c 100644
--- a/src/mesa/drivers/dri/i965/brw_bufmgr.c
+++ b/src/mesa/drivers/dri/i965/brw_bufmgr.c
@@ -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);
diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.h b/src/mesa/drivers/dri/i965/brw_bufmgr.h
index 15d37c04851..d09bc74c9c2 100644
--- a/src/mesa/drivers/dri/i965/brw_bufmgr.h
+++ b/src/mesa/drivers/dri/i965/brw_bufmgr.h
@@ -77,6 +77,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.
*
* This is only valid when reusable, since non-reusable
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index fb5ed279c8d..20651d735af 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -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;