From d0809d7b15ba58c05bb0b63128c9cf7042304cd2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 8 Feb 2011 16:57:26 +0000 Subject: [PATCH] intel: Use system memory for DYNAMIC_DRAW source objects Dynamic draw buffers are used by clients for temporary arrays and for uploading normal vertex arrays. By keeping the data in memory, we can avoid reusing active buffer objects and reallocate them as they are changed. This is important for Sandybridge which can not issue blits within a batch and so ends up flushing the batch upon every update, that is each batch only contains a single draw operation (if using dynamic arrays or regular arrays from system memory). Signed-off-by: Chris Wilson --- src/mesa/drivers/dri/intel/intel_buffer_objects.c | 51 ++++++++++++++--------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index d917161..62e8d82 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -162,11 +162,15 @@ intel_bufferobj_data(struct gl_context * ctx, intel_obj->sys_buffer = NULL; if (size != 0) { + if (usage == GL_DYNAMIC_DRAW #ifdef I915 - /* On pre-965, stick VBOs in system memory, as we're always doing swtnl - * with their contents anyway. - */ - if (target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER) { + /* On pre-965, stick VBOs in system memory, as we're always doing + * swtnl with their contents anyway. + */ + || target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER +#endif + ) + { intel_obj->sys_buffer = malloc(size); if (intel_obj->sys_buffer != NULL) { if (data != NULL) @@ -174,7 +178,6 @@ intel_bufferobj_data(struct gl_context * ctx, return GL_TRUE; } } -#endif intel_bufferobj_alloc_buffer(intel, intel_obj); if (!intel_obj->buffer) return GL_FALSE; @@ -211,9 +214,13 @@ intel_bufferobj_subdata(struct gl_context * ctx, if (intel_obj->region) intel_bufferobj_cow(intel, intel_obj); - if (intel_obj->sys_buffer) + if (intel_obj->sys_buffer) { + if (intel_obj->buffer) { + drm_intel_bo_unreference(intel_obj->buffer); + intel_obj->buffer = NULL; + } memcpy((char *)intel_obj->sys_buffer + offset, data, size); - else { + } else { /* Flush any existing batchbuffer that might reference this data. */ if (intel->gen < 6) { if (drm_intel_bo_busy(intel_obj->buffer) || @@ -280,6 +287,10 @@ intel_bufferobj_map(struct gl_context * ctx, assert(intel_obj); if (intel_obj->sys_buffer) { + if (!read_only && intel_obj->buffer) { + drm_intel_bo_unreference(intel_obj->buffer); + intel_obj->buffer = NULL; + } obj->Pointer = intel_obj->sys_buffer; obj->Length = obj->Size; obj->Offset = 0; @@ -347,6 +358,10 @@ intel_bufferobj_map_range(struct gl_context * ctx, obj->AccessFlags = access; if (intel_obj->sys_buffer) { + if (access != GL_READ_ONLY_ARB && intel_obj->buffer) { + drm_intel_bo_unreference(intel_obj->buffer); + intel_obj->buffer = NULL; + } obj->Pointer = intel_obj->sys_buffer + offset; return obj->Pointer; } @@ -525,20 +540,16 @@ intel_bufferobj_buffer(struct intel_context *intel, } if (intel_obj->buffer == NULL) { - void *sys_buffer = intel_obj->sys_buffer; - - /* only one of buffer and sys_buffer could be non-NULL */ + /* XXX suballocate for DYNAMIC READ */ intel_bufferobj_alloc_buffer(intel, intel_obj); - intel_obj->sys_buffer = NULL; - - intel_bufferobj_subdata(&intel->ctx, - GL_ARRAY_BUFFER_ARB, - 0, - intel_obj->Base.Size, - sys_buffer, - &intel_obj->Base); - free(sys_buffer); - intel_obj->sys_buffer = NULL; + drm_intel_bo_subdata(intel_obj->buffer, + 0, intel_obj->Base.Size, + intel_obj->sys_buffer); + + if (flag != INTEL_READ) { + free(intel_obj->sys_buffer); + intel_obj->sys_buffer = NULL; + } } return intel_obj->buffer; -- 2.7.4