{
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;
+}
batch->ptr = batch->map;
batch->reserved_space = BATCH_RESERVED;
batch->dirty_state = ~0;
+ batch->state_batch_offset = batch->size;
}
struct intel_batchbuffer *
int x_off = 0, y_off = 0;
drm_intel_bo_subdata(batch->buf, 0, used, batch->buffer);
+ if (batch->state_batch_offset != batch->size) {
+ drm_intel_bo_subdata(batch->buf,
+ batch->state_batch_offset,
+ batch->size - batch->state_batch_offset,
+ batch->buffer + batch->state_batch_offset);
+ }
batch->ptr = NULL;
GLubyte *ptr;
GLuint size;
+ uint32_t state_batch_offset;
#ifdef DEBUG
/** Tracking of BEGIN_BATCH()/OUT_BATCH()/ADVANCE_BATCH() debugging */
static INLINE GLint
intel_batchbuffer_space(struct intel_batchbuffer *batch)
{
- return (batch->size - batch->reserved_space) - (batch->ptr - batch->map);
+ return (batch->state_batch_offset - batch->reserved_space) -
+ (batch->ptr - batch->map);
}