Mesa (master): i915g: Implement new winsys

Jakob Bornecrantz wallbraker at kemper.freedesktop.org
Mon Aug 31 22:42:21 UTC 2009


Module: Mesa
Branch: master
Commit: 935e4c56e5b10a0a702d95f78e9f4e6660c452dc
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=935e4c56e5b10a0a702d95f78e9f4e6660c452dc

Author: Jakob Bornecrantz <wallbraker at gmail.com>
Date:   Tue Sep  1 00:42:39 2009 +0100

i915g: Implement new winsys

---

 src/gallium/winsys/drm/intel/gem/Makefile          |    8 +-
 src/gallium/winsys/drm/intel/gem/SConscript        |    8 +-
 src/gallium/winsys/drm/intel/gem/intel_be_api.c    |   36 --
 src/gallium/winsys/drm/intel/gem/intel_be_api.h    |   18 -
 .../winsys/drm/intel/gem/intel_be_batchbuffer.c    |  156 -------
 .../winsys/drm/intel/gem/intel_be_batchbuffer.h    |   55 ---
 .../winsys/drm/intel/gem/intel_be_context.c        |  117 -----
 .../winsys/drm/intel/gem/intel_be_context.h        |   31 --
 src/gallium/winsys/drm/intel/gem/intel_be_device.c |  474 --------------------
 src/gallium/winsys/drm/intel/gem/intel_be_device.h |  107 -----
 src/gallium/winsys/drm/intel/gem/intel_be_fence.h  |   34 --
 src/gallium/winsys/drm/intel/gem/intel_drm_api.c   |  202 +++++++++
 .../winsys/drm/intel/gem/intel_drm_batchbuffer.c   |  211 +++++++++
 .../winsys/drm/intel/gem/intel_drm_buffer.c        |  134 ++++++
 src/gallium/winsys/drm/intel/gem/intel_drm_fence.c |   81 ++++
 .../winsys/drm/intel/gem/intel_drm_winsys.h        |   78 ++++
 16 files changed, 714 insertions(+), 1036 deletions(-)

diff --git a/src/gallium/winsys/drm/intel/gem/Makefile b/src/gallium/winsys/drm/intel/gem/Makefile
index 7ab1a2a..0d6d4e3 100644
--- a/src/gallium/winsys/drm/intel/gem/Makefile
+++ b/src/gallium/winsys/drm/intel/gem/Makefile
@@ -4,10 +4,10 @@ include $(TOP)/configs/current
 LIBNAME = inteldrm
 
 C_SOURCES = \
-	intel_be_batchbuffer.c \
-	intel_be_context.c \
-	intel_be_device.c \
-	intel_be_api.c
+	intel_drm_batchbuffer.c \
+	intel_drm_buffer.c \
+	intel_drm_fence.c \
+	intel_drm_api.c
 
 LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
 
diff --git a/src/gallium/winsys/drm/intel/gem/SConscript b/src/gallium/winsys/drm/intel/gem/SConscript
index ea8a2e5..26717f3 100644
--- a/src/gallium/winsys/drm/intel/gem/SConscript
+++ b/src/gallium/winsys/drm/intel/gem/SConscript
@@ -3,10 +3,10 @@ Import('*')
 env = drienv.Clone()
 
 inteldrm_sources = [
-    'intel_be_api.c',
-    'intel_be_batchbuffer.c',
-    'intel_be_context.c',
-    'intel_be_device.c',
+    'intel_drm_api.c',
+    'intel_drm_batchbuffer.c',
+    'intel_drm_buffer.c',
+    'intel_drm_fence.c',
 ]
 
 inteldrm = env.ConvenienceLibrary(
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_api.c b/src/gallium/winsys/drm/intel/gem/intel_be_api.c
deleted file mode 100644
index 3e90088..0000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_api.c
+++ /dev/null
@@ -1,36 +0,0 @@
-
-#include "intel_be_api.h"
-#include "i915simple/i915_winsys.h"
-#include "identity/id_drm.h"
-#include "trace/tr_drm.h"
-
-static void destroy(struct drm_api *api)
-{
-
-}
-
-struct drm_api intel_be_drm_api =
-{
-	/* intel_be_context.c */
-	.create_context = intel_be_create_context,
-	/* intel_be_device.c */
-	.create_screen = intel_be_create_screen,
-	.texture_from_shared_handle = intel_be_texture_from_shared_handle,
-	.shared_handle_from_texture = intel_be_shared_handle_from_texture,
-	.local_handle_from_texture = intel_be_local_handle_from_texture,
-	.destroy = destroy,
-};
-
-struct drm_api *
-drm_api_create()
-{
-#ifdef DEBUG
-#if 0
-	return identity_drm_create(&intel_be_drm_api);
-#else
-	return trace_drm_create(&intel_be_drm_api);
-#endif
-#else
-	return &intel_be_drm_api;
-#endif
-}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_api.h b/src/gallium/winsys/drm/intel/gem/intel_be_api.h
deleted file mode 100644
index f286b62..0000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_api.h
+++ /dev/null
@@ -1,18 +0,0 @@
-
-#ifndef _INTEL_BE_API_H_
-#define _INTEL_BE_API_H_
-
-#include "pipe/p_compiler.h"
-
-#include "state_tracker/drm_api.h"
-
-#include "intel_be_device.h"
-
-extern struct drm_api intel_be_drm_api;
-
-struct pipe_screen *intel_be_create_screen(struct drm_api *api, int drmFD,
-					   struct drm_create_screen_arg *arg);
-struct pipe_context *intel_be_create_context(struct drm_api *api,
-					     struct pipe_screen *screen);
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
deleted file mode 100644
index c4a7958..0000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
+++ /dev/null
@@ -1,156 +0,0 @@
-
-#include "i915simple/i915_debug.h"
-#include "intel_be_batchbuffer.h"
-#include "intel_be_context.h"
-#include "intel_be_device.h"
-#include "intel_be_fence.h"
-#include <errno.h>
-
-#include "util/u_memory.h"
-
-struct intel_be_batchbuffer *
-intel_be_batchbuffer_alloc(struct intel_be_context *intel)
-{
-	struct intel_be_batchbuffer *batch = CALLOC_STRUCT(intel_be_batchbuffer);
-
-
-	batch->base.buffer = NULL;
-	batch->base.winsys = &intel->base;
-	batch->base.map = NULL;
-	batch->base.ptr = NULL;
-	batch->base.size = 0;
-	batch->base.actual_size = intel->device->max_batch_size;
-	batch->base.relocs = 0;
-	batch->base.max_relocs = 100;/*INTEL_DEFAULT_RELOCS;*/
-
-	batch->intel = intel;
-	batch->device = intel->device;
-
-	intel_be_batchbuffer_reset(batch);
-
-	return batch;
-}
-
-void
-intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch)
-{
-	struct intel_be_context *intel = intel_be_context(batch->base.winsys);
-	struct intel_be_device *dev = intel->device;
-
-	if (batch->bo)
-		drm_intel_bo_unreference(batch->bo);
-	batch->bo = drm_intel_bo_alloc(dev->pools.gem,
-	                               "gallium3d_batch_buffer",
-	                               batch->base.actual_size,
-	                               4096);
-	drm_intel_bo_map(batch->bo, TRUE);
-	batch->base.map = batch->bo->virtual;
-
-	memset(batch->base.map, 0, batch->base.actual_size);
-	batch->base.ptr = batch->base.map;
-	batch->base.size = batch->base.actual_size - BATCH_RESERVED;
-	batch->base.relocs = 0;
-}
-
-int
-intel_be_offset_relocation(struct intel_be_batchbuffer *batch,
-			   unsigned pre_add,
-			   drm_intel_bo *bo,
-			   uint32_t read_domains,
-			   uint32_t write_domain)
-{
-	unsigned offset;
-	int ret = 0;
-
-	assert(batch->base.relocs < batch->base.max_relocs);
-
-	offset = (unsigned)(batch->base.ptr - batch->base.map);
-
-	ret = drm_intel_bo_emit_reloc(batch->bo, offset,
-	                              bo, pre_add,
-	                              read_domains,
-	                              write_domain);
-
-	((uint32_t*)batch->base.ptr)[0] = bo->offset + pre_add;
-	batch->base.ptr += 4;
-
-	if (!ret)
-		batch->base.relocs++;
-
-	return ret;
-}
-
-void
-intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
-			   struct intel_be_fence **fence)
-{
-	struct i915_batchbuffer *i915 = &batch->base;
-	unsigned used = 0;
-	int ret = 0;
-	int i;
-
-	assert(i915_batchbuffer_space(i915) >= 0);
-
-	used = batch->base.ptr - batch->base.map;
-	assert((used & 3) == 0);
-
-	if (used & 4) {
-		i915_batchbuffer_dword(i915, (0x0<<29)|(0x4<<23)|(1<<0)); // MI_FLUSH | FLUSH_MAP_CACHE;
-		i915_batchbuffer_dword(i915, (0x0<<29)|(0x0<<23)); // MI_NOOP
-		i915_batchbuffer_dword(i915, (0x0<<29)|(0xA<<23)); // MI_BATCH_BUFFER_END;
-	} else {
-		i915_batchbuffer_dword(i915, (0x0<<29)|(0x4<<23)|(1<<0)); //MI_FLUSH | FLUSH_MAP_CACHE;
-		i915_batchbuffer_dword(i915, (0x0<<29)|(0xA<<23)); // MI_BATCH_BUFFER_END;
-	}
-
-	used = batch->base.ptr - batch->base.map;
-
-	drm_intel_bo_unmap(batch->bo);
-
-	/* Do the sending to HW */
-	ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
-	assert(ret == 0);
-
-	if (batch->device->dump_cmd) {
-		unsigned *ptr;
-		drm_intel_bo_map(batch->bo, FALSE);
-		ptr = (unsigned*)batch->bo->virtual;
-
-		debug_printf("%s:\n", __func__);
-		for (i = 0; i < used / 4; i++, ptr++) {
-			debug_printf("\t%08x:    %08x\n", i*4, *ptr);
-		}
-
-		drm_intel_bo_unmap(batch->bo);
-	} else {
-		/* TODO figgure out why the gpu hangs if we don't run sync */
-		drm_intel_bo_map(batch->bo, FALSE);
-		drm_intel_bo_unmap(batch->bo);
-	}
-
-	intel_be_batchbuffer_reset(batch);
-
-	if (fence) {
-		if (*fence)
-			intel_be_fence_reference(fence, NULL);
-
-		(*fence) = CALLOC_STRUCT(intel_be_fence);
-		pipe_reference_init(&(*fence)->reference, 1);
-		(*fence)->bo = NULL;
-	}
-}
-
-void
-intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch)
-{
-
-}
-
-void
-intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch)
-{
-	if (batch->bo)
-		drm_intel_bo_unreference(batch->bo);
-
-	free(batch);
-}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h
deleted file mode 100644
index 195bf8d..0000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h
+++ /dev/null
@@ -1,55 +0,0 @@
-
-#ifndef INTEL_BE_BATCHBUFFER_H
-#define INTEL_BE_BATCHBUFFER_H
-
-#include "i915simple/i915_batch.h"
-
-#include "drm.h"
-#include "intel_bufmgr.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
-
-struct intel_be_context;
-struct intel_be_device;
-struct intel_be_fence;
-
-struct intel_be_batchbuffer
-{
-	struct i915_batchbuffer base;
-
-	struct intel_be_context *intel;
-	struct intel_be_device *device;
-
-	drm_intel_bo *bo;
-};
-
-struct intel_be_batchbuffer *
-intel_be_batchbuffer_alloc(struct intel_be_context *intel);
-
-void
-intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch);
-
-void
-intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch);
-
-void
-intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
-			   struct intel_be_fence **fence);
-
-void
-intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch);
-
-int
-intel_be_offset_relocation(struct intel_be_batchbuffer *batch,
-			   unsigned pre_add,
-			   drm_intel_bo *bo,
-			   uint32_t read_domains,
-			   uint32_t write_doman);
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c
deleted file mode 100644
index ff4518f..0000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_context.c
+++ /dev/null
@@ -1,117 +0,0 @@
-
-#include "pipe/p_screen.h"
-
-#include "softpipe/sp_winsys.h"
-
-#include "intel_be_device.h"
-#include "intel_be_context.h"
-#include "intel_be_batchbuffer.h"
-
-#include "i915_drm.h"
-
-#include "intel_be_api.h"
-
-static struct i915_batchbuffer *
-intel_be_batch_get(struct i915_winsys *sws)
-{
-	struct intel_be_context *intel = intel_be_context(sws);
-	return &intel->batch->base;
-}
-
-static void
-intel_be_batch_reloc(struct i915_winsys *sws,
-		     struct pipe_buffer *buf,
-		     unsigned access_flags,
-		     unsigned delta)
-{
-	struct intel_be_context *intel = intel_be_context(sws);
-	drm_intel_bo *bo = intel_bo(buf);
-	int ret;
-	uint32_t read = 0;
-	uint32_t write = 0;
-
-	if (access_flags & I915_BUFFER_ACCESS_WRITE) {
-		write = I915_GEM_DOMAIN_RENDER;
-		read = I915_GEM_DOMAIN_RENDER;
-	}
-
-	if (access_flags & I915_BUFFER_ACCESS_READ) {
-		read |= I915_GEM_DOMAIN_SAMPLER;
-	}
-
-	ret = intel_be_offset_relocation(intel->batch,
-	                                 delta,
-	                                 bo,
-	                                 read,
-	                                 write);
-    assert(ret == 0);
-
-	/* TODO change return type */
-	/* return ret; */
-}
-
-static void
-intel_be_batch_flush(struct i915_winsys *sws,
-		     struct pipe_fence_handle **fence)
-{
-	struct intel_be_context *intel = intel_be_context(sws);
-	struct intel_be_fence **f = (struct intel_be_fence **)fence;
-
-	intel_be_batchbuffer_flush(intel->batch, f);
-}
-
-
-/*
- * Misc functions.
- */
-
-static void
-intel_be_destroy_context(struct i915_winsys *winsys)
-{
-	struct intel_be_context *intel = intel_be_context(winsys);
-
-	intel_be_batchbuffer_free(intel->batch);
-
-	free(intel);
-}
-
-boolean
-intel_be_init_context(struct intel_be_context *intel, struct intel_be_device *device)
-{
-	assert(intel);
-	assert(device);
-	intel->device = device;
-
-	intel->base.batch_get = intel_be_batch_get;
-	intel->base.batch_reloc = intel_be_batch_reloc;
-	intel->base.batch_flush = intel_be_batch_flush;
-
-	intel->base.destroy = intel_be_destroy_context;
-
-	intel->batch = intel_be_batchbuffer_alloc(intel);
-
-	return true;
-}
-
-struct pipe_context *
-intel_be_create_context(struct drm_api *api, struct pipe_screen *screen)
-{
-	struct intel_be_context *intel;
-	struct pipe_context *pipe;
-	struct intel_be_device *device = intel_be_device(screen->winsys);
-
-	intel = (struct intel_be_context *)malloc(sizeof(*intel));
-	memset(intel, 0, sizeof(*intel));
-
-	intel_be_init_context(intel, device);
-
-	if (device->softpipe)
-		pipe = softpipe_create(screen);
-	else
-		pipe = i915_create_context(screen, &device->base, &intel->base);
-
-	if (pipe)
-		pipe->priv = intel;
-
-	return pipe;
-}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.h b/src/gallium/winsys/drm/intel/gem/intel_be_context.h
deleted file mode 100644
index 5a36966..0000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_context.h
+++ /dev/null
@@ -1,31 +0,0 @@
-
-#ifndef INTEL_BE_CONTEXT_H
-#define INTEL_BE_CONTEXT_H
-
-#include "i915simple/i915_winsys.h"
-
-struct intel_be_context
-{
-	/** Interface to i915simple driver */
-	struct i915_winsys base;
-
-	struct intel_be_device *device;
-	struct intel_be_batchbuffer *batch;
-};
-
-static INLINE struct intel_be_context *
-intel_be_context(struct i915_winsys *sws)
-{
-	return (struct intel_be_context *)sws;
-}
-
-/**
- * Intialize a allocated intel_be_context struct.
- *
- * Remember to set the hardware_* functions.
- */
-boolean
-intel_be_init_context(struct intel_be_context *intel,
-		      struct intel_be_device *device);
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
deleted file mode 100644
index 2d8e9f1..0000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c
+++ /dev/null
@@ -1,474 +0,0 @@
-
-#include "intel_be_device.h"
-
-#include "pipe/internal/p_winsys_screen.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
-#include "util/u_memory.h"
-#include "util/u_debug.h"
-#include "util/u_math.h"
-
-#include "intel_be_fence.h"
-
-#include "i915simple/i915_winsys.h"
-#include "softpipe/sp_winsys.h"
-
-#include "intel_be_api.h"
-#include <stdio.h>
-
-#define I915_TILING_X 1
-
-/*
- * Buffer
- */
-
-static void *
-intel_be_buffer_map(struct pipe_winsys *winsys,
-		    struct pipe_buffer *buf,
-		    unsigned flags)
-{
-	struct intel_be_buffer *buffer = intel_be_buffer(buf);
-	drm_intel_bo *bo = intel_bo(buf);
-	int write = 0;
-	int ret = 0;
-
-        if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
-           /* Remove this when drm_intel_bo_map supports DONTBLOCK 
-            */
-           return NULL;
-        }
-
-	if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
-		write = 1;
-
-	if (buffer->map_count)
-		goto out;
-
-	if (buffer->map_gtt)
-		ret = drm_intel_gem_bo_map_gtt(bo);
-	else
-		ret = drm_intel_bo_map(bo, write);
-
-	buffer->ptr = bo->virtual;
-
-out:
-	if (ret)
-		return NULL;
-
-	buffer->map_count++;
-	return buffer->ptr;
-}
-
-static void
-intel_be_buffer_unmap(struct pipe_winsys *winsys,
-		      struct pipe_buffer *buf)
-{
-	struct intel_be_buffer *buffer = intel_be_buffer(buf);
-
-	if (--buffer->map_count)
-		return;
-
-	if (buffer->map_gtt)
-		drm_intel_gem_bo_unmap_gtt(intel_bo(buf));
-	else
-		drm_intel_bo_unmap(intel_bo(buf));
-}
-
-static void
-intel_be_buffer_destroy(struct pipe_buffer *buf)
-{
-	drm_intel_bo_unreference(intel_bo(buf));
-	free(buf);
-}
-
-static struct pipe_buffer *
-intel_be_buffer_create(struct pipe_winsys *winsys,
-		       unsigned alignment,
-		       unsigned usage,
-		       unsigned size)
-{
-	struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
-	struct intel_be_device *dev = intel_be_device(winsys);
-	drm_intel_bufmgr *pool;
-	char *name;
-
-	if (!buffer)
-		return NULL;
-
-	pipe_reference_init(&buffer->base.reference, 1);
-	buffer->base.alignment = alignment;
-	buffer->base.usage = usage;
-	buffer->base.size = size;
-	buffer->flinked = FALSE;
-	buffer->flink = 0;
-	buffer->map_gtt = FALSE;
-
-	if (usage & I915_BUFFER_USAGE_SCANOUT) {
-		/* Scanout buffer */
-		name = "gallium3d_scanout";
-		pool = dev->pools.gem;
-	} else if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
-		/* Local buffer */
-		name = "gallium3d_local";
-		pool = dev->pools.gem;
-	} else if (usage & PIPE_BUFFER_USAGE_CUSTOM) {
-		/* For vertex buffers */
-		name = "gallium3d_internal_vertex";
-		pool = dev->pools.gem;
-	} else {
-		/* Regular buffers */
-		name = "gallium3d_regular";
-		pool = dev->pools.gem;
-	}
-
-	buffer->bo = drm_intel_bo_alloc(pool, name, size, alignment);
-	if (usage & I915_BUFFER_USAGE_SCANOUT) {
-		unsigned tiling = I915_TILING_X;
-		unsigned stride = 2048 * 4; /* TODO do something smarter here */
-		drm_intel_bo_set_tiling(buffer->bo, &tiling, stride);
-		buffer->map_gtt = TRUE;
-	}
-
-	if (!buffer->bo)
-		goto err;
-
-	return &buffer->base;
-
-err:
-	free(buffer);
-	return NULL;
-}
-
-static struct pipe_buffer *
-intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
-{
-	struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
-	struct intel_be_device *dev = intel_be_device(winsys);
-	int ret;
-
-	if (!buffer)
-		return NULL;
-
-	pipe_reference_init(&buffer->base.reference, 1);
-	buffer->base.alignment = 0;
-	buffer->base.usage = 0;
-	buffer->base.size = bytes;
-
-	buffer->bo = drm_intel_bo_alloc(dev->pools.gem,
-	                                "gallium3d_user_buffer",
-	                                bytes, 0);
-
-	if (!buffer->bo)
-		goto err;
-
-	ret = drm_intel_bo_subdata(buffer->bo,
-	                           0, bytes, ptr);
-
-	if (ret)
-		goto err;
-
-	return &buffer->base;
-
-err:
-	free(buffer);
-	return NULL;
-}
-
-static struct pipe_buffer *
-intel_be_surface_buffer_create(struct pipe_winsys *winsys,
-                               unsigned width, unsigned height,
-                               enum pipe_format format,
-                               unsigned usage,
-                               unsigned tex_usage,
-                               unsigned *stride)
-{
-	struct pipe_format_block block;
-	unsigned buf_usage = 0;
-	unsigned buf_stride = 0;
-	unsigned buf_size = 0;
-
-	pf_get_block(format, &block);
-	buf_stride = pf_get_stride(&block, width);
-	buf_stride = align(buf_stride, 64);
-
-	if (tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) {
-		/* TODO more checks */
-		assert(buf_stride <= 2048*4);
-		assert(height % 8 == 0);
-		buf_stride = 2048 * 4;
-		buf_usage |= I915_BUFFER_USAGE_SCANOUT;
-	}
-
-	buf_size = buf_stride * height;
-	*stride = buf_stride;
-
-	return intel_be_buffer_create(winsys,
-	                              0,
-	                              buf_usage,
-	                              buf_size);
-}
-
-static struct pipe_buffer *
-intel_be_buffer_from_handle(struct drm_api *api,
-                            struct pipe_screen *screen,
-                            const char* name, unsigned handle)
-{
-	struct intel_be_device *dev = intel_be_device(screen->winsys);
-	struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
-
-	if (!buffer)
-		return NULL;
-
-	buffer->bo = drm_intel_bo_gem_create_from_name(dev->pools.gem, name, handle);
-
-	if (!buffer->bo)
-		goto err;
-
-	pipe_reference_init(&buffer->base.reference, 1);
-	buffer->base.screen = screen;
-	buffer->base.alignment = buffer->bo->align;
-	buffer->base.usage = PIPE_BUFFER_USAGE_GPU_READ |
-	                     PIPE_BUFFER_USAGE_GPU_WRITE |
-	                     PIPE_BUFFER_USAGE_CPU_READ |
-	                     PIPE_BUFFER_USAGE_CPU_WRITE;
-	buffer->base.size = buffer->bo->size;
-
-	return &buffer->base;
-
-err:
-	free(buffer);
-	return NULL;
-}
-
-struct pipe_texture *
-intel_be_texture_from_shared_handle(struct drm_api *api,
-                                    struct pipe_screen *screen,
-                                    struct pipe_texture *templ,
-                                    const char* name,
-                                    unsigned pitch,
-                                    unsigned handle)
-{
-	struct pipe_buffer *buffer;
-
-	buffer = intel_be_buffer_from_handle(api,
-	                                     screen,
-	                                     name,
-	                                     handle);
-	if (!buffer)
-		return NULL;
-
-	return screen->texture_blanket(screen, templ, &pitch, buffer);
-}
-
-static boolean
-intel_be_get_texture_buffer(struct drm_api *api,
-                            struct pipe_texture *texture,
-                            struct pipe_buffer **buffer,
-                            unsigned *stride)
-{
-	struct intel_be_device *dev;
-
-	if (!texture)
-		return FALSE;
-
-	dev = intel_be_device(texture->screen->winsys);
-	if (dev->softpipe)
-		return softpipe_get_texture_buffer(texture, buffer, stride);
-	else
-		return i915_get_texture_buffer(texture, buffer, stride);
-}
-
-boolean
-intel_be_shared_handle_from_texture(struct drm_api *api,
-                                    struct pipe_screen *screen,
-                                    struct pipe_texture *texture,
-                                    unsigned *pitch,
-                                    unsigned *handle)
-{
-	struct pipe_buffer *buffer = NULL;
-	struct intel_be_buffer *buf;
-	if (!intel_be_get_texture_buffer(api,
-	                                 texture,
-	                                 &buffer,
-	                                 pitch))
-		return FALSE;
-
-	buf = intel_be_buffer(buffer);
-	if (!buf->flinked) {
-		if (drm_intel_bo_flink(intel_bo(buffer), &buf->flink))
-			return FALSE;
-		buf->flinked = TRUE;
-	}
-
-	*handle = buf->flink;
-
-	pipe_buffer_reference(&buffer, NULL);
-
-	return TRUE;
-}
-
-boolean
-intel_be_local_handle_from_texture(struct drm_api *api,
-                                   struct pipe_screen *screen,
-                                   struct pipe_texture *texture,
-                                   unsigned *pitch,
-                                   unsigned *handle)
-{
-	struct pipe_buffer *buffer = NULL;
-	if (!intel_be_get_texture_buffer(api,
-	                                 texture,
-	                                 &buffer,
-	                                 pitch))
-		return FALSE;
-
-	*handle = intel_bo(buffer)->handle;
-
-	pipe_buffer_reference(&buffer, NULL);
-
-	return TRUE;
-}
-
-/*
- * Fence
- */
-
-static void
-intel_be_fence_refunref(struct pipe_winsys *sws,
-			 struct pipe_fence_handle **ptr,
-			 struct pipe_fence_handle *fence)
-{
-	struct intel_be_fence **p = (struct intel_be_fence **)ptr;
-	struct intel_be_fence *f = (struct intel_be_fence *)fence;
-
-        intel_be_fence_reference(p, f);
-}
-
-static int
-intel_be_fence_signalled(struct pipe_winsys *sws,
-			 struct pipe_fence_handle *fence,
-			 unsigned flag)
-{
-	assert(0);
-
-	return 0;
-}
-
-static int
-intel_be_fence_finish(struct pipe_winsys *sws,
-		      struct pipe_fence_handle *fence,
-		      unsigned flag)
-{
-	struct intel_be_fence *f = (struct intel_be_fence *)fence;
-
-	/* fence already expired */
-	if (!f->bo)
-		return 0;
-
-	drm_intel_bo_wait_rendering(f->bo);
-	drm_intel_bo_unreference(f->bo);
-	f->bo = NULL;
-
-	return 0;
-}
-
-/*
- * Misc functions
- */
-
-static void
-intel_be_destroy_winsys(struct pipe_winsys *winsys)
-{
-	struct intel_be_device *dev = intel_be_device(winsys);
-
-	drm_intel_bufmgr_destroy(dev->pools.gem);
-
-	free(dev);
-}
-
-boolean
-intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
-{
-	dev->fd = fd;
-	dev->id = id;
-	dev->max_batch_size = 16 * 4096;
-	dev->max_vertex_size = 128 * 4096;
-
-	dev->base.buffer_create = intel_be_buffer_create;
-	dev->base.user_buffer_create = intel_be_user_buffer_create;
-	dev->base.buffer_map = intel_be_buffer_map;
-	dev->base.buffer_unmap = intel_be_buffer_unmap;
-	dev->base.buffer_destroy = intel_be_buffer_destroy;
-
-	/* Used by softpipe */
-	dev->base.surface_buffer_create = intel_be_surface_buffer_create;
-
-	dev->base.fence_reference = intel_be_fence_refunref;
-	dev->base.fence_signalled = intel_be_fence_signalled;
-	dev->base.fence_finish = intel_be_fence_finish;
-
-	dev->base.destroy = intel_be_destroy_winsys;
-
-	dev->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size);
-
-	dev->softpipe = debug_get_bool_option("INTEL_SOFTPIPE", FALSE);
-	dev->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
-
-	return true;
-}
-
-static void
-intel_be_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);
-}
-
-struct pipe_screen *
-intel_be_create_screen(struct drm_api *api, int drmFD,
-		       struct drm_create_screen_arg *arg)
-{
-	struct intel_be_device *dev;
-	struct pipe_screen *screen;
-	unsigned int deviceID;
-
-	if (arg != NULL) {
-		switch(arg->mode) {
-		case DRM_CREATE_NORMAL:
-			break;
-		default:
-			return NULL;
-		}
-	}
-
-	/* Allocate the private area */
-	dev = malloc(sizeof(*dev));
-	if (!dev)
-		return NULL;
-	memset(dev, 0, sizeof(*dev));
-
-	intel_be_get_device_id(&deviceID);
-	intel_be_init_device(dev, drmFD, deviceID);
-
-	if (dev->softpipe) {
-		screen = softpipe_create_screen(&dev->base);
-	} else
-		screen = i915_create_screen(&dev->base, deviceID);
-
-	return screen;
-}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.h b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
deleted file mode 100644
index 15916b0..0000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h
+++ /dev/null
@@ -1,107 +0,0 @@
-
-#ifndef INTEL_DRM_DEVICE_H
-#define INTEL_DRM_DEVICE_H
-
-#include "pipe/internal/p_winsys_screen.h"
-#include "pipe/p_context.h"
-
-#include "drm.h"
-#include "intel_bufmgr.h"
-
-struct drm_api;
-
-/*
- * Device
- */
-
-struct intel_be_device
-{
-	struct pipe_winsys base;
-
-	boolean softpipe;
-	boolean dump_cmd;
-
-	int fd; /**< Drm file discriptor */
-
-	unsigned id;
-
-	size_t max_batch_size;
-	size_t max_vertex_size;
-
-	struct {
-		drm_intel_bufmgr *gem;
-	} pools;
-};
-
-static INLINE struct intel_be_device *
-intel_be_device(struct pipe_winsys *winsys)
-{
-	return (struct intel_be_device *)winsys;
-}
-
-boolean
-intel_be_init_device(struct intel_be_device *device, int fd, unsigned id);
-
-/*
- * Buffer
- */
-
-struct intel_be_buffer {
-	struct pipe_buffer base;
-	void *ptr;
-	unsigned map_count;
-	boolean map_gtt;
-
-	drm_intel_bo *bo;
-	boolean flinked;
-	unsigned flink;
-};
-
-/**
- * Create a texture from a shared drm handle.
- */
-struct pipe_texture *
-intel_be_texture_from_shared_handle(struct drm_api *api,
-                                    struct pipe_screen *screen,
-                                    struct pipe_texture *templ,
-                                    const char* name,
-                                    unsigned pitch,
-                                    unsigned handle);
-
-/**
- * Gets a shared handle from a texture.
- *
- * If texture is destroyed handle may become invalid.
- */
-boolean
-intel_be_shared_handle_from_texture(struct drm_api *api,
-                                    struct pipe_screen *screen,
-                                    struct pipe_texture *texture,
-                                    unsigned *pitch,
-                                    unsigned *handle);
-
-/**
- * Gets the local handle from a texture. As used by KMS.
- *
- * If texture is destroyed handle may become invalid.
- */
-boolean
-intel_be_local_handle_from_texture(struct drm_api *api,
-                                   struct pipe_screen *screen,
-                                   struct pipe_texture *texture,
-                                   unsigned *pitch,
-                                   unsigned *handle);
-
-static INLINE struct intel_be_buffer *
-intel_be_buffer(struct pipe_buffer *buf)
-{
-	return (struct intel_be_buffer *)buf;
-}
-
-static INLINE drm_intel_bo *
-intel_bo(struct pipe_buffer *buf)
-{
-	return intel_be_buffer(buf)->bo;
-}
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_fence.h b/src/gallium/winsys/drm/intel/gem/intel_be_fence.h
deleted file mode 100644
index a8abb01..0000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_fence.h
+++ /dev/null
@@ -1,34 +0,0 @@
-
-#ifndef INTEL_BE_FENCE_H
-#define INTEL_BE_FENCE_H
-
-#include "pipe/p_defines.h"
-
-#include "drm.h"
-#include "intel_bufmgr.h"
-
-/**
- * Because gem does not have fence's we have to create our own fences.
- *
- * They work by keeping the batchbuffer around and checking if that has
- * been idled. If bo is NULL fence has expired.
- */
-struct intel_be_fence
-{
-	struct pipe_reference reference;
-	drm_intel_bo *bo;
-};
-
-static INLINE void
-intel_be_fence_reference(struct intel_be_fence **ptr, struct intel_be_fence *f)
-{
-	struct intel_be_fence *old_fence = *ptr;
-
-        if (pipe_reference((struct pipe_reference**)ptr, &f->reference)) {
-		if (old_fence->bo)
-			drm_intel_bo_unreference(old_fence->bo);
-		free(old_fence);
-	}
-}
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
new file mode 100644
index 0000000..4c5a1d2
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
@@ -0,0 +1,202 @@
+
+#include "state_tracker/drm_api.h"
+
+#include "intel_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915simple/i915_context.h"
+#include "i915simple/i915_screen.h"
+
+
+/*
+ * Helper functions
+ */
+
+
+static void
+intel_drm_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 intel_buffer *
+intel_drm_buffer_from_handle(struct intel_drm_winsys *idws,
+                             const char* name, unsigned handle)
+{
+   struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
+
+   if (!buf)
+      return NULL;
+
+   buf->magic = 0xDEAD1337;
+   buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, name, handle);
+   buf->flinked = TRUE;
+   buf->flink = handle;
+
+   if (!buf->bo)
+      goto err;
+
+   return (struct intel_buffer *)buf;
+
+err:
+   FREE(buf);
+   return NULL;
+}
+
+
+/*
+ * Exported functions
+ */
+
+
+static struct pipe_texture *
+intel_drm_texture_from_shared_handle(struct drm_api *api,
+                                     struct pipe_screen *screen,
+                                     struct pipe_texture *templ,
+                                     const char* name,
+                                     unsigned pitch,
+                                     unsigned handle)
+{
+   struct intel_drm_winsys *idws = intel_drm_winsys(i915_screen(screen)->iws);
+   struct intel_buffer *buffer;
+
+   buffer = intel_drm_buffer_from_handle(idws, name, handle);
+   if (!buffer)
+      return NULL;
+
+   return i915_texture_blanket_intel(screen, templ, pitch, buffer);
+}
+
+static boolean
+intel_drm_shared_handle_from_texture(struct drm_api *api,
+                                     struct pipe_screen *screen,
+                                     struct pipe_texture *texture,
+                                     unsigned *pitch,
+                                     unsigned *handle)
+{
+   struct intel_drm_buffer *buf = NULL;
+   struct intel_buffer *buffer = NULL;
+   if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
+      return FALSE;
+
+   buf = intel_drm_buffer(buffer);
+   if (!buf->flinked) {
+      if (drm_intel_bo_flink(buf->bo, &buf->flink))
+         return FALSE;
+      buf->flinked = TRUE;
+   }
+
+   *handle = buf->flink;
+
+   return TRUE;
+}
+
+static boolean
+intel_drm_local_handle_from_texture(struct drm_api *api,
+                                    struct pipe_screen *screen,
+                                    struct pipe_texture *texture,
+                                    unsigned *pitch,
+                                    unsigned *handle)
+{
+   struct intel_buffer *buffer = NULL;
+   if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
+      return FALSE;
+
+   *handle = intel_drm_buffer(buffer)->bo->handle;
+
+   return TRUE;
+}
+
+static void
+intel_drm_winsys_destroy(struct intel_winsys *iws)
+{
+   struct intel_drm_winsys *idws = intel_drm_winsys(iws);
+
+   drm_intel_bufmgr_destroy(idws->pools.gem);
+
+   FREE(idws);
+}
+
+static struct pipe_screen *
+intel_drm_create_screen(struct drm_api *api, int drmFD,
+                        struct drm_create_screen_arg *arg)
+{
+   struct intel_drm_winsys *idws;
+   unsigned int deviceID;
+
+   if (arg != NULL) {
+      switch(arg->mode) {
+      case DRM_CREATE_NORMAL:
+         break;
+      default:
+         return NULL;
+      }
+   }
+
+   idws = CALLOC_STRUCT(intel_drm_winsys);
+   if (!idws)
+      return NULL;
+
+   intel_drm_get_device_id(&deviceID);
+
+   intel_drm_winsys_init_batchbuffer_functions(idws);
+   intel_drm_winsys_init_buffer_functions(idws);
+   intel_drm_winsys_init_fence_functions(idws);
+
+   idws->fd = drmFD;
+   idws->id = deviceID;
+   idws->max_batch_size = 16 * 4096;
+
+   idws->base.destroy = intel_drm_winsys_destroy;
+
+   idws->pools.gem = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size);
+
+   idws->softpipe = FALSE;
+   idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
+
+   return i915_create_screen(&idws->base, deviceID);
+}
+
+static struct pipe_context *
+intel_drm_create_context(struct drm_api *api, struct pipe_screen *screen)
+{
+   return i915_create_context(screen);
+}
+
+static void
+destroy(struct drm_api *api)
+{
+
+}
+
+struct drm_api intel_drm_api =
+{
+   .create_context = intel_drm_create_context,
+   .create_screen = intel_drm_create_screen,
+   .texture_from_shared_handle = intel_drm_texture_from_shared_handle,
+   .shared_handle_from_texture = intel_drm_shared_handle_from_texture,
+   .local_handle_from_texture = intel_drm_local_handle_from_texture,
+   .destroy = destroy,
+};
+
+struct drm_api *
+drm_api_create()
+{
+   return &intel_drm_api;
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c
new file mode 100644
index 0000000..77b3fec
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c
@@ -0,0 +1,211 @@
+
+#include "intel_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915_drm.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
+
+struct intel_drm_batchbuffer
+{
+   struct intel_batchbuffer base;
+
+   size_t actual_size;
+
+   drm_intel_bo *bo;
+};
+
+static INLINE struct intel_drm_batchbuffer *
+intel_drm_batchbuffer(struct intel_batchbuffer *batch)
+{
+   return (struct intel_drm_batchbuffer *)batch;
+}
+
+static void
+intel_drm_batchbuffer_reset(struct intel_drm_batchbuffer *batch)
+{
+   struct intel_drm_winsys *idws = intel_drm_winsys(batch->base.iws);
+
+   if (batch->bo)
+      drm_intel_bo_unreference(batch->bo);
+   batch->bo = drm_intel_bo_alloc(idws->pools.gem,
+                                  "gallium3d_batchbuffer",
+                                  batch->actual_size,
+                                  4096);
+   drm_intel_bo_map(batch->bo, TRUE);
+   batch->base.map = batch->bo->virtual;
+
+   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 intel_batchbuffer *
+intel_drm_batchbuffer_create(struct intel_winsys *iws)
+{
+   struct intel_drm_winsys *idws = intel_drm_winsys(iws);
+   struct intel_drm_batchbuffer *batch = CALLOC_STRUCT(intel_drm_batchbuffer);
+
+   batch->base.map = NULL;
+   batch->base.ptr = NULL;
+   batch->base.size = 0;
+
+   batch->base.relocs = 0;
+   batch->base.max_relocs = 100;/*INTEL_DEFAULT_RELOCS;*/
+
+   batch->base.iws = iws;
+
+   batch->actual_size = idws->max_batch_size;
+
+   intel_drm_batchbuffer_reset(batch);
+
+   return &batch->base;
+}
+
+static int
+intel_drm_batchbuffer_reloc(struct intel_batchbuffer *ibatch,
+                            struct intel_buffer *buffer,
+                            enum intel_buffer_usage usage,
+                            unsigned pre_add)
+{
+   struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch);
+   unsigned write_domain = 0;
+   unsigned read_domain = 0;
+   unsigned offset;
+   int ret = 0;
+
+   assert(batch->base.relocs < batch->base.max_relocs);
+
+   if (usage == INTEL_USAGE_SAMPLER) {
+      write_domain = 0;
+      read_domain = I915_GEM_DOMAIN_SAMPLER;
+
+   } else if (usage == INTEL_USAGE_RENDER) {
+      write_domain = I915_GEM_DOMAIN_RENDER;
+      read_domain = I915_GEM_DOMAIN_RENDER;
+
+   } else if (usage == INTEL_USAGE_2D_TARGET) {
+      write_domain = I915_GEM_DOMAIN_RENDER;
+      read_domain = I915_GEM_DOMAIN_RENDER;
+
+   } else if (usage == INTEL_USAGE_2D_SOURCE) {
+      write_domain = 0;
+      read_domain = I915_GEM_DOMAIN_RENDER;
+
+   } else if (usage == INTEL_USAGE_VERTEX) {
+      write_domain = 0;
+      read_domain = I915_GEM_DOMAIN_VERTEX;
+
+   } else {
+      assert(0);
+      return -1;
+   }
+
+   offset = (unsigned)(batch->base.ptr - batch->base.map);
+
+   ret = drm_intel_bo_emit_reloc(batch->bo, offset,
+                                 intel_bo(buffer), pre_add,
+                                 read_domain,
+                                 write_domain);
+
+   ((uint32_t*)batch->base.ptr)[0] = intel_bo(buffer)->offset + pre_add;
+   batch->base.ptr += 4;
+
+   if (!ret)
+      batch->base.relocs++;
+
+   return ret;
+}
+
+static void
+intel_drm_batchbuffer_flush(struct intel_batchbuffer *ibatch,
+                            struct pipe_fence_handle **fence)
+{
+   struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch);
+   unsigned used = 0;
+   int ret = 0;
+   int i;
+
+   assert(intel_batchbuffer_space(ibatch) >= 0);
+
+   used = batch->base.ptr - batch->base.map;
+   assert((used & 3) == 0);
+
+   if (used & 4) {
+      // MI_FLUSH | FLUSH_MAP_CACHE;
+      intel_batchbuffer_dword(ibatch, (0x0<<29)|(0x4<<23)|(1<<0));
+      // MI_NOOP
+      intel_batchbuffer_dword(ibatch, (0x0<<29)|(0x0<<23));
+      // MI_BATCH_BUFFER_END;
+      intel_batchbuffer_dword(ibatch, (0x0<<29)|(0xA<<23));
+   } else {
+      //MI_FLUSH | FLUSH_MAP_CACHE;
+      intel_batchbuffer_dword(ibatch, (0x0<<29)|(0x4<<23)|(1<<0));
+      // MI_BATCH_BUFFER_END;
+      intel_batchbuffer_dword(ibatch, (0x0<<29)|(0xA<<23));
+   }
+
+   used = batch->base.ptr - batch->base.map;
+
+   drm_intel_bo_unmap(batch->bo);
+
+   /* Do the sending to HW */
+   ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
+   assert(ret == 0);
+
+   if (intel_drm_winsys(ibatch->iws)->dump_cmd) {
+      unsigned *ptr;
+      drm_intel_bo_map(batch->bo, FALSE);
+      ptr = (unsigned*)batch->bo->virtual;
+
+      debug_printf("%s:\n", __func__);
+      for (i = 0; i < used / 4; i++, ptr++) {
+         debug_printf("\t%08x:    %08x\n", i*4, *ptr);
+      }
+
+      drm_intel_bo_unmap(batch->bo);
+   } else {
+      /* TODO figgure out why the gpu hangs if we don't run sync */
+      drm_intel_bo_map(batch->bo, FALSE);
+      drm_intel_bo_unmap(batch->bo);
+   }
+
+   if (fence) {
+      ibatch->iws->fence_reference(ibatch->iws, fence, NULL);
+
+#if 0
+      (*fence) = intel_drm_fence_create(batch->bo);
+#else
+      /* we run synced to GPU so just pass null */
+      (*fence) = intel_drm_fence_create(NULL);
+#endif
+   }
+
+   intel_drm_batchbuffer_reset(batch);
+}
+
+static void
+intel_drm_batchbuffer_destroy(struct intel_batchbuffer *ibatch)
+{
+   struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch);
+
+   if (batch->bo)
+      drm_intel_bo_unreference(batch->bo);
+
+   free(batch);
+}
+
+void intel_drm_winsys_init_batchbuffer_functions(struct intel_drm_winsys *idws)
+{
+   idws->base.batchbuffer_create = intel_drm_batchbuffer_create;
+   idws->base.batchbuffer_reloc = intel_drm_batchbuffer_reloc;
+   idws->base.batchbuffer_flush = intel_drm_batchbuffer_flush;
+   idws->base.batchbuffer_destroy = intel_drm_batchbuffer_destroy;
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c b/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c
new file mode 100644
index 0000000..e017cd2
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c
@@ -0,0 +1,134 @@
+
+#include "intel_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915_drm.h"
+
+static struct intel_buffer *
+intel_drm_buffer_create(struct intel_winsys *iws,
+                        unsigned size, unsigned alignment,
+                        enum intel_buffer_type type)
+{
+   struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
+   struct intel_drm_winsys *idws = intel_drm_winsys(iws);
+   drm_intel_bufmgr *pool;
+   char *name;
+
+   if (!buf)
+      return NULL;
+
+   buf->magic = 0xDEAD1337;
+   buf->flinked = FALSE;
+   buf->flink = 0;
+   buf->map_gtt = FALSE;
+
+   if (type == INTEL_NEW_TEXTURE) {
+      name = "gallium3d_texture";
+      pool = idws->pools.gem;
+   } else if (type == INTEL_NEW_VERTEX) {
+      name = "gallium3d_vertex";
+      pool = idws->pools.gem;
+   } else if (type == INTEL_NEW_SCANOUT) {
+      name = "gallium3d_scanout";
+      pool = idws->pools.gem;
+      buf->map_gtt = TRUE;
+   } else {
+      assert(0);
+      name = "gallium3d_unknown";
+      pool = idws->pools.gem;
+   }
+
+   buf->bo = drm_intel_bo_alloc(pool, name, size, alignment);
+
+   if (!buf->bo)
+      goto err;
+
+   return (struct intel_buffer *)buf;
+
+err:
+   assert(0);
+   FREE(buf);
+   return NULL;
+}
+
+static int
+intel_drm_buffer_set_fence_reg(struct intel_winsys *iws,
+                               struct intel_buffer *buffer,
+                               unsigned stride,
+                               enum intel_buffer_tile tile)
+{
+   assert(I915_TILING_NONE == INTEL_TILE_NONE);
+   assert(I915_TILING_X == INTEL_TILE_X);
+   assert(I915_TILING_Y == INTEL_TILE_Y);
+
+   return drm_intel_bo_set_tiling(intel_bo(buffer), &tile, stride);
+}
+
+static void *
+intel_drm_buffer_map(struct intel_winsys *iws,
+                     struct intel_buffer *buffer,
+                     boolean write)
+{
+   struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
+   drm_intel_bo *bo = intel_bo(buffer);
+   int ret = 0;
+
+   assert(bo);
+
+   if (buf->map_count)
+      goto out;
+
+   if (buf->map_gtt)
+      ret = drm_intel_gem_bo_map_gtt(bo);
+   else
+      ret = drm_intel_bo_map(bo, write);
+
+   buf->ptr = bo->virtual;
+
+   assert(ret == 0);
+out:
+   if (ret)
+      return NULL;
+
+   buf->map_count++;
+   return buf->ptr;
+}
+
+static void
+intel_drm_buffer_unmap(struct intel_winsys *iws,
+                       struct intel_buffer *buffer)
+{
+   struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
+
+   if (--buf->map_count)
+      return;
+
+   if (buf->map_gtt)
+      drm_intel_gem_bo_unmap_gtt(intel_bo(buffer));
+   else
+      drm_intel_bo_unmap(intel_bo(buffer));
+}
+
+static void
+intel_drm_buffer_destroy(struct intel_winsys *iws,
+                         struct intel_buffer *buffer)
+{
+   drm_intel_bo_unreference(intel_bo(buffer));
+
+#ifdef DEBUG
+   intel_drm_buffer(buffer)->magic = 0;
+   intel_drm_buffer(buffer)->bo = NULL;
+#endif
+
+   FREE(buffer);
+}
+
+void
+intel_drm_winsys_init_buffer_functions(struct intel_drm_winsys *idws)
+{
+   idws->base.buffer_create = intel_drm_buffer_create;
+   idws->base.buffer_set_fence_reg = intel_drm_buffer_set_fence_reg;
+   idws->base.buffer_map = intel_drm_buffer_map;
+   idws->base.buffer_unmap = intel_drm_buffer_unmap;
+   idws->base.buffer_destroy = intel_drm_buffer_destroy;
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c b/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c
new file mode 100644
index 0000000..e70bfe7
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c
@@ -0,0 +1,81 @@
+
+#include "intel_drm_winsys.h"
+#include "util/u_memory.h"
+#include "pipe/p_refcnt.h"
+
+/**
+ * Because gem does not have fence's we have to create our own fences.
+ *
+ * They work by keeping the batchbuffer around and checking if that has
+ * been idled. If bo is NULL fence has expired.
+ */
+struct intel_drm_fence
+{
+   struct pipe_reference reference;
+   drm_intel_bo *bo;
+};
+
+
+struct pipe_fence_handle *
+intel_drm_fence_create(drm_intel_bo *bo)
+{
+   struct intel_drm_fence *fence = CALLOC_STRUCT(intel_drm_fence);
+
+   pipe_reference_init(&fence->reference, 1);
+   /* bo is null if fence already expired */
+   if (bo) {
+      drm_intel_bo_reference(bo);
+      fence->bo = bo;
+   }
+
+   return (struct pipe_fence_handle *)fence;
+}
+
+static void
+intel_drm_fence_reference(struct intel_winsys *iws,
+                          struct pipe_fence_handle **ptr,
+                          struct pipe_fence_handle *fence)
+{
+   struct intel_drm_fence *old = (struct intel_drm_fence *)*ptr;
+   struct intel_drm_fence *f = (struct intel_drm_fence *)fence;
+
+   if (pipe_reference((struct pipe_reference**)ptr, &f->reference)) {
+      if (old->bo)
+         drm_intel_bo_unreference(old->bo);
+      FREE(old);
+   }
+}
+
+static int
+intel_drm_fence_signalled(struct intel_winsys *iws,
+                          struct pipe_fence_handle *fence)
+{
+   assert(0);
+
+   return 0;
+}
+
+static int
+intel_drm_fence_finish(struct intel_winsys *iws,
+                       struct pipe_fence_handle *fence)
+{
+   struct intel_drm_fence *f = (struct intel_drm_fence *)fence;
+
+   /* fence already expired */
+   if (!f->bo)
+      return 0;
+
+   drm_intel_bo_wait_rendering(f->bo);
+   drm_intel_bo_unreference(f->bo);
+   f->bo = NULL;
+
+   return 0;
+}
+
+void
+intel_drm_winsys_init_fence_functions(struct intel_drm_winsys *idws)
+{
+   idws->base.fence_reference = intel_drm_fence_reference;
+   idws->base.fence_signalled = intel_drm_fence_signalled;
+   idws->base.fence_finish = intel_drm_fence_finish;
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h b/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h
new file mode 100644
index 0000000..415c45f
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h
@@ -0,0 +1,78 @@
+
+#ifndef INTEL_DRM_WINSYS_H
+#define INTEL_DRM_WINSYS_H
+
+#include "i915simple/intel_batchbuffer.h"
+
+#include "drm.h"
+#include "intel_bufmgr.h"
+
+
+/*
+ * Winsys
+ */
+
+
+struct intel_drm_winsys
+{
+   struct intel_winsys base;
+
+   boolean softpipe;
+   boolean dump_cmd;
+
+   int fd; /**< Drm file discriptor */
+
+   unsigned id;
+
+   size_t max_batch_size;
+
+   struct {
+      drm_intel_bufmgr *gem;
+   } pools;
+};
+
+static INLINE struct intel_drm_winsys *
+intel_drm_winsys(struct intel_winsys *iws)
+{
+   return (struct intel_drm_winsys *)iws;
+}
+
+struct intel_drm_winsys * intel_drm_winsys_create(int fd, unsigned pci_id);
+struct pipe_fence_handle * intel_drm_fence_create(drm_intel_bo *bo);
+
+void intel_drm_winsys_init_batchbuffer_functions(struct intel_drm_winsys *idws);
+void intel_drm_winsys_init_buffer_functions(struct intel_drm_winsys *idws);
+void intel_drm_winsys_init_fence_functions(struct intel_drm_winsys *idws);
+
+
+/*
+ * Buffer
+ */
+
+
+struct intel_drm_buffer {
+   unsigned magic;
+
+   drm_intel_bo *bo;
+
+   void *ptr;
+   unsigned map_count;
+   boolean map_gtt;
+
+   boolean flinked;
+   unsigned flink;
+};
+
+static INLINE struct intel_drm_buffer *
+intel_drm_buffer(struct intel_buffer *buffer)
+{
+   return (struct intel_drm_buffer *)buffer;
+}
+
+static INLINE drm_intel_bo *
+intel_bo(struct intel_buffer *buffer)
+{
+   return intel_drm_buffer(buffer)->bo;
+}
+
+#endif




More information about the mesa-commit mailing list