diff options
author | Eric Anholt <[email protected]> | 2008-07-23 09:17:07 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2008-07-23 10:21:25 -0700 |
commit | 2e3714380027252ba17a11f23eae851d3f77ab02 (patch) | |
tree | d65ba0bebfcc26e72258ac05848127fb535bc32c /src/mesa/drivers | |
parent | d2d5abfaeb46fc7b4d4267a6c9e92420fc9b5334 (diff) |
intel: Add a little span cache to spead up readpixels by cutting syscalls.
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_fbo.c | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_fbo.h | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_span.c | 48 |
3 files changed, 42 insertions, 12 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index d539097a66f..254f3efae0c 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -153,6 +153,9 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb) intel_unpair_depth_stencil(ctx, irb); } + if (irb->span_cache != NULL) + _mesa_free(irb->span_cache); + if (intel && irb->region) { intel_region_release(&irb->region); } diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h index f55d3747f24..9d15582d78c 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.h +++ b/src/mesa/drivers/dri/intel/intel_fbo.h @@ -79,6 +79,9 @@ struct intel_renderbuffer GLuint pf_pending; /**< sequence number of pending flip */ GLuint vbl_pending; /**< vblank sequence number of pending flip */ + + uint8_t *span_cache; + unsigned long span_cache_offset; }; extern struct intel_renderbuffer *intel_renderbuffer(struct gl_renderbuffer diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index 44e2eff680f..06f7c9b4b7d 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -43,51 +43,74 @@ static void intel_set_span_functions(struct intel_context *intel, struct gl_renderbuffer *rb); +#define SPAN_CACHE_SIZE 4096 + +static void +get_span_cache(struct intel_renderbuffer *irb, uint32_t offset) +{ + if (irb->span_cache == NULL) { + irb->span_cache = _mesa_malloc(SPAN_CACHE_SIZE); + irb->span_cache_offset = -1; + } + + if ((offset & ~(SPAN_CACHE_SIZE - 1)) != irb->span_cache_offset) { + irb->span_cache_offset = offset & ~(SPAN_CACHE_SIZE - 1); + dri_bo_get_subdata(irb->region->buffer, irb->span_cache_offset, + SPAN_CACHE_SIZE, irb->span_cache); + } +} + +static void +clear_span_cache(struct intel_renderbuffer *irb) +{ + irb->span_cache_offset = -1; +} + static uint32_t pread_32(struct intel_renderbuffer *irb, uint32_t offset) { - uint32_t val; + get_span_cache(irb, offset); - dri_bo_get_subdata(irb->region->buffer, offset, 4, &val); - - return val; + return *(uint32_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1))); } static uint16_t pread_16(struct intel_renderbuffer *irb, uint32_t offset) { - uint16_t val; - - dri_bo_get_subdata(irb->region->buffer, offset, 2, &val); + get_span_cache(irb, offset); - return val; + return *(uint16_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1))); } static uint8_t pread_8(struct intel_renderbuffer *irb, uint32_t offset) { - uint8_t val; + get_span_cache(irb, offset); - dri_bo_get_subdata(irb->region->buffer, offset, 1, &val); - - return val; + return *(uint8_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1))); } static void pwrite_32(struct intel_renderbuffer *irb, uint32_t offset, uint32_t val) { + clear_span_cache(irb); + dri_bo_subdata(irb->region->buffer, offset, 4, &val); } static void pwrite_16(struct intel_renderbuffer *irb, uint32_t offset, uint16_t val) { + clear_span_cache(irb); + dri_bo_subdata(irb->region->buffer, offset, 2, &val); } static void pwrite_8(struct intel_renderbuffer *irb, uint32_t offset, uint8_t val) { + clear_span_cache(irb); + dri_bo_subdata(irb->region->buffer, offset, 1, &val); } @@ -481,6 +504,7 @@ intel_renderbuffer_unmap(struct intel_context *intel, if (irb == NULL || irb->region == NULL) return; + clear_span_cache(irb); irb->pfPitch = 0; rb->GetRow = NULL; |