diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_batchbuffer.c | 38 | ||||
-rw-r--r-- | 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, |