Mesa (gallium-0.2): intel: Add a none working GEM backend for intel

Jakob Bornecrantz wallbraker at kemper.freedesktop.org
Wed Jan 14 11:29:48 UTC 2009


Module: Mesa
Branch: gallium-0.2
Commit: 529f86fb113529d1ecf113dc45efade7fe185f94
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=529f86fb113529d1ecf113dc45efade7fe185f94

Author: Jakob Bornecrantz <wallbraker at gmail.com>
Date:   Mon Jan  5 11:44:56 2009 +0100

intel: Add a none working GEM backend for intel

---

 src/gallium/winsys/drm/intel/gem/Makefile          |   18 ++
 src/gallium/winsys/drm/intel/gem/Makefile.template |   64 +++++
 .../winsys/drm/intel/gem/intel_be_batchbuffer.c    |  120 +++++++++
 .../winsys/drm/intel/gem/intel_be_batchbuffer.h    |   55 ++++
 .../winsys/drm/intel/gem/intel_be_context.c        |   79 ++++++
 .../winsys/drm/intel/gem/intel_be_context.h        |   48 ++++
 src/gallium/winsys/drm/intel/gem/intel_be_device.c |  260 ++++++++++++++++++++
 src/gallium/winsys/drm/intel/gem/intel_be_device.h |   70 ++++++
 src/gallium/winsys/drm/intel/gem/intel_be_fence.h  |   38 +++
 9 files changed, 752 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 0000000..b25fc25
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/Makefile
@@ -0,0 +1,18 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = inteldrm
+
+C_SOURCES = \
+	intel_be_batchbuffer.c \
+	intel_be_context.c \
+	intel_be_device.c
+
+
+include ./Makefile.template
+
+DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \
+                && pkg-config libdrm --atleast-version=2.3.1 \
+                && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
+symlinks:
+
diff --git a/src/gallium/winsys/drm/intel/gem/Makefile.template b/src/gallium/winsys/drm/intel/gem/Makefile.template
new file mode 100644
index 0000000..557070a
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/Makefile.template
@@ -0,0 +1,64 @@
+# -*-makefile-*-
+
+
+# We still have a dependency on the "dri" buffer manager.  Most likely
+# the interface can be reused in non-dri environments, and also as a
+# frontend to simpler memory managers.
+#
+COMMON_SOURCES =
+
+OBJECTS = $(C_SOURCES:.c=.o) \
+	$(CPP_SOURCES:.cpp=.o) \
+	$(ASM_SOURCES:.S=.o)
+
+
+### Include directories
+INCLUDES = \
+	-I. \
+	-I$(TOP)/src/gallium/include \
+	-I$(TOP)/src/gallium/auxiliary \
+	-I$(TOP)/src/gallium/drivers \
+	-I$(TOP)/include \
+	$(DRIVER_INCLUDES)
+
+
+##### RULES #####
+
+.c.o:
+	$(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
+
+.cpp.o:
+	$(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@
+
+.S.o:
+	$(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES)  $< -o $@
+
+
+##### TARGETS #####
+
+default: depend symlinks $(LIBNAME)
+
+
+$(LIBNAME): $(OBJECTS) Makefile Makefile.template
+	$(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS)
+
+
+depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
+	rm -f depend
+	touch depend
+	$(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \
+		$(ASM_SOURCES) 2> /dev/null
+
+
+# Emacs tags
+tags:
+	etags `find . -name \*.[ch]` `find ../include`
+
+
+# Remove .o and backup files
+clean::
+	-rm -f *.o */*.o *~ *.so *.a *~ server/*.o $(SYMLINKS)
+	-rm -f depend depend.bak
+
+
+include depend
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 0000000..2399910
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
@@ -0,0 +1,120 @@
+
+#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 = 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 NULL;
+}
+
+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->base.max_relocs = INTEL_DEFAULT_RELOCS;
+
+	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);
+	batch->base.ptr += 4;
+
+/*
+	TODO: Enable this when we submit batch buffers to HW
+	ret = drm_intel_bo_emit_reloc(bo, pre_add,
+	                              batch->bo, offset,
+	                              read_domains,
+	                              write_domain);
+*/
+
+	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;
+
+	assert(i915_batchbuffer_space(i915) >= 0);
+
+	/* TODO: submit stuff to HW */
+
+	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 0000000..195bf8d
--- /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 0000000..92fc2dd
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c
@@ -0,0 +1,79 @@
+
+#include "intel_be_device.h"
+#include "intel_be_context.h"
+#include "intel_be_batchbuffer.h"
+
+#include "i915_drm.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;
+	}
+
+	if (access_flags & I915_BUFFER_ACCESS_READ) {
+		read = I915_GEM_DOMAIN_SAMPLER |
+		       I915_GEM_DOMAIN_INSTRUCTION |
+		       I915_GEM_DOMAIN_VERTEX;
+	}
+
+	ret = intel_be_offset_relocation(intel->batch,
+	                                 delta,
+	                                 bo,
+	                                 read,
+	                                 write);
+	/* 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);
+}
+
+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->batch = intel_be_batchbuffer_alloc(intel);
+
+	return true;
+}
+
+void
+intel_be_destroy_context(struct intel_be_context *intel)
+{
+	intel_be_batchbuffer_free(intel->batch);
+}
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 0000000..9cee1a4
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.h
@@ -0,0 +1,48 @@
+
+#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;
+
+	/*
+	 * Hardware lock functions.
+	 *
+	 * Needs to be filled in by the winsys.
+	 */
+	void (*hardware_lock)(struct intel_be_context *context);
+	void (*hardware_unlock)(struct intel_be_context *context);
+	boolean (*hardware_locked)(struct intel_be_context *context);
+};
+
+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);
+
+/**
+ * Destroy a intel_be_context.
+ *
+ * Does not free the struct that is up to the winsys.
+ */
+void
+intel_be_destroy_context(struct intel_be_context *intel);
+
+#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 0000000..cf0c140
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
@@ -0,0 +1,260 @@
+
+#include "intel_be_device.h"
+
+#include "pipe/p_winsys.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_screen.h"
+
+
+/**
+ *  Turn a pipe winsys into an intel/pipe winsys:
+ */
+static INLINE struct intel_be_device *
+intel_be_device(struct pipe_winsys *winsys)
+{
+	return (struct intel_be_device *)winsys;
+}
+
+/*
+ * 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_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;
+
+	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 intel_be_device *dev,
+			    const char* name, unsigned handle)
+{
+	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;
+}
+
+/*
+ * 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
+ */
+
+boolean
+intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
+{
+	dev->fd = fd;
+	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_alloc = NULL;
+	dev->base.surface_alloc_storage = NULL;
+	dev->base.surface_release = 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->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size);
+
+	dev->screen = i915_create_screen(&dev->base, id);
+
+	return true;
+}
+
+void
+intel_be_destroy_device(struct intel_be_device *dev)
+{
+	drm_intel_bufmgr_destroy(dev->pools.gem);
+}
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 0000000..53d6353
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
@@ -0,0 +1,70 @@
+
+#ifndef INTEL_DRM_DEVICE_H
+#define INTEL_DRM_DEVICE_H
+
+#include "pipe/p_winsys.h"
+#include "pipe/p_context.h"
+
+#include "drm.h"
+#include "intel_bufmgr.h"
+
+/*
+ * Device
+ */
+
+struct intel_be_device
+{
+	struct pipe_winsys base;
+
+	/**
+	 * Hw level screen
+	 */
+	struct pipe_screen *screen;
+
+	int fd; /**< Drm file discriptor */
+
+	size_t max_batch_size;
+	size_t max_vertex_size;
+
+	struct {
+		drm_intel_bufmgr *gem;
+	} pools;
+};
+
+boolean
+intel_be_init_device(struct intel_be_device *device, int fd, unsigned id);
+
+void
+intel_be_destroy_device(struct intel_be_device *dev);
+
+/*
+ * Buffer
+ */
+
+struct intel_be_buffer {
+	struct pipe_buffer base;
+	drm_intel_bo *bo;
+};
+
+/**
+ * Create a be buffer from a drm bo handle
+ *
+ * Takes a reference
+ */
+struct pipe_buffer *
+intel_be_buffer_from_handle(struct intel_be_device *device,
+                            const char* name, 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 0000000..0fe18f6
--- /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




More information about the mesa-commit mailing list