summaryrefslogtreecommitdiffstats
path: root/src/gallium/winsys/i915
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/i915')
-rw-r--r--src/gallium/winsys/i915/sw/Makefile12
-rw-r--r--src/gallium/winsys/i915/sw/SConscript17
-rw-r--r--src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c157
-rw-r--r--src/gallium/winsys/i915/sw/i915_sw_buffer.c116
-rw-r--r--src/gallium/winsys/i915/sw/i915_sw_fence.c58
-rw-r--r--src/gallium/winsys/i915/sw/i915_sw_winsys.c59
-rw-r--r--src/gallium/winsys/i915/sw/i915_sw_winsys.h59
7 files changed, 478 insertions, 0 deletions
diff --git a/src/gallium/winsys/i915/sw/Makefile b/src/gallium/winsys/i915/sw/Makefile
new file mode 100644
index 00000000000..6aab6d29614
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/Makefile
@@ -0,0 +1,12 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = i915sw
+
+C_SOURCES = \
+ i915_sw_batchbuffer.c \
+ i915_sw_buffer.c \
+ i915_sw_fence.c \
+ i915_sw_winsys.c
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/i915/sw/SConscript b/src/gallium/winsys/i915/sw/SConscript
new file mode 100644
index 00000000000..84f427a128a
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/SConscript
@@ -0,0 +1,17 @@
+Import('*')
+
+env = env.Clone()
+
+i915_sw_sources = [
+ 'i915_sw_batchbuffer.c',
+ 'i915_sw_buffer.c',
+ 'i915_sw_winsys.c',
+ 'i915_sw_fence.c',
+]
+
+i915sw = env.ConvenienceLibrary(
+ target ='i915sw',
+ source = i915_sw_sources,
+)
+
+Export('i915sw')
diff --git a/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c b/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c
new file mode 100644
index 00000000000..a480cfed57b
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c
@@ -0,0 +1,157 @@
+
+#include "i915_sw_winsys.h"
+#include "i915/i915_batchbuffer.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.max_relocs = 300;/*INTEL_DEFAULT_RELOCS;*/
+
+ batch->base.iws = iws;
+
+ i915_sw_batchbuffer_reset(batch);
+
+ return &batch->base;
+}
+
+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)
+{
+ struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch);
+ int ret = 0;
+
+ assert(batch->base.relocs < batch->base.max_relocs);
+
+ 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;
+ int i;
+
+ 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(ibatch, (0x4<<23)|(1<<0));
+ used += 4;
+#endif
+
+ if ((used & 4) == 0) {
+ /* MI_NOOP */
+ i915_winsys_batchbuffer_dword(ibatch, 0);
+ }
+ /* MI_BATCH_BUFFER_END */
+ i915_winsys_batchbuffer_dword(ibatch, (0xA<<23));
+
+ used = batch->base.ptr - batch->base.map;
+ assert((used & 4) == 0);
+
+ if (i915_sw_winsys(ibatch->iws)->dump_cmd) {
+ unsigned *ptr = (unsigned *)batch->base.map;
+
+ debug_printf("%s:\n", __func__);
+ for (i = 0; i < used / 4; i++, ptr++) {
+ debug_printf("\t%08x: %08x\n", i*4, *ptr);
+ }
+ }
+
+ 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.batchbuffer_reloc = i915_sw_batchbuffer_reloc;
+ isws->base.batchbuffer_flush = i915_sw_batchbuffer_flush;
+ isws->base.batchbuffer_destroy = i915_sw_batchbuffer_destroy;
+}
diff --git a/src/gallium/winsys/i915/sw/i915_sw_buffer.c b/src/gallium/winsys/i915/sw/i915_sw_buffer.c
new file mode 100644
index 00000000000..9a27da5e1a2
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/i915_sw_buffer.c
@@ -0,0 +1,116 @@
+
+#include "i915_sw_winsys.h"
+#include "util/u_memory.h"
+
+static struct i915_winsys_buffer *
+i915_sw_buffer_create(struct i915_winsys *iws,
+ unsigned size, unsigned alignment,
+ enum i915_winsys_buffer_type type)
+{
+ struct i915_sw_buffer *buf = CALLOC_STRUCT(i915_sw_buffer);
+ char *name;
+
+ if (!buf)
+ return NULL;
+
+ if (type == I915_NEW_TEXTURE) {
+ name = "gallium3d_texture";
+ } else if (type == I915_NEW_VERTEX) {
+ name = "gallium3d_vertex";
+ } else if (type == I915_NEW_SCANOUT) {
+ name = "gallium3d_scanout";
+ } else {
+ assert(0);
+ name = "gallium3d_unknown";
+ }
+
+ buf->magic = 0xDEAD1337;
+ buf->name = name;
+ buf->type = type;
+ buf->ptr = calloc(size, 1);
+
+ if (!buf->ptr)
+ goto err;
+
+ return (struct i915_winsys_buffer *)buf;
+
+err:
+ assert(0);
+ FREE(buf);
+ return NULL;
+}
+
+static int
+i915_sw_buffer_set_fence_reg(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ unsigned stride,
+ enum i915_winsys_buffer_tile tile)
+{
+ struct i915_sw_buffer *buf = i915_sw_buffer(buffer);
+
+ if (tile != I915_TILE_NONE) {
+ assert(buf->map_count == 0);
+ }
+
+ buf->tile = tile;
+
+ return 0;
+}
+
+static void *
+i915_sw_buffer_map(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ boolean write)
+{
+ struct i915_sw_buffer *buf = i915_sw_buffer(buffer);
+
+ buf->map_count += 1;
+ return buf->ptr;
+}
+
+static void
+i915_sw_buffer_unmap(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer)
+{
+ struct i915_sw_buffer *buf = i915_sw_buffer(buffer);
+
+ buf->map_count -= 1;
+}
+
+static int
+i915_sw_buffer_write(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ size_t offset,
+ size_t size,
+ const void *data)
+{
+ struct i915_sw_buffer *buf = i915_sw_buffer(buffer);
+
+ memcpy(buf->ptr + offset, data, size);
+ return 0;
+}
+
+static void
+i915_sw_buffer_destroy(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer)
+{
+ struct i915_sw_buffer *buf = i915_sw_buffer(buffer);
+
+#ifdef DEBUG
+ buf->magic = 0;
+#endif
+
+ FREE(buf->ptr);
+ FREE(buf);
+}
+
+void
+i915_sw_winsys_init_buffer_functions(struct i915_sw_winsys *isws)
+{
+ isws->base.buffer_create = i915_sw_buffer_create;
+ isws->base.buffer_set_fence_reg = i915_sw_buffer_set_fence_reg;
+ isws->base.buffer_map = i915_sw_buffer_map;
+ isws->base.buffer_unmap = i915_sw_buffer_unmap;
+ isws->base.buffer_write = i915_sw_buffer_write;
+ isws->base.buffer_destroy = i915_sw_buffer_destroy;
+}
diff --git a/src/gallium/winsys/i915/sw/i915_sw_fence.c b/src/gallium/winsys/i915/sw/i915_sw_fence.c
new file mode 100644
index 00000000000..4b61b2a5e30
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/i915_sw_fence.c
@@ -0,0 +1,58 @@
+
+#include "i915_sw_winsys.h"
+#include "util/u_memory.h"
+#include "util/u_atomic.h"
+#include "util/u_inlines.h"
+
+struct i915_sw_fence
+{
+ struct pipe_reference reference;
+};
+
+struct pipe_fence_handle *
+i915_sw_fence_create()
+{
+ struct i915_sw_fence *fence = CALLOC_STRUCT(i915_sw_fence);
+
+ pipe_reference_init(&fence->reference, 1);
+
+ return (struct pipe_fence_handle *)fence;
+}
+
+static void
+i915_sw_fence_reference(struct i915_winsys *iws,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+ struct i915_sw_fence *old = (struct i915_sw_fence *)*ptr;
+ struct i915_sw_fence *f = (struct i915_sw_fence *)fence;
+
+ if (pipe_reference(&((struct i915_sw_fence *)(*ptr))->reference, &f->reference)) {
+ FREE(old);
+ }
+ *ptr = fence;
+}
+
+static int
+i915_sw_fence_signalled(struct i915_winsys *iws,
+ struct pipe_fence_handle *fence)
+{
+ assert(0);
+
+ return 0;
+}
+
+static int
+i915_sw_fence_finish(struct i915_winsys *iws,
+ struct pipe_fence_handle *fence)
+{
+ return 0;
+}
+
+void
+i915_sw_winsys_init_fence_functions(struct i915_sw_winsys *isws)
+{
+ isws->base.fence_reference = i915_sw_fence_reference;
+ isws->base.fence_signalled = i915_sw_fence_signalled;
+ isws->base.fence_finish = i915_sw_fence_finish;
+}
diff --git a/src/gallium/winsys/i915/sw/i915_sw_winsys.c b/src/gallium/winsys/i915/sw/i915_sw_winsys.c
new file mode 100644
index 00000000000..a95f2009dd4
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/i915_sw_winsys.c
@@ -0,0 +1,59 @@
+
+#include "i915_sw_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915/i915_context.h"
+#include "i915/i915_screen.h"
+
+
+/*
+ * Helper functions
+ */
+
+
+static void
+i915_sw_get_device_id(unsigned int *device_id)
+{
+ /* just pick a i945 hw id */
+ *device_id = 0x27A2;
+}
+
+static void
+i915_sw_destroy(struct i915_winsys *iws)
+{
+ struct i915_sw_winsys *isws = i915_sw_winsys(iws);
+ FREE(isws);
+}
+
+
+/*
+ * Exported functions
+ */
+
+
+struct pipe_screen *
+i915_sw_create_screen()
+{
+ struct i915_sw_winsys *isws;
+ unsigned int deviceID;
+
+ isws = CALLOC_STRUCT(i915_sw_winsys);
+ if (!isws)
+ return NULL;
+
+ i915_sw_get_device_id(&deviceID);
+
+ i915_sw_winsys_init_batchbuffer_functions(isws);
+ i915_sw_winsys_init_buffer_functions(isws);
+ i915_sw_winsys_init_fence_functions(isws);
+
+ isws->base.destroy = i915_sw_destroy;
+
+ isws->id = deviceID;
+ isws->max_batch_size = 16 * 4096;
+
+ isws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
+
+ /* XXX so this will leak winsys:es */
+ return i915_create_screen(&isws->base, deviceID);
+}
diff --git a/src/gallium/winsys/i915/sw/i915_sw_winsys.h b/src/gallium/winsys/i915/sw/i915_sw_winsys.h
new file mode 100644
index 00000000000..92e7c36fd8c
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/i915_sw_winsys.h
@@ -0,0 +1,59 @@
+
+#ifndef I915_SW_WINSYS_H
+#define I915_SW_WINSYS_H
+
+#include "i915/i915_winsys.h"
+
+
+/*
+ * Winsys
+ */
+
+
+struct i915_sw_winsys
+{
+ struct i915_winsys base;
+
+ boolean dump_cmd;
+
+ unsigned id;
+
+ size_t max_batch_size;
+};
+
+static INLINE struct i915_sw_winsys *
+i915_sw_winsys(struct i915_winsys *iws)
+{
+ return (struct i915_sw_winsys *)iws;
+}
+
+struct pipe_screen* i915_sw_create_screen(void);
+struct pipe_fence_handle * i915_sw_fence_create(void);
+
+void i915_sw_winsys_init_batchbuffer_functions(struct i915_sw_winsys *idws);
+void i915_sw_winsys_init_buffer_functions(struct i915_sw_winsys *idws);
+void i915_sw_winsys_init_fence_functions(struct i915_sw_winsys *idws);
+
+
+/*
+ * Buffer
+ */
+
+
+struct i915_sw_buffer {
+ unsigned magic;
+
+ void *ptr;
+ unsigned map_count;
+ enum i915_winsys_buffer_type type;
+ enum i915_winsys_buffer_tile tile;
+ const char *name;
+};
+
+static INLINE struct i915_sw_buffer *
+i915_sw_buffer(struct i915_winsys_buffer *buffer)
+{
+ return (struct i915_sw_buffer *)buffer;
+}
+
+#endif