diff options
| author | Eric Anholt <eric@anholt.net> | 2008-07-23 09:17:07 -0700 | 
|---|---|---|
| committer | Eric Anholt <eric@anholt.net> | 2008-07-23 10:21:25 -0700 | 
| commit | 2e3714380027252ba17a11f23eae851d3f77ab02 (patch) | |
| tree | d65ba0bebfcc26e72258ac05848127fb535bc32c | |
| parent | d2d5abfaeb46fc7b4d4267a6c9e92420fc9b5334 (diff) | |
intel: Add a little span cache to spead up readpixels by cutting syscalls.
| -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 d539097a66..254f3efae0 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 f55d3747f2..9d15582d78 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 44e2eff680..06f7c9b4b7 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; | 
