From aac120977d1ead319141d48d65c9bba626ec03b8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 20 Feb 2011 13:23:47 +0000 Subject: i965: Move repeat-instruction-suppression to batchbuffer core Move the tracking of the last emitted instructions into the core batchbuffer routines and take advantage of the shadow batch copy to avoid extra memory allocations and copies. Signed-off-by: Chris Wilson --- src/mesa/drivers/dri/intel/intel_batchbuffer.c | 68 +++++++++++++++++++++++++- src/mesa/drivers/dri/intel/intel_batchbuffer.h | 7 ++- src/mesa/drivers/dri/intel/intel_context.h | 14 ++---- 3 files changed, 74 insertions(+), 15 deletions(-) (limited to 'src/mesa/drivers/dri/intel') diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c index 7d224ae535..805f3a34e8 100644 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c @@ -33,6 +33,25 @@ #include "intel_bufmgr.h" #include "intel_buffers.h" +struct cached_batch_item { + struct cached_batch_item *next; + uint16_t header; + uint16_t size; +}; + +static void clear_cache( struct intel_context *intel ) +{ + struct cached_batch_item *item = intel->batch.cached_items; + + while (item) { + struct cached_batch_item *next = item->next; + free(item); + item = next; + } + + intel->batch.cached_items = NULL; +} + void intel_batchbuffer_reset(struct intel_context *intel) { @@ -40,6 +59,7 @@ intel_batchbuffer_reset(struct intel_context *intel) drm_intel_bo_unreference(intel->batch.bo); intel->batch.bo = NULL; } + clear_cache(intel); intel->batch.bo = drm_intel_bo_alloc(intel->bufmgr, "batchbuffer", intel->maxBatchSize, 4096); @@ -53,6 +73,7 @@ void intel_batchbuffer_free(struct intel_context *intel) { drm_intel_bo_unreference(intel->batch.bo); + clear_cache(intel); } @@ -165,7 +186,8 @@ intel_batchbuffer_emit_reloc(struct intel_context *intel, ret = drm_intel_bo_emit_reloc(intel->batch.bo, 4*intel->batch.used, buffer, delta, read_domains, write_domain); - assert (ret == 0); + assert(ret == 0); + (void)ret; /* * Using the old buffer offset, write in what the right data would be, in case @@ -191,7 +213,8 @@ intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel, ret = drm_intel_bo_emit_reloc_fence(intel->batch.bo, 4*intel->batch.used, buffer, delta, read_domains, write_domain); - assert (ret == 0); + assert(ret == 0); + (void)ret; /* * Using the old buffer offset, write in what the right data would @@ -213,6 +236,47 @@ intel_batchbuffer_data(struct intel_context *intel, intel->batch.used += bytes >> 2; } +void +intel_batchbuffer_cached_advance(struct intel_context *intel) +{ + struct cached_batch_item **prev = &intel->batch.cached_items, *item; + uint32_t sz = (intel->batch.used - intel->batch.emit) * sizeof(uint32_t); + uint32_t *start = intel->batch.map + intel->batch.emit; + uint16_t op = *start >> 16; + + while (*prev) { + uint32_t *old; + + item = *prev; + old = intel->batch.map + item->header; + if (op == *old >> 16) { + if (item->size == sz && memcmp(old, start, sz) == 0) { + if (prev != &intel->batch.cached_items) { + *prev = item->next; + item->next = intel->batch.cached_items; + intel->batch.cached_items = item; + } + intel->batch.used = intel->batch.emit; + return; + } + + goto emit; + } + prev = &item->next; + } + + item = malloc(sizeof(struct cached_batch_item)); + if (item == NULL) + return; + + item->next = intel->batch.cached_items; + intel->batch.cached_items = item; + +emit: + item->size = sz; + item->header = intel->batch.emit; +} + /* Emit a pipelined flush to either flush render and texture cache for * reading from a FBO-drawn texture, or flush so that frontbuffer * render appears on the screen in DRI1. diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h index 7699715c0e..a0a5c9841c 100644 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.h @@ -101,9 +101,9 @@ intel_batchbuffer_begin(struct intel_context *intel, int n, bool is_blit) { intel_batchbuffer_require_space(intel, n * 4, is_blit); + intel->batch.emit = intel->batch.used; #ifdef DEBUG - intel->batch.emit.total = n; - intel->batch.emit.start_ptr = intel->batch.used; + intel->batch.total = n; #endif } @@ -123,6 +123,8 @@ intel_batchbuffer_advance(struct intel_context *intel) #endif } +void intel_batchbuffer_cached_advance(struct intel_context *intel); + /* Here are the crusty old macros, to be removed: */ #define BATCH_LOCALS @@ -141,5 +143,6 @@ intel_batchbuffer_advance(struct intel_context *intel) } while (0) #define ADVANCE_BATCH() intel_batchbuffer_advance(intel); +#define CACHED_BATCH() intel_batchbuffer_cached_advance(intel); #endif diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index bf2a0b4ead..6116764ad6 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -171,22 +171,14 @@ struct intel_context struct intel_batchbuffer { drm_intel_bo *bo; + struct cached_batch_item *cached_items; - uint16_t used; - uint16_t reserved_space; + uint16_t emit, total; + uint16_t used, reserved_space; uint32_t map[8192]; #define BATCH_SZ (8192*sizeof(uint32_t)) uint32_t state_batch_offset; - -#ifdef DEBUG - /** Tracking of BEGIN_BATCH()/OUT_BATCH()/ADVANCE_BATCH() debugging */ - struct { - uint16_t total; - uint16_t start_ptr; - } emit; -#endif - bool is_blit; } batch; -- cgit v1.2.3