summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/intel
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2008-07-23 09:17:07 -0700
committerEric Anholt <[email protected]>2008-07-23 10:21:25 -0700
commit2e3714380027252ba17a11f23eae851d3f77ab02 (patch)
treed65ba0bebfcc26e72258ac05848127fb535bc32c /src/mesa/drivers/dri/intel
parentd2d5abfaeb46fc7b4d4267a6c9e92420fc9b5334 (diff)
intel: Add a little span cache to spead up readpixels by cutting syscalls.
Diffstat (limited to 'src/mesa/drivers/dri/intel')
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c3
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.h3
-rw-r--r--src/mesa/drivers/dri/intel/intel_span.c48
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;