summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/intel/intel_buffer_objects.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-02-08 20:01:10 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2011-02-21 12:59:34 +0000
commite476e122207e6195a16a8c7d2cab90eeba227934 (patch)
tree7c1a5f31a6078ffd7174f6a04816968f6fc3a382 /src/mesa/drivers/dri/intel/intel_buffer_objects.c
parentd0809d7b15ba58c05bb0b63128c9cf7042304cd2 (diff)
intel: Pack dynamic draws together
Dynamic arrays have the tendency to be small and so allocating a bo for each one is overkill and we can exploit many efficiency gains by packing them together. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/mesa/drivers/dri/intel/intel_buffer_objects.c')
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.c62
1 files changed, 55 insertions, 7 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index 62e8d822c2..f54fc1a12b 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -528,7 +528,8 @@ intel_bufferobj_unmap(struct gl_context * ctx,
drm_intel_bo *
intel_bufferobj_buffer(struct intel_context *intel,
- struct intel_buffer_object *intel_obj, GLuint flag)
+ struct intel_buffer_object *intel_obj,
+ GLuint flag)
{
if (intel_obj->region) {
if (flag == INTEL_WRITE_PART)
@@ -539,19 +540,65 @@ intel_bufferobj_buffer(struct intel_context *intel,
}
}
+ if (intel_obj->source) {
+ drm_intel_bo_unreference(intel_obj->buffer);
+ intel_obj->buffer = NULL;
+ intel_obj->source = 0;
+ }
+
if (intel_obj->buffer == NULL) {
- /* XXX suballocate for DYNAMIC READ */
intel_bufferobj_alloc_buffer(intel, intel_obj);
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;
+ free(intel_obj->sys_buffer);
+ intel_obj->sys_buffer = NULL;
+ intel_obj->offset = 0;
+ }
+
+ return intel_obj->buffer;
+}
+
+#define INTEL_UPLOAD_SIZE (64*1024)
+
+static void wrap_buffers(struct intel_context *intel, GLuint size)
+{
+ if (size < INTEL_UPLOAD_SIZE)
+ size = INTEL_UPLOAD_SIZE;
+
+ if (intel->upload.bo != NULL)
+ drm_intel_bo_unreference(intel->upload.bo);
+
+ intel->upload.bo = drm_intel_bo_alloc(intel->bufmgr, "upload", size, 0);
+ intel->upload.offset = 0;
+}
+
+drm_intel_bo *
+intel_bufferobj_source(struct intel_context *intel,
+ struct intel_buffer_object *intel_obj,
+ GLuint *offset)
+{
+ if (intel_obj->buffer == NULL) {
+ GLuint size = ALIGN(intel_obj->Base.Size, 64);
+
+ if (intel->upload.bo == NULL ||
+ intel->upload.offset + size > intel->upload.bo->size) {
+ wrap_buffers(intel, size);
}
+
+ drm_intel_bo_reference(intel->upload.bo);
+ intel_obj->buffer = intel->upload.bo;
+ intel_obj->offset = intel->upload.offset;
+ intel_obj->source = 1;
+ intel->upload.offset += size;
+
+ drm_intel_bo_subdata(intel_obj->buffer,
+ intel_obj->offset, intel_obj->Base.Size,
+ intel_obj->sys_buffer);
}
+ *offset = intel_obj->offset;
return intel_obj->buffer;
}
@@ -566,6 +613,7 @@ intel_bufferobj_copy_subdata(struct gl_context *ctx,
struct intel_buffer_object *intel_src = intel_buffer_object(src);
struct intel_buffer_object *intel_dst = intel_buffer_object(dst);
drm_intel_bo *src_bo, *dst_bo;
+ GLuint src_offset;
if (size == 0)
return;
@@ -600,11 +648,11 @@ intel_bufferobj_copy_subdata(struct gl_context *ctx,
/* Otherwise, we have real BOs, so blit them. */
dst_bo = intel_bufferobj_buffer(intel, intel_dst, INTEL_WRITE_PART);
- src_bo = intel_bufferobj_buffer(intel, intel_src, INTEL_READ);
+ src_bo = intel_bufferobj_source(intel, intel_src, &src_offset);
intel_emit_linear_blit(intel,
dst_bo, write_offset,
- src_bo, read_offset, size);
+ src_bo, read_offset + src_offset, size);
/* 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