intel: Add a little span cache to spead up readpixels by cutting syscalls.
authorEric Anholt <eric@anholt.net>
Wed, 23 Jul 2008 16:17:07 +0000 (09:17 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 23 Jul 2008 17:21:25 +0000 (10:21 -0700)
src/mesa/drivers/dri/intel/intel_fbo.c
src/mesa/drivers/dri/intel/intel_fbo.h
src/mesa/drivers/dri/intel/intel_span.c

index d539097a66f6cc2b15d7df1efea430743fb0bf60..254f3efae0cb87070fb46ea58e9139a56c0f5a64 100644 (file)
@@ -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);
    }
index f55d3747f24e662e731d7c6dd39bd96274922da4..9d15582d78c8d1da410a3f83ce8bf4b3b3a2e6b0 100644 (file)
@@ -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
index 44e2eff680f1579e546490f32af7c5d274fd5f6b..06f7c9b4b7de28c33d05cf2a4ebd39b61497a364 100644 (file)
@@ -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;