diff options
Diffstat (limited to 'src/gallium/winsys/i915/sw')
-rw-r--r-- | src/gallium/winsys/i915/sw/Makefile | 12 | ||||
-rw-r--r-- | src/gallium/winsys/i915/sw/SConscript | 17 | ||||
-rw-r--r-- | src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c | 157 | ||||
-rw-r--r-- | src/gallium/winsys/i915/sw/i915_sw_buffer.c | 116 | ||||
-rw-r--r-- | src/gallium/winsys/i915/sw/i915_sw_fence.c | 58 | ||||
-rw-r--r-- | src/gallium/winsys/i915/sw/i915_sw_winsys.c | 59 | ||||
-rw-r--r-- | src/gallium/winsys/i915/sw/i915_sw_winsys.h | 59 |
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 |