summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i965/intel_batchbuffer.c38
-rw-r--r--src/mesa/drivers/dri/i965/intel_batchbuffer.h4
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,