i915g: Add a software only debuging winsys
authorJakob Bornecrantz <wallbraker@gmail.com>
Sat, 17 Apr 2010 14:17:33 +0000 (15:17 +0100)
committerJakob Bornecrantz <wallbraker@gmail.com>
Sat, 17 Apr 2010 20:13:23 +0000 (21:13 +0100)
configure.ac
src/gallium/winsys/i915/sw/Makefile [new file with mode: 0644]
src/gallium/winsys/i915/sw/SConscript [new file with mode: 0644]
src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c [new file with mode: 0644]
src/gallium/winsys/i915/sw/i915_sw_buffer.c [new file with mode: 0644]
src/gallium/winsys/i915/sw/i915_sw_fence.c [new file with mode: 0644]
src/gallium/winsys/i915/sw/i915_sw_winsys.c [new file with mode: 0644]
src/gallium/winsys/i915/sw/i915_sw_winsys.h [new file with mode: 0644]

index 5647442ea17b1b5e76a4afc5d2b1dde978e46741..0e777074339b930b909b38837c10de505a5011f7 100644 (file)
@@ -1359,9 +1359,11 @@ AC_ARG_ENABLE([gallium-intel],
     [enable_gallium_intel="$enableval"],
     [enable_gallium_intel=auto])
 if test "x$enable_gallium_intel" = xyes; then
+    GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw"
     GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915 i965"
     gallium_check_st "i915/drm i965/drm" "dri-i915 dri-i965" "egl-i915 egl-i965" "xorg-i915 xorg-i965"
 elif test "x$enable_gallium_intel" = xauto; then
+    GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw"
     GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915 i965"
 fi
 
diff --git a/src/gallium/winsys/i915/sw/Makefile b/src/gallium/winsys/i915/sw/Makefile
new file mode 100644 (file)
index 0000000..6aab6d2
--- /dev/null
@@ -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 (file)
index 0000000..84f427a
--- /dev/null
@@ -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 (file)
index 0000000..a480cfe
--- /dev/null
@@ -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 (file)
index 0000000..9a27da5
--- /dev/null
@@ -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 (file)
index 0000000..4b61b2a
--- /dev/null
@@ -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 (file)
index 0000000..a95f200
--- /dev/null
@@ -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 (file)
index 0000000..92e7c36
--- /dev/null
@@ -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