#include "i915_sw_winsys.h" #include "i915/i915_batchbuffer.h" #include "i915/i915_debug.h" #include "util/u_memory.h" #define BATCH_RESERVED 16 #define INTEL_DEFAULT_RELOCS 100 #define INTEL_MAX_RELOCS 400 #define INTEL_BATCH_NO_CLIPRECTS 0x1 #define INTEL_BATCH_CLIPRECTS 0x2 #define INTEL_ALWAYS_FLUSH struct i915_sw_batchbuffer { struct i915_winsys_batchbuffer base; size_t actual_size; }; static INLINE struct i915_sw_batchbuffer * i915_sw_batchbuffer(struct i915_winsys_batchbuffer *batch) { return (struct i915_sw_batchbuffer *)batch; } static void i915_sw_batchbuffer_reset(struct i915_sw_batchbuffer *batch) { memset(batch->base.map, 0, batch->actual_size); batch->base.ptr = batch->base.map; batch->base.size = batch->actual_size - BATCH_RESERVED; batch->base.relocs = 0; } static struct i915_winsys_batchbuffer * i915_sw_batchbuffer_create(struct i915_winsys *iws) { struct i915_sw_winsys *isws = i915_sw_winsys(iws); struct i915_sw_batchbuffer *batch = CALLOC_STRUCT(i915_sw_batchbuffer); batch->actual_size = isws->max_batch_size; batch->base.map = MALLOC(batch->actual_size); batch->base.ptr = NULL; batch->base.size = 0; batch->base.relocs = 0; batch->base.iws = iws; i915_sw_batchbuffer_reset(batch); return &batch->base; } static boolean i915_sw_batchbuffer_validate_buffers(struct i915_winsys_batchbuffer *batch, struct i915_winsys_buffer **buffer, int num_of_buffers) { return TRUE; } static int i915_sw_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch, struct i915_winsys_buffer *buffer, enum i915_winsys_buffer_usage usage, unsigned pre_add, boolean fenced) { struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch); int ret = 0; if (usage == I915_USAGE_SAMPLER) { } else if (usage == I915_USAGE_RENDER) { } else if (usage == I915_USAGE_2D_TARGET) { } else if (usage == I915_USAGE_2D_SOURCE) { } else if (usage == I915_USAGE_VERTEX) { } else { assert(0); return -1; } ((uint32_t*)batch->base.ptr)[0] = 0; batch->base.ptr += 4; if (!ret) batch->base.relocs++; return ret; } static void i915_sw_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch, struct pipe_fence_handle **fence) { struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch); unsigned used = 0; assert(i915_winsys_batchbuffer_space(ibatch) >= 0); used = batch->base.ptr - batch->base.map; assert((used & 3) == 0); #ifdef INTEL_ALWAYS_FLUSH /* MI_FLUSH | FLUSH_MAP_CACHE */ i915_winsys_batchbuffer_dword_unchecked(ibatch, (0x4<<23)|(1<<0)); used += 4; #endif if ((used & 4) == 0) { /* MI_NOOP */ i915_winsys_batchbuffer_dword_unchecked(ibatch, 0); } /* MI_BATCH_BUFFER_END */ i915_winsys_batchbuffer_dword_unchecked(ibatch, (0xA<<23)); used = batch->base.ptr - batch->base.map; assert((used & 4) == 0); if (i915_sw_winsys(ibatch->iws)->dump_cmd) { i915_dump_batchbuffer(ibatch); } if (fence) { ibatch->iws->fence_reference(ibatch->iws, fence, NULL); (*fence) = i915_sw_fence_create(); } i915_sw_batchbuffer_reset(batch); } static void i915_sw_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch) { struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch); FREE(batch->base.map); FREE(batch); } void i915_sw_winsys_init_batchbuffer_functions(struct i915_sw_winsys *isws) { isws->base.batchbuffer_create = i915_sw_batchbuffer_create; isws->base.validate_buffers = i915_sw_batchbuffer_validate_buffers; isws->base.batchbuffer_reloc = i915_sw_batchbuffer_reloc; isws->base.batchbuffer_flush = i915_sw_batchbuffer_flush; isws->base.batchbuffer_destroy = i915_sw_batchbuffer_destroy; }