@@ -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 | |||
@@ -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 |
@@ -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') |
@@ -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; | |||
} |
@@ -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; | |||
} |
@@ -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; | |||
} |
@@ -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); | |||
} |
@@ -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 |