summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/drm/intel/gem
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/drm/intel/gem')
-rw-r--r--src/gallium/winsys/drm/intel/gem/Makefile16
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_api.c15
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_api.h14
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c139
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h55
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_context.c118
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_context.h31
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.c316
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.h92
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_fence.h38
10 files changed, 834 insertions, 0 deletions
diff --git a/src/gallium/winsys/drm/intel/gem/Makefile b/src/gallium/winsys/drm/intel/gem/Makefile
new file mode 100644
index 0000000000..7ab1a2a771
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/Makefile
@@ -0,0 +1,16 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = inteldrm
+
+C_SOURCES = \
+ intel_be_batchbuffer.c \
+ intel_be_context.c \
+ intel_be_device.c \
+ intel_be_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/intel/gem/intel_be_api.c b/src/gallium/winsys/drm/intel/gem/intel_be_api.c
new file mode 100644
index 0000000000..3f71c25441
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_api.c
@@ -0,0 +1,15 @@
+
+#include "intel_be_api.h"
+#include "i915simple/i915_winsys.h"
+
+struct drm_api drm_api_hocks =
+{
+ /* intel_be_context.c */
+ .create_context = intel_be_create_context,
+ /* intel_be_device.c */
+ .create_screen = intel_be_create_screen,
+ .buffer_from_texture = i915_get_texture_buffer,
+ .buffer_from_handle = intel_be_buffer_from_handle,
+ .handle_from_buffer = intel_be_handle_from_buffer,
+ .global_handle_from_buffer = intel_be_global_handle_from_buffer,
+};
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_api.h b/src/gallium/winsys/drm/intel/gem/intel_be_api.h
new file mode 100644
index 0000000000..73e458d4ba
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_api.h
@@ -0,0 +1,14 @@
+
+#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"
+
+struct pipe_screen *intel_be_create_screen(int drmFD, int pciID);
+struct pipe_context *intel_be_create_context(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
new file mode 100644
index 0000000000..0137433785
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
@@ -0,0 +1,139 @@
+
+#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 = 500;/*INTEL_DEFAULT_RELOCS;*/
+
+ batch->base.map = malloc(batch->base.actual_size);
+ memset(batch->base.map, 0, batch->base.actual_size);
+
+ batch->base.ptr = batch->base.map;
+
+ 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);
+
+ 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;
+
+ batch->bo = drm_intel_bo_alloc(dev->pools.gem,
+ "gallium3d_batch_buffer",
+ batch->base.actual_size, 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;
+
+ 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_subdata(batch->bo, 0, used, batch->base.map);
+ ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
+
+ assert(ret == 0);
+
+ intel_be_batchbuffer_reset(batch);
+
+ if (fence) {
+ if (*fence)
+ intel_be_fence_unreference(*fence);
+
+ (*fence) = CALLOC_STRUCT(intel_be_fence);
+ (*fence)->refcount = 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->base.map);
+ 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
new file mode 100644
index 0000000000..195bf8dee7
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h
@@ -0,0 +1,55 @@
+
+#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
new file mode 100644
index 0000000000..bb6f1b916c
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c
@@ -0,0 +1,118 @@
+
+#include "pipe/p_screen.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_VERTEX;
+ }
+
+ 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;
+
+ if (fence && *fence)
+ assert(0);
+
+ 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 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 0
+ pipe = intel_create_softpipe(intel, screen->winsys);
+#else
+ pipe = i915_create_context(screen, &device->base, &intel->base);
+#endif
+
+ 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
new file mode 100644
index 0000000000..5a369669c0
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.h
@@ -0,0 +1,31 @@
+
+#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
new file mode 100644
index 0000000000..2e191a6d12
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
@@ -0,0 +1,316 @@
+
+#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 "intel_be_fence.h"
+
+#include "i915simple/i915_winsys.h"
+
+#include "intel_be_api.h"
+
+/*
+ * Buffer
+ */
+
+static void *
+intel_be_buffer_map(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf,
+ unsigned flags)
+{
+ drm_intel_bo *bo = intel_bo(buf);
+ int write = 0;
+ int ret;
+
+ 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;
+
+ ret = drm_intel_bo_map(bo, write);
+
+ if (ret)
+ return NULL;
+
+ return bo->virtual;
+}
+
+static void
+intel_be_buffer_unmap(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf)
+{
+ drm_intel_bo_unmap(intel_bo(buf));
+}
+
+static void
+intel_be_buffer_destroy(struct pipe_winsys *winsys,
+ 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;
+
+ buffer->base.refcount = 1;
+ buffer->base.alignment = alignment;
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+ buffer->flinked = FALSE;
+ buffer->flink = 0;
+
+ 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 (!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;
+
+ buffer->base.refcount = 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;
+}
+
+struct pipe_buffer *
+intel_be_buffer_from_handle(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;
+
+ buffer->base.refcount = 1;
+ 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;
+}
+
+boolean
+intel_be_handle_from_buffer(struct pipe_screen *screen,
+ struct pipe_buffer *buffer,
+ unsigned *handle)
+{
+ drm_intel_bo *bo;
+
+ if (!buffer)
+ return FALSE;
+
+ *handle = intel_bo(buffer)->handle;
+ return TRUE;
+}
+
+boolean
+intel_be_global_handle_from_buffer(struct pipe_screen *screen,
+ struct pipe_buffer *buffer,
+ unsigned *handle)
+{
+ struct intel_be_buffer *buf = intel_be_buffer(buffer);
+
+ if (!buffer)
+ return FALSE;
+
+ if (!buf->flinked) {
+ if (drm_intel_bo_flink(intel_bo(buffer), &buf->flink))
+ return FALSE;
+ buf->flinked = TRUE;
+ }
+
+ *handle = buf->flink;
+ 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;
+
+ assert(p);
+
+ if (f)
+ intel_be_fence_reference(f);
+
+ if (*p)
+ intel_be_fence_unreference(*p);
+
+ *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;
+
+ /* Not used anymore */
+ dev->base.surface_buffer_create = NULL;
+
+ 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);
+
+ return true;
+}
+
+struct pipe_screen *
+intel_be_create_screen(int drmFD, int deviceID)
+{
+ struct intel_be_device *dev;
+ struct pipe_screen *screen;
+
+ /* Allocate the private area */
+ dev = malloc(sizeof(*dev));
+ if (!dev)
+ return NULL;
+ memset(dev, 0, sizeof(*dev));
+
+ intel_be_init_device(dev, drmFD, deviceID);
+
+ 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
new file mode 100644
index 0000000000..47d2176cb4
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
@@ -0,0 +1,92 @@
+
+#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"
+
+/*
+ * Device
+ */
+
+struct intel_be_device
+{
+ struct pipe_winsys base;
+
+ 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;
+ drm_intel_bo *bo;
+ boolean flinked;
+ unsigned flink;
+};
+
+/**
+ * Create a be buffer from a drm bo handle.
+ *
+ * Takes a reference.
+ */
+struct pipe_buffer *
+intel_be_buffer_from_handle(struct pipe_screen *screen,
+ const char* name, unsigned handle);
+
+/**
+ * Gets a handle from a buffer.
+ *
+ * If buffer is destroyed handle may become invalid.
+ */
+boolean
+intel_be_handle_from_buffer(struct pipe_screen *screen,
+ struct pipe_buffer *buffer,
+ unsigned *handle);
+
+/**
+ * Gets the global handle from a buffer.
+ *
+ * If buffer is destroyed handle may become invalid.
+ */
+boolean
+intel_be_global_handle_from_buffer(struct pipe_screen *screen,
+ struct pipe_buffer *buffer,
+ 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
new file mode 100644
index 0000000000..0fe18f66f8
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_fence.h
@@ -0,0 +1,38 @@
+
+#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
+{
+ uint32_t refcount;
+ drm_intel_bo *bo;
+};
+
+static INLINE void
+intel_be_fence_reference(struct intel_be_fence *f)
+{
+ f->refcount++;
+}
+
+static INLINE void
+intel_be_fence_unreference(struct intel_be_fence *f)
+{
+ if (!--f->refcount) {
+ if (f->bo)
+ drm_intel_bo_unreference(f->bo);
+ free(f);
+ }
+}
+
+#endif