summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_state_batch.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-03-11 14:33:00 -0800
committerEric Anholt <eric@anholt.net>2010-06-11 00:15:56 -0700
commit321014156b3f7842a84d9b9915389c9f6f6486f5 (patch)
tree2b0b4c7d266ca968e438014b16802c030c09d589 /src/mesa/drivers/dri/i965/brw_state_batch.c
parentf5bb775fd1f333d8e579d07a5cac1ded2bd54a2f (diff)
downloadexternal_mesa3d-321014156b3f7842a84d9b9915389c9f6f6486f5.zip
external_mesa3d-321014156b3f7842a84d9b9915389c9f6f6486f5.tar.gz
external_mesa3d-321014156b3f7842a84d9b9915389c9f6f6486f5.tar.bz2
i965: Add support for streaming indirect state rather than caching objects.
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_state_batch.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_batch.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_state_batch.c b/src/mesa/drivers/dri/i965/brw_state_batch.c
index 3901941..be3989e 100644
--- a/src/mesa/drivers/dri/i965/brw_state_batch.c
+++ b/src/mesa/drivers/dri/i965/brw_state_batch.c
@@ -97,3 +97,52 @@ void brw_destroy_batch_cache( struct brw_context *brw )
{
brw_clear_batch_cache(brw);
}
+
+/**
+ * Allocates a block of space in the batchbuffer for indirect state.
+ *
+ * We don't want to allocate separate BOs for every bit of indirect
+ * state in the driver. It means overallocating by a significant
+ * margin (4096 bytes, even if the object is just a 20-byte surface
+ * state), and more buffers to walk and count for aperture size checking.
+ *
+ * However, due to the restrictions inposed by the aperture size
+ * checking performance hacks, we can't have the batch point at a
+ * separate indirect state buffer, because once the batch points at
+ * it, no more relocations can be added to it. So, we sneak these
+ * buffers in at the top of the batchbuffer.
+ */
+void *
+brw_state_batch(struct brw_context *brw,
+ int size,
+ int alignment,
+ drm_intel_bo **out_bo,
+ uint32_t *out_offset)
+{
+ struct intel_batchbuffer *batch = brw->intel.batch;
+ uint32_t offset;
+
+ assert(size < batch->buf->size);
+ offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment);
+
+ /* If allocating from the top would wrap below the batchbuffer, or
+ * if the batch's used space (plus the reserved pad) collides with our
+ * space, then flush and try again.
+ */
+ if (batch->state_batch_offset < size ||
+ offset < batch->ptr - batch->map + batch->reserved_space) {
+ intel_batchbuffer_flush(batch);
+ offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment);
+ }
+
+ batch->state_batch_offset = offset;
+
+ if (*out_bo != batch->buf) {
+ drm_intel_bo_unreference(*out_bo);
+ drm_intel_bo_reference(batch->buf);
+ *out_bo = batch->buf;
+ }
+
+ *out_offset = offset;
+ return batch->map + offset;
+}