summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <[email protected]>2011-02-08 16:57:26 +0000
committerChris Wilson <[email protected]>2011-02-21 12:59:34 +0000
commitd0809d7b15ba58c05bb0b63128c9cf7042304cd2 (patch)
treef1b3f8f6b85f7ab0cd9bcbd221245950b4202e63
parent45ba7afbd15b28ffd61548ee46334ff4527a7cde (diff)
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 <[email protected]>
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.c51
1 files 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 d917161c4be..62e8d822c2a 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;