summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/intel
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-02-20 13:23:47 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2011-02-21 12:59:35 +0000
commitaac120977d1ead319141d48d65c9bba626ec03b8 (patch)
treed1ac3a43eb7d784883c6d8076cd3ca5b9bd53909 /src/mesa/drivers/dri/intel
parent8d68a90e225d831a395ba788e425cb717eec1f9a (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')
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.c68
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.h7
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h14
3 files changed, 74 insertions, 15 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.
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;