[Mesa-dev] [PATCH 11/18] i965: Track active GPU region from MapBufferRange
Chris Wilson
chris at chris-wilson.co.uk
Mon Jul 6 03:33:16 PDT 2015
Avoid unrequired synchronization if the user requests to map an unused
range on active buffer, equivalent to BufferSubData.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
src/mesa/drivers/dri/i965/intel_buffer_objects.c | 78 +++++++++++++-----------
1 file changed, 42 insertions(+), 36 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.c b/src/mesa/drivers/dri/i965/intel_buffer_objects.c
index fda5c9f..283182d 100644
--- a/src/mesa/drivers/dri/i965/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.c
@@ -330,44 +330,50 @@ brw_map_buffer_range(struct gl_context *ctx,
* If they set INVALIDATE_BUFFER, we can pitch the current contents to
* achieve the required synchronization.
*/
- if (!(access & GL_MAP_UNSYNCHRONIZED_BIT)) {
+ if (!(access & GL_MAP_UNSYNCHRONIZED_BIT) &&
+ brw_bo_busy(intel_obj->buffer, BUSY_WRITE | BUSY_RETIRE)) {
if ((access & GL_MAP_INVALIDATE_BUFFER_BIT)) {
- if (brw_bo_busy(intel_obj->buffer, BUSY_WRITE | BUSY_RETIRE)) {
- brw_bo_put(intel_obj->buffer);
- alloc_buffer_object(brw, intel_obj);
- }
- }
- }
+ brw_bo_put(intel_obj->buffer);
+ alloc_buffer_object(brw, intel_obj);
+ } else if (offset + length <= intel_obj->gpu_active_start ||
+ intel_obj->gpu_active_end <= offset) {
+ access |= GL_MAP_UNSYNCHRONIZED_BIT;
+ } else if (!(access & GL_MAP_PERSISTENT_BIT) &&
+ (access & GL_MAP_INVALIDATE_RANGE_BIT)) {
+ /* 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
+ * FlushRange time.
+ *
+ * That is, unless they're looking for a persistent mapping -- we
+ * would need to do blits in the MemoryBarrier call, and it's easier
+ * to just do a GPU stall and do a mapping.
+ */
- /* 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
- * FlushRange time.
- *
- * That is, unless they're looking for a persistent mapping -- we would
- * need to do blits in the MemoryBarrier call, and it's easier to just do a
- * GPU stall and do a mapping.
- */
- if (!(access & (GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_PERSISTENT_BIT)) &&
- (access & GL_MAP_INVALIDATE_RANGE_BIT) &&
- brw_bo_busy(intel_obj->buffer, BUSY_WRITE | BUSY_RETIRE)) {
- /* Ensure that the base alignment of the allocation meets the alignment
- * guarantees the driver has advertised to the application.
- */
- const unsigned alignment = ctx->Const.MinMapBufferAlignment;
-
- intel_obj->map_extra[index] = (uintptr_t) offset % alignment;
- intel_obj->range_map_bo[index] =
- brw_bo_create(&brw->batch,
- "BO blit temp",
- length + intel_obj->map_extra[index],
- alignment, 0);
-
- obj->Mappings[index].Pointer =
- brw_bo_map(intel_obj->range_map_bo[index], MAP_WRITE) +
- intel_obj->map_extra[index];
-
- return obj->Mappings[index].Pointer;
+ /* Ensure that the base alignment of the allocation meets the alignment
+ * guarantees the driver has advertised to the application.
+ */
+ const unsigned alignment = ctx->Const.MinMapBufferAlignment;
+
+ intel_obj->map_extra[index] = (uintptr_t) offset % alignment;
+ intel_obj->range_map_bo[index] =
+ brw_bo_create(&brw->batch,
+ "BO blit temp",
+ length + intel_obj->map_extra[index],
+ alignment, 0);
+
+ obj->Mappings[index].Pointer =
+ brw_bo_map(intel_obj->range_map_bo[index], MAP_WRITE) +
+ intel_obj->map_extra[index];
+
+ return obj->Mappings[index].Pointer;
+ } else {
+ perf_debug("Stalling on glBufferMapRange(%ld, %ld) (%ldkb) to a busy "
+ "(%d-%d) buffer object.\n",
+ (long)offset, (long)offset + length, (long)(length/1024),
+ intel_obj->gpu_active_start,
+ intel_obj->gpu_active_end);
+ }
}
map_flags = 0;
--
2.1.4
More information about the mesa-dev
mailing list