summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;