From 1c9053d0765dc6372238e333dc5adca3e175b210 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 5 Apr 2018 01:37:31 -0700 Subject: [PATCH] i965: Prepare batchbuffer module for softpin support. If EXEC_OBJECT_PINNED is set, we don't want to emit any relocations. We simply want to add the BO to the validation list, and possibly mark it as writeable. The new brw_use_pinned_bo() interface does just that. To avoid having to make every caller consider both the relocation and softpin cases, we make emit_reloc() call brw_use_pinned_bo() when given a softpinned buffer. We also can't grow buffers that are softpinned - the mechanism places a larger BO at the same offset as the original, which requires moving BOs around in the VMA. With softpin, we only allocate enough VMA for the original size of the BO. v2: Assert that BOs aren't pinned if the kernel says we should move them (feedback from Chris Wilson) Reviewed-by: Scott D Phillips --- src/mesa/drivers/dri/i965/intel_batchbuffer.c | 38 +++++++++++++++++-- src/mesa/drivers/dri/i965/intel_batchbuffer.h | 4 ++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c index f51edf92346..df999ffeb1d 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -232,6 +232,10 @@ recreate_growing_buffer(struct brw_context *brw, struct intel_batchbuffer *batch = &brw->batch; struct brw_bufmgr *bufmgr = screen->bufmgr; + /* We can't grow buffers when using softpin, so just overallocate them. */ + if (brw_using_softpin(bufmgr)) + size *= 2; + grow->bo = brw_bo_alloc(bufmgr, name, size, memzone); grow->bo->kflags |= can_do_exec_capture(screen) ? EXEC_OBJECT_CAPTURE : 0; grow->partial_bo = NULL; @@ -382,6 +386,13 @@ grow_buffer(struct brw_context *brw, struct brw_bufmgr *bufmgr = brw->bufmgr; struct brw_bo *bo = grow->bo; + /* We can't grow buffers that are softpinned, as the growing mechanism + * involves putting a larger buffer at the same gtt_offset...and we've + * only allocated the smaller amount of VMA. Without relocations, this + * simply won't work. This should never happen, however. + */ + assert(!(bo->kflags & EXEC_OBJECT_PINNED)); + perf_debug("Growing %s - ran out of space\n", bo->name); if (grow->partial_bo) { @@ -709,6 +720,7 @@ execbuffer(int fd, /* Update brw_bo::gtt_offset */ if (batch->validation_list[i].offset != bo->gtt_offset) { + assert(!(bo->kflags & EXEC_OBJECT_PINNED)); DBG("BO %d migrated: 0x%" PRIx64 " -> 0x%llx\n", bo->gem_handle, bo->gtt_offset, batch->validation_list[i].offset); @@ -908,6 +920,14 @@ emit_reloc(struct intel_batchbuffer *batch, { assert(target != NULL); + if (target->kflags & EXEC_OBJECT_PINNED) { + brw_use_pinned_bo(batch, target, reloc_flags & RELOC_WRITE); + return target->gtt_offset + target_offset; + } + + unsigned int index = add_exec_bo(batch, target); + struct drm_i915_gem_exec_object2 *entry = &batch->validation_list[index]; + if (rlist->reloc_count == rlist->reloc_array_size) { rlist->reloc_array_size *= 2; rlist->relocs = realloc(rlist->relocs, @@ -915,9 +935,6 @@ emit_reloc(struct intel_batchbuffer *batch, sizeof(struct drm_i915_gem_relocation_entry)); } - unsigned int index = add_exec_bo(batch, target); - struct drm_i915_gem_exec_object2 *entry = &batch->validation_list[index]; - if (reloc_flags & RELOC_32BIT) { /* Restrict this buffer to the low 32 bits of the address space. * @@ -951,6 +968,21 @@ emit_reloc(struct intel_batchbuffer *batch, return entry->offset + target_offset; } +void +brw_use_pinned_bo(struct intel_batchbuffer *batch, struct brw_bo *bo, + unsigned writable_flag) +{ + assert(bo->kflags & EXEC_OBJECT_PINNED); + assert((writable_flag & ~EXEC_OBJECT_WRITE) == 0); + + unsigned int index = add_exec_bo(batch, bo); + struct drm_i915_gem_exec_object2 *entry = &batch->validation_list[index]; + assert(entry->offset == bo->gtt_offset); + + if (writable_flag) + entry->flags |= EXEC_OBJECT_WRITE; +} + uint64_t brw_batch_reloc(struct intel_batchbuffer *batch, uint32_t batch_offset, struct brw_bo *target, uint32_t target_offset, diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.h b/src/mesa/drivers/dri/i965/intel_batchbuffer.h index bd07bef9deb..d10948f1916 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.h @@ -53,6 +53,10 @@ bool brw_batch_references(struct intel_batchbuffer *batch, struct brw_bo *bo); #define RELOC_NEEDS_GGTT EXEC_OBJECT_NEEDS_GTT /* Inverted meaning, but using the same bit...emit_reloc will flip it. */ #define RELOC_32BIT EXEC_OBJECT_SUPPORTS_48B_ADDRESS + +void brw_use_pinned_bo(struct intel_batchbuffer *batch, struct brw_bo *bo, + unsigned writeable_flag); + uint64_t brw_batch_reloc(struct intel_batchbuffer *batch, uint32_t batch_offset, struct brw_bo *target, -- 2.30.2