diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-02-08 20:01:10 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-02-21 12:59:34 +0000 |
commit | e476e122207e6195a16a8c7d2cab90eeba227934 (patch) | |
tree | 7c1a5f31a6078ffd7174f6a04816968f6fc3a382 /src/mesa/drivers/dri/intel/intel_buffer_objects.c | |
parent | d0809d7b15ba58c05bb0b63128c9cf7042304cd2 (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.c | 62 |
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 |