diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-02-20 13:23:47 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-02-21 12:59:35 +0000 |
commit | aac120977d1ead319141d48d65c9bba626ec03b8 (patch) | |
tree | d1ac3a43eb7d784883c6d8076cd3ca5b9bd53909 /src/mesa/drivers/dri/intel/intel_batchbuffer.c | |
parent | 8d68a90e225d831a395ba788e425cb717eec1f9a (diff) |
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 <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/mesa/drivers/dri/intel/intel_batchbuffer.c')
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_batchbuffer.c | 68 |
1 files changed, 66 insertions, 2 deletions
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. |