#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;
}