[Mesa-dev] [PATCH 1/2] intel: Avoid double copy with MapBufferRange's explicit flushing case.
Kenneth Graunke
kenneth at whitecape.org
Sun Oct 28 13:36:50 PDT 2012
When mapping a buffer object with GL_MAP_INVALIDATE_RANGE_BIT and
GL_MAP_FLUSH_EXPLICIT_BIT and encountering a busy BO, we malloc'd
a temporary buffer. Then, on FlushMappedBufferRange, we'd allocate
a second temporary BO, immediately pwrite the data to that (copy #1),
then use the BLT ring to write it into the original buffer (copy #2).
This is unnecessary. Just use a BO in the first place, like the
non-explicit-flushing case, and set a flag to control when we should
do the linear blit.
Cc: Eric Anholt <eric at anholt.net>
Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
src/mesa/drivers/dri/intel/intel_buffer_objects.c | 52 ++++++++---------------
src/mesa/drivers/dri/intel/intel_buffer_objects.h | 2 +-
2 files changed, 18 insertions(+), 36 deletions(-)
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index f94c6f5..bfbad63 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -346,21 +346,17 @@ intel_bufferobj_map_range(struct gl_context * ctx,
*/
if ((access & GL_MAP_INVALIDATE_RANGE_BIT) &&
drm_intel_bo_busy(intel_obj->buffer)) {
- if (access & GL_MAP_FLUSH_EXPLICIT_BIT) {
- intel_obj->range_map_buffer = malloc(length);
- obj->Pointer = intel_obj->range_map_buffer;
+ intel_obj->explicit_flush = access & GL_MAP_FLUSH_EXPLICIT_BIT;
+ intel_obj->range_map_bo = drm_intel_bo_alloc(intel->bufmgr,
+ "range map",
+ length, 64);
+ if (!(access & GL_MAP_READ_BIT)) {
+ drm_intel_gem_bo_map_gtt(intel_obj->range_map_bo);
} else {
- intel_obj->range_map_bo = drm_intel_bo_alloc(intel->bufmgr,
- "range map",
- length, 64);
- if (!(access & GL_MAP_READ_BIT)) {
- drm_intel_gem_bo_map_gtt(intel_obj->range_map_bo);
- } else {
- drm_intel_bo_map(intel_obj->range_map_bo,
- (access & GL_MAP_WRITE_BIT) != 0);
- }
- obj->Pointer = intel_obj->range_map_bo->virtual;
+ drm_intel_bo_map(intel_obj->range_map_bo,
+ (access & GL_MAP_WRITE_BIT) != 0);
}
+ obj->Pointer = intel_obj->range_map_bo->virtual;
return obj->Pointer;
}
@@ -388,27 +384,20 @@ intel_bufferobj_flush_mapped_range(struct gl_context *ctx,
{
struct intel_context *intel = intel_context(ctx);
struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
- drm_intel_bo *temp_bo;
/* Unless we're in the range map using a temporary system buffer,
* there's no work to do.
*/
- if (intel_obj->range_map_buffer == NULL)
+ if (!intel_obj->explicit_flush)
return;
if (length == 0)
return;
- temp_bo = drm_intel_bo_alloc(intel->bufmgr, "range map flush", length, 64);
-
- drm_intel_bo_subdata(temp_bo, 0, length, intel_obj->range_map_buffer);
-
intel_emit_linear_blit(intel,
intel_obj->buffer, obj->Offset + offset,
- temp_bo, 0,
+ intel_obj->range_map_bo, 0,
length);
-
- drm_intel_bo_unreference(temp_bo);
}
@@ -425,22 +414,15 @@ intel_bufferobj_unmap(struct gl_context * ctx, struct gl_buffer_object *obj)
assert(obj->Pointer);
if (intel_obj->sys_buffer != NULL) {
/* always keep the mapping around. */
- } else if (intel_obj->range_map_buffer != NULL) {
- /* Since we've emitted some blits to buffers that will (likely) be used
- * in rendering operations in other cache domains in this batch, emit a
- * flush. Once again, we wish for a domain tracker in libdrm to cover
- * usage inside of a batchbuffer.
- */
- intel_batchbuffer_emit_mi_flush(intel);
- free(intel_obj->range_map_buffer);
- intel_obj->range_map_buffer = NULL;
} else if (intel_obj->range_map_bo != NULL) {
drm_intel_bo_unmap(intel_obj->range_map_bo);
- intel_emit_linear_blit(intel,
- intel_obj->buffer, obj->Offset,
- intel_obj->range_map_bo, 0,
- obj->Length);
+ if (!intel_obj->explicit_flush) {
+ intel_emit_linear_blit(intel,
+ intel_obj->buffer, obj->Offset,
+ intel_obj->range_map_bo, 0,
+ obj->Length);
+ }
/* Since we've emitted some blits to buffers that will (likely) be used
* in rendering operations in other cache domains in this batch, emit a
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.h b/src/mesa/drivers/dri/intel/intel_buffer_objects.h
index 92a4121..ef66fb2 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.h
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.h
@@ -47,7 +47,7 @@ struct intel_buffer_object
void *sys_buffer;
drm_intel_bo *range_map_bo;
- void *range_map_buffer;
+ bool explicit_flush;
unsigned int range_map_offset;
GLsizei range_map_size;
--
1.8.0
More information about the mesa-dev
mailing list