diff options
author | Chris Wilson <[email protected]> | 2017-07-21 16:36:46 +0100 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2017-08-04 10:26:37 -0700 |
commit | 00f822ddfd1230f0291e84e09db6e2dab4698b15 (patch) | |
tree | 4977503be6c6623f190347664d6e01aee42bd773 /src/mesa/drivers | |
parent | 2410deefff2d1551fabfefa4d0ef48e8d9b73bc2 (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.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_bufmgr.h | 10 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_batchbuffer.c | 18 |
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; |