aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2017-01-17 17:18:01 -0800
committerKenneth Graunke <[email protected]>2017-07-13 16:58:17 -0700
commit5f223648f2e821afa76f872cbcaecd703a16fdb1 (patch)
tree74b09d429888a29ac03be3c80c8a9454ee71bf65
parentf47612dafb3479c6e1ea90801ab17fe1e8eac778 (diff)
i965: Track a range of the buffer which contains valid data.
Reviewed-by: Chris Wilson <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/intel_buffer_objects.c41
-rw-r--r--src/mesa/drivers/dri/i965/intel_buffer_objects.h11
2 files changed, 48 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.c b/src/mesa/drivers/dri/i965/intel_buffer_objects.c
index c1ee16c9f68..ff73a37d608 100644
--- a/src/mesa/drivers/dri/i965/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.c
@@ -54,6 +54,21 @@ mark_buffer_inactive(struct intel_buffer_object *intel_obj)
intel_obj->gpu_active_end = 0;
}
+static void
+mark_buffer_valid_data(struct intel_buffer_object *intel_obj,
+ uint32_t offset, uint32_t size)
+{
+ intel_obj->valid_data_start = MIN2(intel_obj->valid_data_start, offset);
+ intel_obj->valid_data_end = MAX2(intel_obj->valid_data_end, offset + size);
+}
+
+static void
+mark_buffer_invalid(struct intel_buffer_object *intel_obj)
+{
+ intel_obj->valid_data_start = ~0;
+ intel_obj->valid_data_end = 0;
+}
+
/** Allocates a new brw_bo to store the data for the buffer object. */
static void
alloc_buffer_object(struct brw_context *brw,
@@ -74,6 +89,7 @@ alloc_buffer_object(struct brw_context *brw,
brw->ctx.NewDriverState |= BRW_NEW_ATOMIC_BUFFER;
mark_buffer_inactive(intel_obj);
+ mark_buffer_invalid(intel_obj);
}
static void
@@ -173,8 +189,10 @@ brw_buffer_data(struct gl_context *ctx,
if (!intel_obj->buffer)
return false;
- if (data != NULL)
+ if (data != NULL) {
brw_bo_subdata(intel_obj->buffer, 0, size, data);
+ mark_buffer_valid_data(intel_obj, 0, size);
+ }
}
return true;
@@ -223,6 +241,8 @@ brw_buffer_subdata(struct gl_context *ctx,
if (intel_obj->gpu_active_end > intel_obj->gpu_active_start)
intel_obj->prefer_stall_to_blit = true;
+
+ mark_buffer_valid_data(intel_obj, offset, size);
return;
}
@@ -231,17 +251,21 @@ brw_buffer_subdata(struct gl_context *ctx,
brw_batch_references(&brw->batch, intel_obj->buffer);
if (busy) {
- if (size == intel_obj->Base.Size) {
+ if (size == intel_obj->Base.Size ||
+ (intel_obj->valid_data_start >= offset &&
+ intel_obj->valid_data_end <= offset + size)) {
/* Replace the current busy bo so the subdata doesn't stall. */
brw_bo_unreference(intel_obj->buffer);
alloc_buffer_object(brw, intel_obj);
} else if (!intel_obj->prefer_stall_to_blit) {
perf_debug("Using a blit copy to avoid stalling on "
"glBufferSubData(%ld, %ld) (%ldkb) to a busy "
- "(%d-%d) buffer object.\n",
+ "(%d-%d) / valid (%d-%d) buffer object.\n",
(long)offset, (long)offset + size, (long)(size/1024),
intel_obj->gpu_active_start,
- intel_obj->gpu_active_end);
+ intel_obj->gpu_active_end,
+ intel_obj->valid_data_start,
+ intel_obj->valid_data_end);
struct brw_bo *temp_bo =
brw_bo_alloc(brw->bufmgr, "subdata temp", size, 64);
@@ -253,6 +277,7 @@ brw_buffer_subdata(struct gl_context *ctx,
size);
brw_bo_unreference(temp_bo);
+ mark_buffer_valid_data(intel_obj, offset, size);
return;
} else {
perf_debug("Stalling on glBufferSubData(%ld, %ld) (%ldkb) to a busy "
@@ -267,6 +292,7 @@ brw_buffer_subdata(struct gl_context *ctx,
brw_bo_subdata(intel_obj->buffer, offset, size, data);
mark_buffer_inactive(intel_obj);
+ mark_buffer_valid_data(intel_obj, offset, size);
}
@@ -378,6 +404,9 @@ brw_map_buffer_range(struct gl_context *ctx,
}
}
+ if (access & MAP_WRITE)
+ mark_buffer_valid_data(intel_obj, offset, length);
+
/* If the user is mapping a range of an active buffer object but
* doesn't require the current contents of that range, make a new
* BO, and we'll copy what they put in there out at unmap or
@@ -551,6 +580,10 @@ intel_bufferobj_buffer(struct brw_context *brw,
mark_buffer_gpu_usage(intel_obj, offset, size);
+ /* If writing, (conservatively) mark this section as having valid data. */
+ if (write)
+ mark_buffer_valid_data(intel_obj, offset, size);
+
return intel_obj->buffer;
}
diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.h b/src/mesa/drivers/dri/i965/intel_buffer_objects.h
index 6058d824fee..3b46d5c9c81 100644
--- a/src/mesa/drivers/dri/i965/intel_buffer_objects.h
+++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.h
@@ -70,6 +70,17 @@ struct intel_buffer_object
uint32_t gpu_active_start;
uint32_t gpu_active_end;
+ /** @{
+ * Tracking for what range of the BO may contain valid data.
+ *
+ * Users may create a large buffer object and only fill part of it
+ * with valid data. This is a conservative estimate of what part
+ * of the buffer contains valid data that we have to preserve.
+ */
+ uint32_t valid_data_start;
+ uint32_t valid_data_end;
+ /** @} */
+
/**
* If we've avoided stalls/blits using the active tracking, flag the buffer
* for (occasional) stalling in the future to avoid getting stuck in a