summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <[email protected]>2017-07-21 16:36:47 +0100
committerKenneth Graunke <[email protected]>2017-08-04 10:26:37 -0700
commit3f353342a6b6744773c26ed66b12afed42bd57af (patch)
tree0c82a59b1f564c93e013990b656523fba5bf7a42 /src
parent12a77f391f80e2c35fd4676a9c9f882003221712 (diff)
i965: Use I915_EXEC_NO_RELOC
If we correctly fill the batch with the right relocation value, and that matches the expected location of the object, we can then tell the kernel it can forgo checking each individual relocation by only checking whether the object moved. v2: Rebase to apply ahead of I915_EXEC_HANDLE_LUT Signed-off-by: Chris Wilson <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/intel_batchbuffer.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index 58482ecac9f..dcc6f90238c 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -637,7 +637,19 @@ do_flush_locked(struct brw_context *brw, int in_fence_fd, int *out_fence_fd)
}
if (!brw->screen->no_hw) {
- int flags = 0;
+ /* The requirement for using I915_EXEC_NO_RELOC are:
+ *
+ * The addresses written in the objects must match the corresponding
+ * reloc.presumed_offset which in turn must match the corresponding
+ * execobject.offset.
+ *
+ * Any render targets written to in the batch must be flagged with
+ * EXEC_OBJECT_WRITE.
+ *
+ * To avoid stalling, execobject.offset should match the current
+ * address of that object within the active context.
+ */
+ int flags = I915_EXEC_NO_RELOC;
if (brw->gen >= 6 && batch->ring == BLT_RING) {
flags |= I915_EXEC_BLT;
@@ -767,8 +779,6 @@ brw_emit_reloc(struct intel_batchbuffer *batch, uint32_t batch_offset,
{
assert(target != NULL);
- uint64_t offset64;
-
if (batch->reloc_count == batch->reloc_array_size) {
batch->reloc_array_size *= 2;
batch->relocs = realloc(batch->relocs,
@@ -780,16 +790,32 @@ brw_emit_reloc(struct intel_batchbuffer *batch, uint32_t batch_offset,
assert(batch_offset <= BATCH_SZ - sizeof(uint32_t));
assert(_mesa_bitcount(write_domain) <= 1);
- if (target != batch->bo)
- add_exec_bo(batch, target);
+ uint64_t offset64;
+ if (target != batch->bo) {
+ unsigned int index = add_exec_bo(batch, target);
+ struct drm_i915_gem_exec_object2 *entry = &batch->validation_list[index];
+
+ if (write_domain) {
+ entry->flags |= EXEC_OBJECT_WRITE;
+
+ /* PIPECONTROL needs a w/a on gen6 */
+ if (write_domain == I915_GEM_DOMAIN_INSTRUCTION) {
+ struct brw_context *brw = container_of(batch, brw, batch);
+ if (brw->gen == 6)
+ entry->flags |= EXEC_OBJECT_NEEDS_GTT;
+ }
+ }
+
+ offset64 = entry->offset;
+ } else {
+ offset64 = target->offset64;
+ }
struct drm_i915_gem_relocation_entry *reloc =
&batch->relocs[batch->reloc_count];
batch->reloc_count++;
- /* ensure gcc doesn't reload */
- offset64 = *((volatile uint64_t *)&target->offset64);
reloc->offset = batch_offset;
reloc->delta = target_offset;
reloc->target_handle = target->gem_handle;