summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/drm/i965
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/drm/i965')
-rw-r--r--src/gallium/winsys/drm/i965/Makefile12
-rw-r--r--src/gallium/winsys/drm/i965/SConscript7
-rw-r--r--src/gallium/winsys/drm/i965/dri/Makefile26
-rw-r--r--src/gallium/winsys/drm/i965/dri/SConscript19
-rw-r--r--src/gallium/winsys/drm/i965/egl/Makefile29
-rw-r--r--src/gallium/winsys/drm/i965/gem/Makefile14
-rw-r--r--src/gallium/winsys/drm/i965/gem/SConscript15
-rw-r--r--src/gallium/winsys/drm/i965/gem/i965_drm_api.c243
-rw-r--r--src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c427
-rw-r--r--src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h64
-rw-r--r--src/gallium/winsys/drm/i965/xlib/Makefile97
-rw-r--r--src/gallium/winsys/drm/i965/xlib/xlib_i965.c522
-rw-r--r--src/gallium/winsys/drm/i965/xorg/Makefile57
-rw-r--r--src/gallium/winsys/drm/i965/xorg/intel_xorg.c147
14 files changed, 1679 insertions, 0 deletions
diff --git a/src/gallium/winsys/drm/i965/Makefile b/src/gallium/winsys/drm/i965/Makefile
new file mode 100644
index 00000000000..d8feef6824a
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/Makefile
@@ -0,0 +1,12 @@
+# src/gallium/winsys/drm/intel/Makefile
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+SUBDIRS = gem $(GALLIUM_STATE_TRACKERS_DIRS)
+
+default install clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) $@) || exit 1; \
+ fi \
+ done
diff --git a/src/gallium/winsys/drm/i965/SConscript b/src/gallium/winsys/drm/i965/SConscript
new file mode 100644
index 00000000000..50d7b75ed68
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/SConscript
@@ -0,0 +1,7 @@
+Import('*')
+
+SConscript(['gem/SConscript',])
+
+if 'mesa' in env['statetrackers']:
+
+ SConscript(['dri/SConscript'])
diff --git a/src/gallium/winsys/drm/i965/dri/Makefile b/src/gallium/winsys/drm/i965/dri/Makefile
new file mode 100644
index 00000000000..f7e81eed87b
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/dri/Makefile
@@ -0,0 +1,26 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = i965_dri.so
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
+ $(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/identity/libidentity.a \
+ $(TOP)/src/gallium/drivers/i965/libi965.a
+
+
+DRIVER_SOURCES =
+
+C_SOURCES = \
+ $(COMMON_GALLIUM_SOURCES) \
+ $(DRIVER_SOURCES)
+
+include ../../Makefile.template
+
+DRI_LIB_DEPS += -ldrm_intel
+
+symlinks: $(TOP)/$(LIB_DIR)/gallium
+ @rm -f $(TOP)/$(LIB_DIR)/gallium/i965_dri.so
diff --git a/src/gallium/winsys/drm/i965/dri/SConscript b/src/gallium/winsys/drm/i965/dri/SConscript
new file mode 100644
index 00000000000..233ef464be5
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/dri/SConscript
@@ -0,0 +1,19 @@
+Import('*')
+
+env = drienv.Clone()
+
+env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+
+drivers = [
+ st_dri,
+ i965drm,
+ i965,
+ trace,
+]
+
+env.LoadableModule(
+ target ='i965_dri.so',
+ source = COMMON_GALLIUM_SOURCES,
+ LIBS = drivers + mesa + auxiliaries + env['LIBS'],
+ SHLIBPREFIX = '',
+)
diff --git a/src/gallium/winsys/drm/i965/egl/Makefile b/src/gallium/winsys/drm/i965/egl/Makefile
new file mode 100644
index 00000000000..a1b32eb2a79
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/egl/Makefile
@@ -0,0 +1,29 @@
+TOP = ../../../../../..
+GALLIUMDIR = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = EGL_i965.so
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
+ $(GALLIUMDIR)/winsys/drm/i965/gem/libi965drm.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/i965/libi965.a
+
+DRIVER_SOURCES =
+
+C_SOURCES = \
+ $(COMMON_GALLIUM_SOURCES) \
+ $(DRIVER_SOURCES)
+
+DRIVER_EXTRAS = -ldrm_intel
+
+ASM_SOURCES =
+
+DRIVER_DEFINES = -I../gem $(shell pkg-config libdrm --atleast-version=2.3.1 \
+ && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
+
+include ../../Makefile.template
+
+symlinks:
diff --git a/src/gallium/winsys/drm/i965/gem/Makefile b/src/gallium/winsys/drm/i965/gem/Makefile
new file mode 100644
index 00000000000..6a7497b6be3
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/gem/Makefile
@@ -0,0 +1,14 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = i965drm
+
+C_SOURCES = \
+ i965_drm_buffer.c \
+ i965_drm_api.c
+
+LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
+
+LIBRARY_DEFINES = $(shell pkg-config libdrm --cflags-only-other)
+
+include ../../../../Makefile.template
diff --git a/src/gallium/winsys/drm/i965/gem/SConscript b/src/gallium/winsys/drm/i965/gem/SConscript
new file mode 100644
index 00000000000..6256ec6eaf0
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/gem/SConscript
@@ -0,0 +1,15 @@
+Import('*')
+
+env = drienv.Clone()
+
+i965drm_sources = [
+ 'i965_drm_api.c',
+ 'i965_drm_buffer.c',
+]
+
+i965drm = env.ConvenienceLibrary(
+ target ='i965drm',
+ source = i965drm_sources,
+)
+
+Export('i965drm')
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_api.c b/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
new file mode 100644
index 00000000000..fc9678d2b62
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
@@ -0,0 +1,243 @@
+
+#include <stdio.h>
+#include "state_tracker/drm_api.h"
+
+#include "i965_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i965/brw_context.h" /* XXX: shouldn't be doing this */
+#include "i965/brw_screen.h" /* XXX: shouldn't be doing this */
+
+#include "trace/tr_drm.h"
+
+/*
+ * Helper functions
+ */
+
+
+static void
+i965_libdrm_get_device_id(unsigned int *device_id)
+{
+ char path[512];
+ FILE *file;
+ void *shutup_gcc;
+
+ /*
+ * FIXME: Fix this up to use a drm ioctl or whatever.
+ */
+
+ snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
+ file = fopen(path, "r");
+ if (!file) {
+ return;
+ }
+
+ shutup_gcc = fgets(path, sizeof(path), file);
+ sscanf(path, "%x", device_id);
+ fclose(file);
+}
+
+static struct i965_libdrm_buffer *
+i965_libdrm_buffer_from_handle(struct i965_libdrm_winsys *idws,
+ const char* name, unsigned handle)
+{
+ struct i965_libdrm_buffer *buf = CALLOC_STRUCT(i965_libdrm_buffer);
+ uint32_t swizzle = 0;
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (!buf)
+ return NULL;
+ pipe_reference_init(&buf->base.reference, 1);
+ buf->bo = drm_intel_bo_gem_create_from_name(idws->gem, name, handle);
+ buf->base.size = buf->bo->size;
+ buf->base.sws = &idws->base;
+ buf->flinked = TRUE;
+ buf->flink = handle;
+
+
+ if (!buf->bo)
+ goto err;
+
+ drm_intel_bo_get_tiling(buf->bo, &buf->tiling, &swizzle);
+ if (buf->tiling != 0)
+ buf->map_gtt = TRUE;
+
+ return buf;
+
+err:
+ FREE(buf);
+ return NULL;
+}
+
+
+/*
+ * Exported functions
+ */
+
+
+static struct pipe_texture *
+i965_libdrm_texture_from_shared_handle(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *template,
+ const char* name,
+ unsigned pitch,
+ unsigned handle)
+{
+ /* XXX: this is silly -- there should be a way to get directly from
+ * the "drm_api" struct to ourselves, without peering into
+ * unrelated code:
+ */
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(brw_screen(screen)->sws);
+ struct i965_libdrm_buffer *buffer;
+
+ if (BRW_DUMP)
+ debug_printf("%s %s pitch %d handle 0x%x\n", __FUNCTION__,
+ name, pitch, handle);
+
+ buffer = i965_libdrm_buffer_from_handle(idws, name, handle);
+ if (!buffer)
+ return NULL;
+
+ return brw_texture_blanket_winsys_buffer(screen, template, pitch,
+ buffer->tiling,
+ &buffer->base);
+}
+
+
+static boolean
+i965_libdrm_shared_handle_from_texture(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned *pitch,
+ unsigned *handle)
+{
+ struct i965_libdrm_buffer *buf = NULL;
+ struct brw_winsys_buffer *buffer = NULL;
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
+ return FALSE;
+
+ buf = i965_libdrm_buffer(buffer);
+ if (!buf->flinked) {
+ if (drm_intel_bo_flink(buf->bo, &buf->flink))
+ return FALSE;
+ buf->flinked = TRUE;
+ }
+
+ *handle = buf->flink;
+
+ if (BRW_DUMP)
+ debug_printf(" -> pitch %d handle 0x%x\n", *pitch, *handle);
+
+ return TRUE;
+}
+
+static boolean
+i965_libdrm_local_handle_from_texture(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned *pitch,
+ unsigned *handle)
+{
+ struct brw_winsys_buffer *buffer = NULL;
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
+ return FALSE;
+
+ *handle = i965_libdrm_buffer(buffer)->bo->handle;
+
+ if (BRW_DUMP)
+ debug_printf(" -> pitch %d handle 0x%x\n", *pitch, *handle);
+
+ return TRUE;
+}
+
+static void
+i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
+{
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(iws);
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ drm_intel_bufmgr_destroy(idws->gem);
+
+ FREE(idws);
+}
+
+static struct pipe_screen *
+i965_libdrm_create_screen(struct drm_api *api, int drmFD,
+ struct drm_create_screen_arg *arg)
+{
+ struct i965_libdrm_winsys *idws;
+ unsigned int deviceID;
+
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (arg != NULL) {
+ switch(arg->mode) {
+ case DRM_CREATE_NORMAL:
+ break;
+ default:
+ return NULL;
+ }
+ }
+
+ idws = CALLOC_STRUCT(i965_libdrm_winsys);
+ if (!idws)
+ return NULL;
+
+ i965_libdrm_get_device_id(&deviceID);
+
+ i965_libdrm_winsys_init_buffer_functions(idws);
+
+ idws->fd = drmFD;
+ idws->id = deviceID;
+
+ idws->base.destroy = i965_libdrm_winsys_destroy;
+
+ idws->gem = drm_intel_bufmgr_gem_init(idws->fd, BRW_BATCH_SIZE);
+ drm_intel_bufmgr_gem_enable_reuse(idws->gem);
+
+ idws->send_cmd = !debug_get_bool_option("BRW_NO_HW", FALSE);
+
+ return brw_create_screen(&idws->base, deviceID);
+}
+
+static struct pipe_context *
+i965_libdrm_create_context(struct drm_api *api, struct pipe_screen *screen)
+{
+ return brw_create_context(screen);
+}
+
+static void
+destroy(struct drm_api *api)
+{
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+}
+
+struct drm_api i965_libdrm_api =
+{
+ .create_context = i965_libdrm_create_context,
+ .create_screen = i965_libdrm_create_screen,
+ .texture_from_shared_handle = i965_libdrm_texture_from_shared_handle,
+ .shared_handle_from_texture = i965_libdrm_shared_handle_from_texture,
+ .local_handle_from_texture = i965_libdrm_local_handle_from_texture,
+ .destroy = destroy,
+};
+
+struct drm_api *
+drm_api_create()
+{
+ return trace_drm_create(&i965_libdrm_api);
+}
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c b/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c
new file mode 100644
index 00000000000..a4a72b372dd
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c
@@ -0,0 +1,427 @@
+
+#include "i965_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915_drm.h"
+#include "intel_bufmgr.h"
+
+
+
+const char *names[BRW_BUFFER_TYPE_MAX] = {
+ "TEXTURE",
+ "SCANOUT",
+ "VERTEX",
+ "CURBE",
+ "QUERY",
+ "SHADER_CONSTANTS",
+ "WM_SCRATCH",
+ "BATCH",
+ "GENERAL_STATE",
+ "SURFACE_STATE",
+ "PIXEL",
+ "GENERIC",
+};
+
+const char *usages[BRW_USAGE_MAX] = {
+ "STATE",
+ "QUERY_RESULT",
+ "RENDER_TARGET",
+ "DEPTH_BUFFER",
+ "BLIT_SOURCE",
+ "BLIT_DEST",
+ "SAMPLER",
+ "VERTEX",
+ "SCRATCH"
+};
+
+
+const char *data_types[BRW_DATA_MAX] =
+{
+ "GS: CC_VP",
+ "GS: CC_UNIT",
+ "GS: WM_PROG",
+ "GS: SAMPLER_DEFAULT_COLOR",
+ "GS: SAMPLER",
+ "GS: WM_UNIT",
+ "GS: SF_PROG",
+ "GS: SF_VP",
+ "GS: SF_UNIT",
+ "GS: VS_UNIT",
+ "GS: VS_PROG",
+ "GS: GS_UNIT",
+ "GS: GS_PROG",
+ "GS: CLIP_VP",
+ "GS: CLIP_UNIT",
+ "GS: CLIP_PROG",
+ "SS: SURFACE",
+ "SS: SURF_BIND",
+ "CONSTANT DATA",
+ "BATCH DATA",
+ "(untyped)"
+};
+
+static enum pipe_error
+i965_libdrm_bo_alloc(struct brw_winsys_screen *sws,
+ enum brw_buffer_type type,
+ unsigned size,
+ unsigned alignment,
+ struct brw_winsys_buffer **bo_out)
+{
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(sws);
+ struct i965_libdrm_buffer *buf;
+
+ if (BRW_DUMP)
+ debug_printf("%s type %s sz %d align %d\n",
+ __FUNCTION__, names[type], size, alignment );
+
+ buf = CALLOC_STRUCT(i965_libdrm_buffer);
+ if (!buf)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ switch (type) {
+ case BRW_BUFFER_TYPE_TEXTURE:
+/* case BRW_BUFFER_TYPE_SCANOUT:*/
+ case BRW_BUFFER_TYPE_VERTEX:
+ case BRW_BUFFER_TYPE_CURBE:
+ case BRW_BUFFER_TYPE_QUERY:
+ case BRW_BUFFER_TYPE_SHADER_CONSTANTS:
+ case BRW_BUFFER_TYPE_SHADER_SCRATCH:
+ case BRW_BUFFER_TYPE_BATCH:
+ case BRW_BUFFER_TYPE_GENERAL_STATE:
+ case BRW_BUFFER_TYPE_SURFACE_STATE:
+ case BRW_BUFFER_TYPE_PIXEL:
+ case BRW_BUFFER_TYPE_GENERIC:
+ break;
+ case BRW_BUFFER_TYPE_SCANOUT:
+ buf->map_gtt = TRUE;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ buf->bo = drm_intel_bo_alloc(idws->gem,
+ names[type],
+ size,
+ alignment);
+
+ if (!buf->bo)
+ goto err;
+
+ pipe_reference_init(&buf->base.reference, 1);
+ buf->base.size = size;
+ buf->base.sws = sws;
+
+ *bo_out = &buf->base;
+ return PIPE_OK;
+
+err:
+ assert(0);
+ FREE(buf);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+static void
+i965_libdrm_bo_destroy(struct brw_winsys_buffer *buffer)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ drm_intel_bo_unreference(buf->bo);
+ FREE(buffer);
+}
+
+static enum pipe_error
+i965_libdrm_bo_emit_reloc(struct brw_winsys_buffer *buffer,
+ enum brw_buffer_usage usage,
+ unsigned delta,
+ unsigned offset,
+ struct brw_winsys_buffer *buffer2)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+ struct i965_libdrm_buffer *buf2 = i965_libdrm_buffer(buffer2);
+ int read, write;
+ int ret;
+
+ if (BRW_DUMP)
+ debug_printf("%s buf %p offset %x delta %x buf2 %p/%s/%s\n",
+ __FUNCTION__, (void *)buffer,
+ offset, delta,
+ (void *)buffer2, names[buf2->data_type], usages[usage]);
+
+ switch (usage) {
+ case BRW_USAGE_STATE:
+ read = I915_GEM_DOMAIN_INSTRUCTION;
+ write = 0;
+ break;
+ case BRW_USAGE_QUERY_RESULT:
+ read = I915_GEM_DOMAIN_INSTRUCTION;
+ write = I915_GEM_DOMAIN_INSTRUCTION;
+ break;
+ case BRW_USAGE_RENDER_TARGET:
+ read = I915_GEM_DOMAIN_RENDER;
+ write = 0;
+ break;
+ case BRW_USAGE_DEPTH_BUFFER:
+ read = I915_GEM_DOMAIN_RENDER;
+ write = I915_GEM_DOMAIN_RENDER;
+ break;
+ case BRW_USAGE_BLIT_SOURCE:
+ read = 0;
+ write = I915_GEM_DOMAIN_RENDER;
+ break;
+ case BRW_USAGE_BLIT_DEST:
+ read = I915_GEM_DOMAIN_RENDER;
+ write = I915_GEM_DOMAIN_RENDER;
+ break;
+ case BRW_USAGE_SAMPLER:
+ read = I915_GEM_DOMAIN_SAMPLER;
+ write = 0;
+ break;
+ case BRW_USAGE_VERTEX:
+ read = I915_GEM_DOMAIN_VERTEX;
+ write = 0;
+ break;
+ case BRW_USAGE_SCRATCH:
+ read = 0;
+ write = 0;
+ break;
+ default:
+ assert(0);
+ return -1;
+ }
+
+ /* Needed??
+ ((uint32_t *)buf->bo->virtual)[offset/4] = (delta +
+ buf2->bo->offset);
+ */
+
+ ret = dri_bo_emit_reloc( buf->bo, read, write, delta, offset, buf2->bo );
+ if (ret)
+ return -1;
+
+ return 0;
+}
+
+static enum pipe_error
+i965_libdrm_bo_exec(struct brw_winsys_buffer *buffer,
+ unsigned bytes_used)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(buffer->sws);
+ int ret;
+
+ if (BRW_DUMP)
+ debug_printf("execute buffer %p, bytes %d\n", (void *)buffer, bytes_used);
+
+ if (idws->send_cmd) {
+ ret = dri_bo_exec(buf->bo, bytes_used, NULL, 0, 0);
+ if (ret)
+ return PIPE_ERROR;
+ }
+
+ return PIPE_OK;
+}
+
+static enum pipe_error
+i965_libdrm_bo_subdata(struct brw_winsys_buffer *buffer,
+ enum brw_buffer_data_type data_type,
+ size_t offset,
+ size_t size,
+ const void *data,
+ const struct brw_winsys_reloc *reloc,
+ unsigned nr_reloc)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(buffer->sws);
+ int ret, i;
+
+ (void)data_type;
+
+ if (BRW_DUMP)
+ debug_printf("%s buf %p off %d sz %d %s relocs: %d\n",
+ __FUNCTION__,
+ (void *)buffer, offset, size,
+ data_types[data_type],
+ nr_reloc);
+
+ if (BRW_DUMP)
+ brw_dump_data( idws->id,
+ data_type,
+ buf->bo->offset + offset,
+ data, size );
+
+ /* XXX: use bo_map_gtt/memcpy/unmap_gtt under some circumstances???
+ */
+ ret = drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
+ if (ret)
+ return PIPE_ERROR;
+
+ for (i = 0; i < nr_reloc; i++) {
+ i965_libdrm_bo_emit_reloc(buffer, reloc[i].usage, reloc[i].delta,
+ reloc[i].offset, reloc[i].bo);
+ }
+
+ return PIPE_OK;
+}
+
+static boolean
+i965_libdrm_bo_is_busy(struct brw_winsys_buffer *buffer)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+ boolean ret;
+
+ if (BRW_DUMP)
+ debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
+
+ ret = drm_intel_bo_busy(buf->bo);
+
+ if (BRW_DUMP)
+ debug_printf(" --> %d\n", ret);
+
+ return ret;
+}
+
+static boolean
+i965_libdrm_bo_references(struct brw_winsys_buffer *a,
+ struct brw_winsys_buffer *b)
+{
+ struct i965_libdrm_buffer *bufa = i965_libdrm_buffer(a);
+ struct i965_libdrm_buffer *bufb = i965_libdrm_buffer(b);
+ boolean ret;
+
+ if (BRW_DUMP)
+ debug_printf("%s %p %p\n", __FUNCTION__, (void *)a, (void *)b);
+
+ ret = drm_intel_bo_references(bufa->bo, bufb->bo);
+
+ if (BRW_DUMP)
+ debug_printf(" --> %d\n", ret);
+
+ return ret;
+}
+
+/* XXX: couldn't this be handled by returning true/false on
+ * bo_emit_reloc?
+ */
+static enum pipe_error
+i965_libdrm_check_aperture_space(struct brw_winsys_screen *iws,
+ struct brw_winsys_buffer **buffers,
+ unsigned count)
+{
+ static drm_intel_bo *bos[128];
+ int i;
+ int ret;
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (count > Elements(bos)) {
+ assert(0);
+ return FALSE;
+ }
+
+ for (i = 0; i < count; i++)
+ bos[i] = i965_libdrm_buffer(buffers[i])->bo;
+
+ /* XXX: converting from ??? to pipe_error:
+ */
+ ret = dri_bufmgr_check_aperture_space(bos, count);
+
+ if (BRW_DUMP)
+ debug_printf(" --> %d (ok == %d)\n", ret, PIPE_OK);
+
+ return ret;
+}
+
+static void *
+i965_libdrm_bo_map(struct brw_winsys_buffer *buffer,
+ enum brw_buffer_data_type data_type,
+ unsigned offset,
+ unsigned length,
+ boolean write,
+ boolean discard,
+ boolean flush_explicit)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+ int ret;
+
+
+ if (BRW_DUMP)
+ debug_printf("%s %p %s %s\n", __FUNCTION__, (void *)buffer,
+ write ? "read/write" : "read",
+ write ? data_types[data_type] : "");
+
+ if (!buf->map_count) {
+ if (buf->map_gtt) {
+ ret = drm_intel_gem_bo_map_gtt(buf->bo);
+ if (ret)
+ return NULL;
+ }
+ else {
+ ret = drm_intel_bo_map(buf->bo, write);
+ if (ret)
+ return NULL;
+ }
+ }
+
+ buf->data_type = data_type;
+ buf->map_count++;
+ return buf->bo->virtual;
+}
+
+static void
+i965_libdrm_bo_flush_range(struct brw_winsys_buffer *buffer,
+ unsigned offset,
+ unsigned length)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(buffer->sws);
+
+ if (BRW_DUMP)
+ debug_printf("%s %s offset %d len %d\n", __FUNCTION__,
+ data_types[buf->data_type],
+ offset, length);
+
+ if (BRW_DUMP)
+ brw_dump_data( idws->id,
+ buf->data_type,
+ buf->bo->offset + offset,
+ buf->bo->virtual + offset,
+ length );
+}
+
+static void
+i965_libdrm_bo_unmap(struct brw_winsys_buffer *buffer)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (--buf->map_count > 0)
+ return;
+
+ if (buf->map_gtt)
+ drm_intel_gem_bo_unmap_gtt(buf->bo);
+ else
+ drm_intel_bo_unmap(buf->bo);
+}
+
+void
+i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws)
+{
+ idws->base.bo_alloc = i965_libdrm_bo_alloc;
+ idws->base.bo_destroy = i965_libdrm_bo_destroy;
+ idws->base.bo_emit_reloc = i965_libdrm_bo_emit_reloc;
+ idws->base.bo_exec = i965_libdrm_bo_exec;
+ idws->base.bo_subdata = i965_libdrm_bo_subdata;
+ idws->base.bo_is_busy = i965_libdrm_bo_is_busy;
+ idws->base.bo_references = i965_libdrm_bo_references;
+ idws->base.check_aperture_space = i965_libdrm_check_aperture_space;
+ idws->base.bo_map = i965_libdrm_bo_map;
+ idws->base.bo_flush_range = i965_libdrm_bo_flush_range;
+ idws->base.bo_unmap = i965_libdrm_bo_unmap;
+}
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h b/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h
new file mode 100644
index 00000000000..c6a7d4a8c51
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h
@@ -0,0 +1,64 @@
+
+#ifndef INTEL_DRM_WINSYS_H
+#define INTEL_DRM_WINSYS_H
+
+#include "i965/brw_winsys.h"
+
+#include "drm.h"
+#include "intel_bufmgr.h"
+
+
+
+/*
+ * Winsys
+ */
+
+
+struct i965_libdrm_winsys
+{
+ struct brw_winsys_screen base;
+ drm_intel_bufmgr *gem;
+
+ boolean send_cmd;
+
+ int fd; /**< Drm file discriptor */
+
+ unsigned id;
+};
+
+static INLINE struct i965_libdrm_winsys *
+i965_libdrm_winsys(struct brw_winsys_screen *iws)
+{
+ return (struct i965_libdrm_winsys *)iws;
+}
+
+struct i965_libdrm_winsys *i965_libdrm_winsys_create(int fd, unsigned pci_id);
+
+void i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws);
+
+
+/* Buffer.
+ */
+struct i965_libdrm_buffer {
+ struct brw_winsys_buffer base;
+
+ drm_intel_bo *bo;
+
+ void *ptr;
+ unsigned map_count;
+ unsigned data_type; /* valid while mapped */
+ unsigned tiling;
+
+ boolean map_gtt;
+ boolean flinked;
+ unsigned flink;
+};
+
+static INLINE struct i965_libdrm_buffer *
+i965_libdrm_buffer(struct brw_winsys_buffer *buffer)
+{
+ return (struct i965_libdrm_buffer *)buffer;
+}
+
+
+#endif
diff --git a/src/gallium/winsys/drm/i965/xlib/Makefile b/src/gallium/winsys/drm/i965/xlib/Makefile
new file mode 100644
index 00000000000..0efa0ca6f9a
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/xlib/Makefile
@@ -0,0 +1,97 @@
+# src/gallium/winsys/xlib/Makefile
+
+# This makefile produces a "stand-alone" libGL.so which is based on
+# Xlib (no DRI HW acceleration)
+
+
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+
+GL_MAJOR = 1
+GL_MINOR = 5
+GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY)
+
+
+INCLUDE_DIRS = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/src/mesa/main \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/drivers/i965 \
+ -I$(TOP)/src/gallium/drivers/i965/include \
+ -I$(TOP)/src/gallium/state_trackers/glx/xlib \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I/usr/include/drm
+
+XLIB_WINSYS_SOURCES = \
+ xlib_i965.c \
+
+
+
+XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o)
+
+
+
+LIBS = \
+ $(TOP)/src/gallium/drivers/i965/libi965.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/state_trackers/glx/xlib/libxlib.a \
+ $(TOP)/src/mesa/libglapi.a \
+ $(TOP)/src/mesa/libmesagallium.a \
+ $(GALLIUM_AUXILIARIES)
+
+# $(TOP)/src/gallium/drivers/i965/lib/libi9xx.a \
+
+.SUFFIXES : .cpp
+
+.c.o:
+ $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@
+
+.cpp.o:
+ $(CXX) -c $(INCLUDE_DIRS) $(DEFINES) $(CXXFLAGS) $< -o $@
+
+
+
+default: $(TOP)/$(LIB_DIR)/gallium $(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME)
+
+$(TOP)/$(LIB_DIR)/gallium:
+ @ mkdir -p $(TOP)/$(LIB_DIR)/gallium
+
+# Make the libGL.so library
+$(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) Makefile
+ $(TOP)/bin/mklib -o $(GL_LIB) \
+ -linker "$(CC)" \
+ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
+ -install $(TOP)/$(LIB_DIR)/gallium \
+ $(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \
+ -Wl,--start-group $(LIBS) -Wl,--end-group $(GL_LIB_DEPS)
+
+
+depend: $(XLIB_WINSYS_SOURCES)
+ @ echo "running $(MKDEP)"
+ @ rm -f depend # workaround oops on gutsy?!?
+ @ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(XLIB_WINSYS_SOURCES) \
+ > /dev/null 2>/dev/null
+
+
+install: default
+ $(INSTALL) -d $(INSTALL_DIR)/include/GL
+ $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
+ $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL
+ @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \
+ fi
+
+
+# Emacs tags
+tags:
+ etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h
+
+clean:
+ -rm -f *.o
+
+
+include depend
diff --git a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c
new file mode 100644
index 00000000000..d2b9a1ab311
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c
@@ -0,0 +1,522 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell
+ * Brian Paul
+ */
+
+
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "pipe/p_error.h"
+#include "pipe/p_context.h"
+
+#include "xm_winsys.h"
+
+#include "i965/brw_winsys.h"
+#include "i965/brw_screen.h"
+#include "i965/brw_reg.h"
+#include "i965/brw_structs_dump.h"
+
+#define MAX_VRAM (128*1024*1024)
+
+
+
+extern int brw_disasm (FILE *file,
+ const struct brw_instruction *inst,
+ unsigned count );
+
+extern int intel_decode(const uint32_t *data,
+ int count,
+ uint32_t hw_offset,
+ uint32_t devid);
+
+struct xlib_brw_buffer
+{
+ struct brw_winsys_buffer base;
+ char *virtual;
+ unsigned offset;
+ unsigned type;
+ int map_count;
+ boolean modified;
+};
+
+
+/**
+ * Subclass of brw_winsys_screen for Xlib winsys
+ */
+struct xlib_brw_winsys
+{
+ struct brw_winsys_screen base;
+ struct brw_chipset chipset;
+
+ unsigned size;
+ unsigned used;
+};
+
+static struct xlib_brw_winsys *
+xlib_brw_winsys( struct brw_winsys_screen *screen )
+{
+ return (struct xlib_brw_winsys *)screen;
+}
+
+
+static struct xlib_brw_buffer *
+xlib_brw_buffer( struct brw_winsys_buffer *buffer )
+{
+ return (struct xlib_brw_buffer *)buffer;
+}
+
+
+
+const char *names[BRW_BUFFER_TYPE_MAX] = {
+ "TEXTURE",
+ "SCANOUT",
+ "VERTEX",
+ "CURBE",
+ "QUERY",
+ "SHADER_CONSTANTS",
+ "WM_SCRATCH",
+ "BATCH",
+ "GENERAL_STATE",
+ "SURFACE_STATE",
+ "PIXEL",
+ "GENERIC",
+};
+
+const char *usages[BRW_USAGE_MAX] = {
+ "STATE",
+ "QUERY_RESULT",
+ "RENDER_TARGET",
+ "DEPTH_BUFFER",
+ "BLIT_SOURCE",
+ "BLIT_DEST",
+ "SAMPLER",
+ "VERTEX",
+ "SCRATCH"
+};
+
+
+const char *data_types[BRW_DATA_MAX] =
+{
+ "GS: CC_VP",
+ "GS: CC_UNIT",
+ "GS: WM_PROG",
+ "GS: SAMPLER_DEFAULT_COLOR",
+ "GS: SAMPLER",
+ "GS: WM_UNIT",
+ "GS: SF_PROG",
+ "GS: SF_VP",
+ "GS: SF_UNIT",
+ "GS: VS_UNIT",
+ "GS: VS_PROG",
+ "GS: GS_UNIT",
+ "GS: GS_PROG",
+ "GS: CLIP_VP",
+ "GS: CLIP_UNIT",
+ "GS: CLIP_PROG",
+ "SS: SURFACE",
+ "SS: SURF_BIND",
+ "CONSTANT DATA",
+ "BATCH DATA",
+ "(untyped)"
+};
+
+
+static enum pipe_error
+xlib_brw_bo_alloc( struct brw_winsys_screen *sws,
+ enum brw_buffer_type type,
+ unsigned size,
+ unsigned alignment,
+ struct brw_winsys_buffer **bo_out )
+{
+ struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
+ struct xlib_brw_buffer *buf;
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s type %s sz %d align %d\n",
+ __FUNCTION__, names[type], size, alignment );
+
+ buf = CALLOC_STRUCT(xlib_brw_buffer);
+ if (!buf)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ pipe_reference_init(&buf->base.reference, 1);
+
+ buf->offset = align(xbw->used, alignment);
+ buf->type = type;
+ buf->virtual = MALLOC(size);
+ buf->base.size = size;
+ buf->base.sws = sws;
+
+ xbw->used = align(xbw->used, alignment) + size;
+ if (xbw->used > MAX_VRAM)
+ goto err;
+
+ /* XXX: possibly rentrant call to bo_destroy:
+ */
+ bo_reference(bo_out, &buf->base);
+ return PIPE_OK;
+
+err:
+ assert(0);
+ FREE(buf->virtual);
+ FREE(buf);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+static void
+xlib_brw_bo_destroy( struct brw_winsys_buffer *buffer )
+{
+ struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+
+ FREE(buf);
+}
+
+static int
+xlib_brw_bo_emit_reloc( struct brw_winsys_buffer *buffer,
+ enum brw_buffer_usage usage,
+ unsigned delta,
+ unsigned offset,
+ struct brw_winsys_buffer *buffer2)
+{
+ struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+ struct xlib_brw_buffer *buf2 = xlib_brw_buffer(buffer2);
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s buf %p offset %x val %x + %x buf2 %p/%s/%s\n",
+ __FUNCTION__, (void *)buffer, offset,
+ buf2->offset, delta,
+ (void *)buffer2, names[buf2->type], usages[usage]);
+
+ *(uint32_t *)(buf->virtual + offset) = buf2->offset + delta;
+
+ return 0;
+}
+
+static int
+xlib_brw_bo_exec( struct brw_winsys_buffer *buffer,
+ unsigned bytes_used )
+{
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("execute buffer %p, bytes %d\n", (void *)buffer, bytes_used);
+
+ return 0;
+}
+
+
+
+
+static int
+xlib_brw_bo_subdata(struct brw_winsys_buffer *buffer,
+ enum brw_buffer_data_type data_type,
+ size_t offset,
+ size_t size,
+ const void *data,
+ const struct brw_winsys_reloc *reloc,
+ unsigned nr_relocs)
+{
+ struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+ struct xlib_brw_winsys *xbw = xlib_brw_winsys(buffer->sws);
+ unsigned i;
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s buf %p off %d sz %d %s relocs: %d\n",
+ __FUNCTION__,
+ (void *)buffer, offset, size,
+ data_types[data_type],
+ nr_relocs);
+
+ assert(buf->base.size >= offset + size);
+ memcpy(buf->virtual + offset, data, size);
+
+ /* Apply the relocations:
+ */
+ for (i = 0; i < nr_relocs; i++) {
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("\treloc[%d] usage %s off %d value %x+%x\n",
+ i, usages[reloc[i].usage], reloc[i].offset,
+ xlib_brw_buffer(reloc[i].bo)->offset, reloc[i].delta);
+
+ *(unsigned *)(buf->virtual + offset + reloc[i].offset) =
+ xlib_brw_buffer(reloc[i].bo)->offset + reloc[i].delta;
+ }
+
+ if (BRW_DUMP)
+ brw_dump_data( xbw->chipset.pci_id,
+ data_type,
+ buf->offset + offset,
+ buf->virtual + offset, size );
+
+
+ return 0;
+}
+
+
+static boolean
+xlib_brw_bo_is_busy(struct brw_winsys_buffer *buffer)
+{
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
+ return TRUE;
+}
+
+static boolean
+xlib_brw_bo_references(struct brw_winsys_buffer *a,
+ struct brw_winsys_buffer *b)
+{
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s %p %p\n", __FUNCTION__, (void *)a, (void *)b);
+ return TRUE;
+}
+
+static enum pipe_error
+xlib_brw_check_aperture_space( struct brw_winsys_screen *iws,
+ struct brw_winsys_buffer **buffers,
+ unsigned count )
+{
+ unsigned tot_size = 0;
+ unsigned i;
+
+ for (i = 0; i < count; i++)
+ tot_size += buffers[i]->size;
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s %d bufs, tot_size: %d kb\n",
+ __FUNCTION__, count,
+ (tot_size + 1023) / 1024);
+
+ return PIPE_OK;
+}
+
+static void *
+xlib_brw_bo_map(struct brw_winsys_buffer *buffer,
+ enum brw_buffer_data_type data_type,
+ unsigned offset,
+ unsigned length,
+ boolean write,
+ boolean discard,
+ boolean explicit)
+{
+ struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s %p %s %s\n", __FUNCTION__, (void *)buffer,
+ write ? "read/write" : "read",
+ write ? data_types[data_type] : "");
+
+ if (write)
+ buf->modified = 1;
+
+ buf->map_count++;
+ return buf->virtual;
+}
+
+
+static void
+xlib_brw_bo_flush_range( struct brw_winsys_buffer *buffer,
+ unsigned offset,
+ unsigned length )
+{
+}
+
+
+static void
+xlib_brw_bo_unmap(struct brw_winsys_buffer *buffer)
+{
+ struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
+
+ --buf->map_count;
+ assert(buf->map_count >= 0);
+
+ if (buf->map_count == 0 &&
+ buf->modified) {
+
+ buf->modified = 0;
+
+ /* Consider dumping new buffer contents here, using the
+ * flush-range info to minimize verbosity.
+ */
+ }
+}
+
+
+static void
+xlib_brw_bo_wait_idle( struct brw_winsys_buffer *buffer )
+{
+}
+
+
+static void
+xlib_brw_winsys_destroy( struct brw_winsys_screen *sws )
+{
+ struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
+
+ FREE(xbw);
+}
+
+static struct brw_winsys_screen *
+xlib_create_brw_winsys_screen( void )
+{
+ struct xlib_brw_winsys *ws;
+
+ ws = CALLOC_STRUCT(xlib_brw_winsys);
+ if (!ws)
+ return NULL;
+
+ ws->used = 0;
+
+ ws->base.destroy = xlib_brw_winsys_destroy;
+ ws->base.bo_alloc = xlib_brw_bo_alloc;
+ ws->base.bo_destroy = xlib_brw_bo_destroy;
+ ws->base.bo_emit_reloc = xlib_brw_bo_emit_reloc;
+ ws->base.bo_exec = xlib_brw_bo_exec;
+ ws->base.bo_subdata = xlib_brw_bo_subdata;
+ ws->base.bo_is_busy = xlib_brw_bo_is_busy;
+ ws->base.bo_references = xlib_brw_bo_references;
+ ws->base.check_aperture_space = xlib_brw_check_aperture_space;
+ ws->base.bo_map = xlib_brw_bo_map;
+ ws->base.bo_flush_range = xlib_brw_bo_flush_range;
+ ws->base.bo_unmap = xlib_brw_bo_unmap;
+ ws->base.bo_wait_idle = xlib_brw_bo_wait_idle;
+
+ return &ws->base;
+}
+
+
+/***********************************************************************
+ * Implementation of Xlib co-state-tracker's winsys interface
+ */
+
+static void
+xlib_i965_display_surface(struct xmesa_buffer *xm_buffer,
+ struct pipe_surface *surf)
+{
+ struct brw_surface *surface = brw_surface(surf);
+ struct xlib_brw_buffer *bo = xlib_brw_buffer(surface->bo);
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s offset %x+%x sz %dx%d\n", __FUNCTION__,
+ bo->offset,
+ surface->draw_offset,
+ surf->width,
+ surf->height);
+}
+
+static void
+xlib_i965_flush_frontbuffer(struct pipe_screen *screen,
+ struct pipe_surface *surf,
+ void *context_private)
+{
+ xlib_i965_display_surface(NULL, surf);
+}
+
+
+static struct pipe_screen *
+xlib_create_i965_screen( void )
+{
+ struct brw_winsys_screen *winsys;
+ struct pipe_screen *screen;
+
+ winsys = xlib_create_brw_winsys_screen();
+ if (winsys == NULL)
+ return NULL;
+
+ screen = brw_create_screen(winsys, PCI_CHIP_GM45_GM);
+ if (screen == NULL)
+ goto fail;
+
+ xlib_brw_winsys(winsys)->chipset = brw_screen(screen)->chipset;
+
+ screen->flush_frontbuffer = xlib_i965_flush_frontbuffer;
+ return screen;
+
+fail:
+ if (winsys)
+ winsys->destroy( winsys );
+
+ return NULL;
+}
+
+
+static struct pipe_context *
+xlib_create_i965_context( struct pipe_screen *screen,
+ void *context_private )
+{
+ struct pipe_context *pipe;
+
+ pipe = brw_create_context(screen);
+ if (pipe == NULL)
+ goto fail;
+
+ pipe->priv = context_private;
+ return pipe;
+
+fail:
+ /* Free stuff here */
+ return NULL;
+}
+
+
+
+
+struct xm_driver xlib_i965_driver =
+{
+ .create_pipe_screen = xlib_create_i965_screen,
+ .create_pipe_context = xlib_create_i965_context,
+ .display_surface = xlib_i965_display_surface
+};
+
+
+/* Register this driver at library load:
+ */
+static void _init( void ) __attribute__((constructor));
+static void _init( void )
+{
+ xmesa_set_driver( &xlib_i965_driver );
+}
+
+
+
+/***********************************************************************
+ *
+ * Butt-ugly hack to convince the linker not to throw away public GL
+ * symbols (they are all referenced from getprocaddress, I guess).
+ */
+extern void (*linker_foo(const unsigned char *procName))();
+extern void (*glXGetProcAddress(const unsigned char *procName))();
+
+extern void (*linker_foo(const unsigned char *procName))()
+{
+ return glXGetProcAddress(procName);
+}
diff --git a/src/gallium/winsys/drm/i965/xorg/Makefile b/src/gallium/winsys/drm/i965/xorg/Makefile
new file mode 100644
index 00000000000..d91d0006efd
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/xorg/Makefile
@@ -0,0 +1,57 @@
+TARGET = modesetting_drv.so
+CFILES = $(wildcard ./*.c)
+OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
+TOP = ../../../../../..
+
+include $(TOP)/configs/current
+
+INCLUDES = \
+ $(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
+ -I../gem \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/include \
+ -I$(TOP)/src/egl/main
+
+LIBS = \
+ $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
+ $(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
+ $(TOP)/src/gallium/drivers/i965/libi965.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(GALLIUM_AUXILIARIES)
+
+DRIVER_DEFINES = \
+ -DHAVE_CONFIG_H
+
+
+#############################################
+
+
+
+all default: $(TARGET)
+
+$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS)
+ $(TOP)/bin/mklib -noprefix -o $@ \
+ $(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel
+
+clean:
+ rm -rf $(OBJECTS) $(TARGET)
+
+install:
+ $(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+ $(MINSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+
+
+##############################################
+
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCLUDES) $(DRIVER_DEFINES) $< -o $@
+
+
+##############################################
+
+.PHONY = all clean install
diff --git a/src/gallium/winsys/drm/i965/xorg/intel_xorg.c b/src/gallium/winsys/drm/i965/xorg/intel_xorg.c
new file mode 100644
index 00000000000..ac691cb76b3
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/xorg/intel_xorg.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * Author: Alan Hourihane <alanh@tungstengraphics.com>
+ * Author: Jakob Bornecrantz <wallbraker@gmail.com>
+ *
+ */
+
+#include "../../../../state_trackers/xorg/xorg_winsys.h"
+
+static void intel_xorg_identify(int flags);
+static Bool intel_xorg_pci_probe(DriverPtr driver,
+ int entity_num,
+ struct pci_device *device,
+ intptr_t match_data);
+
+static const struct pci_id_match intel_xorg_device_match[] = {
+ {0x8086, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0},
+ {0, 0, 0},
+};
+
+static SymTabRec intel_xorg_chipsets[] = {
+ {PCI_MATCH_ANY, "Intel Graphics Device"},
+ {-1, NULL}
+};
+
+static PciChipsets intel_xorg_pci_devices[] = {
+ {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
+ {-1, -1, NULL}
+};
+
+static XF86ModuleVersionInfo intel_xorg_version = {
+ "modesetting",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ 0, 1, 0, /* major, minor, patch */
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+/*
+ * Xorg driver exported structures
+ */
+
+_X_EXPORT DriverRec modesetting = {
+ 1,
+ "modesetting",
+ intel_xorg_identify,
+ NULL,
+ xorg_tracker_available_options,
+ NULL,
+ 0,
+ NULL,
+ intel_xorg_device_match,
+ intel_xorg_pci_probe
+};
+
+static MODULESETUPPROTO(intel_xorg_setup);
+
+_X_EXPORT XF86ModuleData modesettingModuleData = {
+ &intel_xorg_version,
+ intel_xorg_setup,
+ NULL
+};
+
+/*
+ * Xorg driver functions
+ */
+
+static pointer
+intel_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = 0;
+
+ /* This module should be loaded only once, but check to be sure.
+ */
+ if (!setupDone) {
+ setupDone = 1;
+ xf86AddDriver(&modesetting, module, HaveDriverFuncs);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer) 1;
+ } else {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+static void
+intel_xorg_identify(int flags)
+{
+ xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers",
+ intel_xorg_chipsets);
+}
+
+static Bool
+intel_xorg_pci_probe(DriverPtr driver,
+ int entity_num, struct pci_device *device, intptr_t match_data)
+{
+ ScrnInfoPtr scrn = NULL;
+ EntityInfoPtr entity;
+
+ scrn = xf86ConfigPciEntity(scrn, 0, entity_num, intel_xorg_pci_devices,
+ NULL, NULL, NULL, NULL, NULL);
+ if (scrn != NULL) {
+ scrn->driverVersion = 1;
+ scrn->driverName = "i965";
+ scrn->name = "modesetting";
+ scrn->Probe = NULL;
+
+ entity = xf86GetEntityInfo(entity_num);
+
+ /* Use all the functions from the xorg tracker */
+ xorg_tracker_set_functions(scrn);
+ }
+ return scrn != NULL;
+}