Avoid unrequired synchronization if the user requests to map an unused range on active buffer, equivalent to BufferSubData.
Signed-off-by: Chris Wilson <ch...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev