summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/drm
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/drm')
-rw-r--r--src/gallium/winsys/drm/Makefile.template4
-rw-r--r--src/gallium/winsys/drm/intel/dri/SConscript8
-rw-r--r--src/gallium/winsys/drm/intel/egl/Makefile1
-rw-r--r--src/gallium/winsys/drm/intel/gem/Makefile8
-rw-r--r--src/gallium/winsys/drm/intel/gem/SConscript8
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_api.c37
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_api.h18
-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.c120
-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.c369
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.h108
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_fence.h34
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_api.c203
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c229
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c148
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_fence.c81
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h78
-rw-r--r--src/gallium/winsys/drm/intel/xorg/Makefile1
-rw-r--r--src/gallium/winsys/drm/intel/xorg/intel_xorg.c12
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c127
-rw-r--r--src/gallium/winsys/drm/nouveau/xorg/Makefile61
-rw-r--r--src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c149
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.c17
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.h5
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.c73
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.h8
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.c94
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.h20
-rw-r--r--src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c12
31 files changed, 1134 insertions, 1124 deletions
diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template
index 985e5a861f..9635c3c50e 100644
--- a/src/gallium/winsys/drm/Makefile.template
+++ b/src/gallium/winsys/drm/Makefile.template
@@ -83,7 +83,9 @@ default: depend symlinks $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME)
$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template
$(MKLIB) -noprefix -o $@ \
- $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS)
+ $(OBJECTS) $(PIPE_DRIVERS) \
+ -Wl,--start-group $(MESA_MODULES) -Wl,--end-group \
+ $(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS)
$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS)
$(MKLIB) -o $(LIBNAME_EGL) \
diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript
index e14e96e32f..f973811072 100644
--- a/src/gallium/winsys/drm/intel/dri/SConscript
+++ b/src/gallium/winsys/drm/intel/dri/SConscript
@@ -2,15 +2,19 @@ Import('*')
env = drienv.Clone()
+env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+
drivers = [
+ st_dri,
+ inteldrm,
softpipe,
i915simple,
trace,
- inteldrm
]
-env.SharedLibrary(
+env.LoadableModule(
target ='i915_dri.so',
source = COMMON_GALLIUM_SOURCES,
LIBS = drivers + mesa + auxiliaries + env['LIBS'],
+ SHLIBPREFIX = '',
)
diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile
index c5217ad2d6..490baded66 100644
--- a/src/gallium/winsys/drm/intel/egl/Makefile
+++ b/src/gallium/winsys/drm/intel/egl/Makefile
@@ -8,6 +8,7 @@ PIPE_DRIVERS = \
$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
$(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a
DRIVER_SOURCES =
diff --git a/src/gallium/winsys/drm/intel/gem/Makefile b/src/gallium/winsys/drm/intel/gem/Makefile
index 7ab1a2a771..0d6d4e37db 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 ea8a2e55f6..26717f391f 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 dd5f814da3..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_api.c
+++ /dev/null
@@ -1,37 +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,
- .buffer_from_texture = intel_be_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,
- .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 f286b62eb8..0000000000
--- 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 d5e63c3bae..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
+++ /dev/null
@@ -1,139 +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 = 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_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->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
deleted file mode 100644
index 195bf8dee7..0000000000
--- 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 db84f9af51..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_context.c
+++ /dev/null
@@ -1,120 +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_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 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 5a369669c0..0000000000
--- 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 e3630f5d12..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c
+++ /dev/null
@@ -1,369 +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 "intel_be_fence.h"
-
-#include "i915simple/i915_winsys.h"
-#include "softpipe/sp_winsys.h"
-
-#include "intel_be_api.h"
-#include <stdio.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_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;
-
- 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;
-
- 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;
-}
-
-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);
-}
-
-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;
-}
-
-boolean
-intel_be_handle_from_buffer(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_buffer *buffer,
- unsigned *handle)
-{
- if (!buffer)
- return FALSE;
-
- *handle = intel_bo(buffer)->handle;
- return TRUE;
-}
-
-boolean
-intel_be_global_handle_from_buffer(struct drm_api *api,
- 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;
-
- 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;
-
- /* 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);
-
- dev->softpipe = debug_get_bool_option("INTEL_SOFTPIPE", 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 56d95bd7fe..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h
+++ /dev/null
@@ -1,108 +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;
-
- 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;
-};
-
-/*
- * Wrapper for driver get_texture_buffer functions.
- */
-boolean
-intel_be_get_texture_buffer(struct drm_api *api,
- struct pipe_texture *texture,
- struct pipe_buffer **buffer,
- unsigned *stride);
-
-/**
- * Create a be buffer from a drm bo handle.
- *
- * Takes a reference.
- */
-struct pipe_buffer *
-intel_be_buffer_from_handle(struct drm_api *api,
- 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 drm_api *api,
- 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 drm_api *api,
- 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
deleted file mode 100644
index a8abb01a9e..0000000000
--- 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 0000000000..0fd5cdd969
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
@@ -0,0 +1,203 @@
+
+#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"
+
+#include "trace/tr_drm.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 trace_drm_create(&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 0000000000..ebd1b607b7
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c
@@ -0,0 +1,229 @@
+
+#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
+
+#undef INTEL_RUN_SYNC
+#undef INTEL_MAP_BATCHBUFFER
+
+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);
+
+#ifdef INTEL_MAP_BATCHBUFFER
+ drm_intel_bo_map(batch->bo, TRUE);
+ batch->base.map = batch->bo->virtual;
+#endif
+
+ 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->actual_size = idws->max_batch_size;
+
+#ifdef INTEL_MAP_BATCHBUFFER
+ batch->base.map = NULL;
+#else
+ batch->base.map = MALLOC(batch->actual_size);
+#endif
+ batch->base.ptr = NULL;
+ batch->base.size = 0;
+
+ batch->base.relocs = 0;
+ batch->base.max_relocs = 300;/*INTEL_DEFAULT_RELOCS;*/
+
+ batch->base.iws = iws;
+
+ 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;
+
+#ifdef INTEL_MAP_BATCHBUFFER
+ drm_intel_bo_unmap(batch->bo);
+#else
+ drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
+#endif
+
+ /* 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 {
+#ifdef INTEL_RUN_SYNC
+ drm_intel_bo_map(batch->bo, FALSE);
+ drm_intel_bo_unmap(batch->bo);
+#endif
+ }
+
+ if (fence) {
+ ibatch->iws->fence_reference(ibatch->iws, fence, NULL);
+
+#ifdef INTEL_RUN_SYNC
+ /* we run synced to GPU so just pass null */
+ (*fence) = intel_drm_fence_create(NULL);
+#else
+ (*fence) = intel_drm_fence_create(batch->bo);
+#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);
+
+#ifndef INTEL_MAP_BATCHBUFFER
+ FREE(batch->base.map);
+#endif
+ 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 0000000000..0030f915a3
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c
@@ -0,0 +1,148 @@
+
+#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;
+ buf->map_gtt = TRUE;
+ } 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 int
+intel_drm_buffer_write(struct intel_winsys *iws,
+ struct intel_buffer *buffer,
+ const void *data,
+ size_t size,
+ size_t offset)
+{
+ struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
+
+ return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
+}
+
+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_write = intel_drm_buffer_write;
+ 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 0000000000..e70bfe7b44
--- /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 0000000000..415c45feea
--- /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
diff --git a/src/gallium/winsys/drm/intel/xorg/Makefile b/src/gallium/winsys/drm/intel/xorg/Makefile
index d51cca8d21..9e56853b02 100644
--- a/src/gallium/winsys/drm/intel/xorg/Makefile
+++ b/src/gallium/winsys/drm/intel/xorg/Makefile
@@ -19,6 +19,7 @@ LIBS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
$(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(GALLIUM_AUXILIARIES)
diff --git a/src/gallium/winsys/drm/intel/xorg/intel_xorg.c b/src/gallium/winsys/drm/intel/xorg/intel_xorg.c
index 46a7971f60..369dc356cf 100644
--- a/src/gallium/winsys/drm/intel/xorg/intel_xorg.c
+++ b/src/gallium/winsys/drm/intel/xorg/intel_xorg.c
@@ -47,8 +47,8 @@ static SymTabRec intel_xorg_chipsets[] = {
};
static PciChipsets intel_xorg_pci_devices[] = {
- {PCI_MATCH_ANY, PCI_MATCH_ANY, RES_SHARED_VGA},
- {-1, -1, RES_UNDEFINED}
+ {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
+ {-1, -1, NULL}
};
static XF86ModuleVersionInfo intel_xorg_version = {
@@ -105,12 +105,6 @@ intel_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
xf86AddDriver(&modesetting, module, HaveDriverFuncs);
/*
- * Tell the loader about symbols from other modules that this module
- * might refer to.
- */
- xorg_tracker_loader_ref_sym_lists();
-
- /*
* The return value must be non-NULL on success even though there
* is no TearDownProc.
*/
@@ -140,7 +134,7 @@ intel_xorg_pci_probe(DriverPtr driver,
NULL, NULL, NULL, NULL, NULL);
if (scrn != NULL) {
scrn->driverVersion = 1;
- scrn->driverName = "modesetting";
+ scrn->driverName = "i915";
scrn->name = "modesetting";
scrn->Probe = NULL;
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
index 3167ccfdc1..117ca6059b 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
@@ -12,51 +12,37 @@
#include "nouveau/nouveau_screen.h"
static struct pipe_surface *
-dri_surface_from_handle(struct drm_api *api, struct pipe_screen *screen,
- unsigned handle,
- enum pipe_format format,
- unsigned width,
- unsigned height,
- unsigned pitch)
+dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
+ unsigned handle, enum pipe_format format,
+ unsigned width, unsigned height, unsigned pitch)
{
- struct pipe_surface *surface = NULL;
- struct pipe_texture *texture = NULL;
- struct pipe_texture templat;
- struct pipe_buffer *buf = NULL;
-
- buf = api->buffer_from_handle(api, screen, "front buffer", handle);
- if (!buf)
- return NULL;
-
- memset(&templat, 0, sizeof(templat));
- templat.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY |
- NOUVEAU_TEXTURE_USAGE_LINEAR;
- templat.target = PIPE_TEXTURE_2D;
- templat.last_level = 0;
- templat.depth[0] = 1;
- templat.format = format;
- templat.width[0] = width;
- templat.height[0] = height;
- pf_get_block(templat.format, &templat.block);
-
- texture = screen->texture_blanket(screen,
- &templat,
- &pitch,
- buf);
-
- /* we don't need the buffer from this point on */
- pipe_buffer_reference(&buf, NULL);
-
- if (!texture)
- return NULL;
-
- surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- /* we don't need the texture from this point on */
- pipe_texture_reference(&texture, NULL);
- return surface;
+ struct pipe_surface *ps = NULL;
+ struct pipe_texture *pt = NULL;
+ struct pipe_texture tmpl;
+
+ memset(&tmpl, 0, sizeof(tmpl));
+ tmpl.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY |
+ NOUVEAU_TEXTURE_USAGE_LINEAR;
+ tmpl.target = PIPE_TEXTURE_2D;
+ tmpl.last_level = 0;
+ tmpl.depth[0] = 1;
+ tmpl.format = format;
+ tmpl.width[0] = width;
+ tmpl.height[0] = height;
+ pf_get_block(tmpl.format, &tmpl.block);
+
+ pt = api->texture_from_shared_handle(api, pscreen, &tmpl,
+ "front buffer", pitch, handle);
+ if (!pt)
+ return NULL;
+
+ ps = pscreen->get_tex_surface(pscreen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ /* we don't need the texture from this point on */
+ pipe_texture_reference(&pt, NULL);
+ return ps;
}
static struct pipe_surface *
@@ -126,7 +112,7 @@ nouveau_drm_create_screen(struct drm_api *api, int fd,
return NULL;
}
- if (arg->mode == DRM_CREATE_DRI1) {
+ if (arg && arg->mode == DRM_CREATE_DRI1) {
struct nouveau_dri *nvdri = dri1->ddx_info;
enum pipe_format format;
@@ -205,16 +191,10 @@ nouveau_drm_create_context(struct drm_api *api, struct pipe_screen *pscreen)
return nvws->pctx[i];
}
-static boolean
-nouveau_drm_pb_from_pt(struct drm_api *api, struct pipe_texture *pt,
- struct pipe_buffer **ppb, unsigned *stride)
-{
- return false;
-}
-
-static struct pipe_buffer *
-nouveau_drm_pb_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
- const char *name, unsigned handle)
+static struct pipe_texture *
+nouveau_drm_pt_from_name(struct drm_api *api, struct pipe_screen *pscreen,
+ struct pipe_texture *templ, const char *name,
+ unsigned stride, unsigned handle)
{
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct pipe_buffer *pb;
@@ -238,41 +218,42 @@ nouveau_drm_pb_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
PIPE_BUFFER_USAGE_CPU_READ_WRITE;
pb->size = nouveau_bo(pb)->size;
- return pb;
+ return pscreen->texture_blanket(pscreen, templ, &stride, pb);
}
static boolean
-nouveau_drm_handle_from_pb(struct drm_api *api, struct pipe_screen *pscreen,
- struct pipe_buffer *pb, unsigned *handle)
+nouveau_drm_name_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
+ struct pipe_texture *pt, unsigned *stride,
+ unsigned *handle)
{
- struct nouveau_bo *bo = nouveau_bo(pb);
+ struct nouveau_miptree *mt = nouveau_miptree(pt);
- if (!bo)
- return FALSE;
+ if (!mt || !mt->bo)
+ return false;
- *handle = bo->handle;
- return TRUE;
+ return nouveau_bo_handle_get(mt->bo, handle) == 0;
}
static boolean
-nouveau_drm_name_from_pb(struct drm_api *api, struct pipe_screen *pscreen,
- struct pipe_buffer *pb, unsigned *handle)
+nouveau_drm_handle_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
+ struct pipe_texture *pt, unsigned *stride,
+ unsigned *handle)
{
- struct nouveau_bo *bo = nouveau_bo(pb);
+ struct nouveau_miptree *mt = nouveau_miptree(pt);
- if (!bo)
- return FALSE;
+ if (!mt || !mt->bo)
+ return false;
- return nouveau_bo_handle_get(bo, handle) == 0;
+ *handle = mt->bo->handle;
+ return true;
}
struct drm_api drm_api_hooks = {
.create_screen = nouveau_drm_create_screen,
.create_context = nouveau_drm_create_context,
- .buffer_from_texture = nouveau_drm_pb_from_pt,
- .buffer_from_handle = nouveau_drm_pb_from_handle,
- .handle_from_buffer = nouveau_drm_handle_from_pb,
- .global_handle_from_buffer = nouveau_drm_name_from_pb,
+ .texture_from_shared_handle = nouveau_drm_pt_from_name,
+ .shared_handle_from_texture = nouveau_drm_name_from_pt,
+ .local_handle_from_texture = nouveau_drm_handle_from_pt,
};
struct drm_api *
diff --git a/src/gallium/winsys/drm/nouveau/xorg/Makefile b/src/gallium/winsys/drm/nouveau/xorg/Makefile
new file mode 100644
index 0000000000..f0d3b337e8
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/xorg/Makefile
@@ -0,0 +1,61 @@
+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/nouveau/drm/libnouveaudrm.a \
+ $(TOP)/src/gallium/drivers/nv04/libnv04.a \
+ $(TOP)/src/gallium/drivers/nv10/libnv10.a \
+ $(TOP)/src/gallium/drivers/nv20/libnv20.a \
+ $(TOP)/src/gallium/drivers/nv30/libnv30.a \
+ $(TOP)/src/gallium/drivers/nv40/libnv40.a \
+ $(TOP)/src/gallium/drivers/nv50/libnv50.a \
+ $(TOP)/src/gallium/drivers/nouveau/libnouveau.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_nouveau
+
+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/nouveau/xorg/nouveau_xorg.c b/src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c
new file mode 100644
index 0000000000..a669b3080a
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c
@@ -0,0 +1,149 @@
+/*
+ * 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 nouveau_xorg_identify(int flags);
+static Bool nouveau_xorg_pci_probe(DriverPtr driver, int entity_num,
+ struct pci_device *device,
+ intptr_t match_data);
+
+static const struct pci_id_match nouveau_xorg_device_match[] = {
+ { 0x10de, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
+ 0x00030000, 0x00ffffff, 0 },
+ { 0x12d2, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
+ 0x00030000, 0x00ffffff, 0 },
+ {0, 0, 0},
+};
+
+static SymTabRec nouveau_xorg_chipsets[] = {
+ {PCI_MATCH_ANY, "NVIDIA Graphics Device"},
+ {-1, NULL}
+};
+
+static PciChipsets nouveau_xorg_pci_devices[] = {
+ {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
+ {-1, -1, NULL}
+};
+
+static XF86ModuleVersionInfo nouveau_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",
+ nouveau_xorg_identify,
+ NULL,
+ xorg_tracker_available_options,
+ NULL,
+ 0,
+ NULL,
+ nouveau_xorg_device_match,
+ nouveau_xorg_pci_probe
+};
+
+static MODULESETUPPROTO(nouveau_xorg_setup);
+
+_X_EXPORT XF86ModuleData modesettingModuleData = {
+ &nouveau_xorg_version,
+ nouveau_xorg_setup,
+ NULL
+};
+
+/*
+ * Xorg driver functions
+ */
+
+static pointer
+nouveau_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
+nouveau_xorg_identify(int flags)
+{
+ xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers",
+ nouveau_xorg_chipsets);
+}
+
+static Bool
+nouveau_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, nouveau_xorg_pci_devices,
+ NULL, NULL, NULL, NULL, NULL);
+ if (scrn != NULL) {
+ scrn->driverVersion = 1;
+ scrn->driverName = "i915";
+ 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;
+}
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index 684a487f24..7bf23cba23 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -32,6 +32,8 @@
#include "radeon_buffer.h"
+#include "radeon_bo_gem.h"
+
static const char *radeon_get_name(struct pipe_winsys *ws)
{
return "Radeon/GEM+KMS";
@@ -72,6 +74,7 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
alignment, domain, 0);
if (radeon_buffer->bo == NULL) {
FREE(radeon_buffer);
+ return NULL;
}
return &radeon_buffer->base;
}
@@ -98,6 +101,7 @@ static struct pipe_buffer *radeon_surface_buffer_create(struct pipe_winsys *ws,
unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
struct pipe_format_block block;
@@ -134,17 +138,19 @@ static void *radeon_buffer_map(struct pipe_winsys *ws,
int write = 0;
if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
- /* XXX Remove this when radeon_bo_map supports DONTBLOCK */
- return NULL;
+ uint32_t domain;
+
+ if (radeon_bo_is_busy(radeon_buffer->bo, &domain))
+ return NULL;
}
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) {
write = 1;
}
- radeon_bo_wait(radeon_buffer->bo);
-
- if (radeon_bo_map(radeon_buffer->bo, write))
+ if (radeon_bo_map(radeon_buffer->bo, write)) {
return NULL;
+ }
+
return radeon_buffer->bo->ptr;
}
@@ -187,7 +193,6 @@ static void radeon_flush_frontbuffer(struct pipe_winsys *pipe_winsys,
struct radeon_winsys* radeon_pipe_winsys(int fd)
{
struct radeon_winsys* radeon_ws;
- struct radeon_bo_manager* bom;
radeon_ws = CALLOC_STRUCT(radeon_winsys);
if (radeon_ws == NULL) {
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
index 8c8b61fa10..f5153b06af 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
@@ -61,11 +61,6 @@ struct radeon_winsys_priv {
/* Radeon BO manager. */
struct radeon_bo_manager* bom;
- /* Radeon BO space checker. */
- struct radeon_cs_space_check sc[RADEON_MAX_BOS];
- /* Current BO count. */
- unsigned bo_count;
-
/* Radeon CS manager. */
struct radeon_cs_manager* csm;
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
index da2010184a..a4011db0b8 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
@@ -26,15 +26,15 @@
/*
* Authors:
* Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Joakim Sindholt <opensource@zhasha.com>
*/
#include "radeon_drm.h"
-#include "trace/tr_drm.h"
/* Create a pipe_screen. */
struct pipe_screen* radeon_create_screen(struct drm_api* api,
int drmFB,
- struct drm_create_screen_arg *arg)
+ struct drm_create_screen_arg *arg)
{
struct radeon_winsys* winsys = radeon_pipe_winsys(drmFB);
@@ -54,7 +54,8 @@ struct pipe_context* radeon_create_context(struct drm_api* api,
if (getenv("RADEON_SOFTPIPE")) {
return radeon_create_softpipe(screen->winsys);
} else {
- return r300_create_context(screen, screen->winsys);
+ return r300_create_context(screen,
+ (struct r300_winsys*)screen->winsys);
}
}
@@ -97,27 +98,40 @@ struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
return &radeon_buffer->base;
}
-boolean radeon_handle_from_buffer(struct drm_api* api,
- struct pipe_screen* screen,
- struct pipe_buffer* buffer,
- unsigned* handle)
+static struct pipe_texture*
+radeon_texture_from_shared_handle(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *templ,
+ const char *name,
+ unsigned stride,
+ unsigned handle)
{
- struct radeon_pipe_buffer* radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
- *handle = radeon_buffer->bo->handle;
- return TRUE;
+ struct pipe_buffer *buffer;
+
+ buffer = radeon_buffer_from_handle(api, screen, name, handle);
+ if (!buffer) {
+ return NULL;
+ }
+
+ return screen->texture_blanket(screen, templ, &stride, buffer);
}
-boolean radeon_global_handle_from_buffer(struct drm_api* api,
- struct pipe_screen* screen,
- struct pipe_buffer* buffer,
- unsigned* handle)
+static boolean radeon_shared_handle_from_texture(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned *stride,
+ unsigned *handle)
{
int retval, fd;
struct drm_gem_flink flink;
- struct radeon_pipe_buffer* radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
+ struct radeon_pipe_buffer* radeon_buffer;
+ struct pipe_buffer *buffer;
+
+ if (!radeon_buffer_from_texture(api, texture, &buffer, stride)) {
+ return FALSE;
+ }
+ radeon_buffer = (struct radeon_pipe_buffer*)buffer;
if (!radeon_buffer->flinked) {
fd = ((struct radeon_winsys*)screen->winsys)->priv->fd;
@@ -138,13 +152,30 @@ boolean radeon_global_handle_from_buffer(struct drm_api* api,
return TRUE;
}
+static boolean radeon_local_handle_from_texture(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned *stride,
+ unsigned *handle)
+{
+ struct pipe_buffer *buffer;
+ if (!radeon_buffer_from_texture(api, texture, &buffer, stride)) {
+ return FALSE;
+ }
+
+ *handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle;
+
+ pipe_buffer_reference(&buffer, NULL);
+
+ return TRUE;
+}
+
struct drm_api drm_api_hooks = {
.create_screen = radeon_create_screen,
.create_context = radeon_create_context,
- .buffer_from_texture = radeon_buffer_from_texture,
- .buffer_from_handle = radeon_buffer_from_handle,
- .handle_from_buffer = radeon_handle_from_buffer,
- .global_handle_from_buffer = radeon_global_handle_from_buffer,
+ .texture_from_shared_handle = radeon_texture_from_shared_handle,
+ .shared_handle_from_texture = radeon_shared_handle_from_texture,
+ .local_handle_from_texture = radeon_local_handle_from_texture,
};
struct drm_api* drm_api_create()
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
index 8560f71db6..88a5c82b28 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
@@ -30,8 +30,13 @@
#ifndef RADEON_DRM_H
#define RADEON_DRM_H
+#include <sys/ioctl.h>
+
+#include "xf86drm.h"
+
#include "pipe/p_screen.h"
+#include "trace/tr_drm.h"
#include "util/u_memory.h"
#include "state_tracker/drm_api.h"
@@ -40,6 +45,9 @@
#include "radeon_r300.h"
#include "radeon_winsys_softpipe.h"
+/* XXX */
+#include "r300_screen.h"
+
struct pipe_screen* radeon_create_screen(struct drm_api* api,
int drmFB,
struct drm_create_screen_arg *arg);
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
index 8c5f756ddf..d2d84f1a8f 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
@@ -27,66 +27,25 @@ static boolean radeon_r300_add_buffer(struct r300_winsys* winsys,
uint32_t rd,
uint32_t wd)
{
- int i;
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
- struct radeon_cs_space_check* sc = priv->sc;
struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo;
- /* Check to see if this BO is already in line for validation;
- * find a slot for it otherwise. */
- for (i = 0; i < priv->bo_count; i++) {
- if (sc[i].bo == bo) {
- sc[i].read_domains |= rd;
- sc[i].write_domain |= wd;
- return TRUE;
- }
- }
-
- if (priv->bo_count >= RADEON_MAX_BOS) {
- /* Dohoho. Not falling for that one again. Request a flush. */
- return FALSE;
- }
-
- sc[priv->bo_count].bo = bo;
- sc[priv->bo_count].read_domains = rd;
- sc[priv->bo_count].write_domain = wd;
- priv->bo_count++;
-
+ radeon_cs_space_add_persistent_bo(priv->cs, bo, rd, wd);
return TRUE;
}
static boolean radeon_r300_validate(struct r300_winsys* winsys)
{
- int retval, i;
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
- struct radeon_cs_space_check* sc = priv->sc;
-
- retval = radeon_cs_space_check(priv->cs, sc, priv->bo_count);
-
- if (retval == RADEON_CS_SPACE_OP_TO_BIG) {
- /* We might as well HCF, since this is not going to fit in the card,
- * period. */
- /* XXX just drop it on the floor instead */
- exit(1);
- } else if (retval == RADEON_CS_SPACE_FLUSH) {
- /* We must flush before more rendering can commence. */
- return TRUE;
- }
- /* XXX should probably be its own function */
- for (i = 0; i < priv->bo_count; i++) {
- if (sc[i].read_domains && sc[i].write_domain) {
- /* Cute, cute. We need to flush first. */
- debug_printf("radeon: BO %p can't be read and written; "
- "requesting flush.\n", sc[i].bo);
- return TRUE;
- }
+ if (radeon_cs_space_check(priv->cs) < 0) {
+ return FALSE;
}
/* Things are fine, we can proceed as normal. */
- return FALSE;
+ return TRUE;
}
static boolean radeon_r300_check_cs(struct r300_winsys* winsys, int size)
@@ -151,8 +110,7 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys)
{
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
- struct radeon_cs_space_check* sc = priv->sc;
- int retval = 1;
+ int retval;
/* Emit the CS. */
retval = radeon_cs_emit(priv->cs);
@@ -160,44 +118,48 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys)
debug_printf("radeon: Bad CS, dumping...\n");
radeon_cs_print(priv->cs, stderr);
}
- radeon_cs_erase(priv->cs);
/* Clean out BOs. */
- memset(sc, 0, sizeof(struct radeon_cs_space_check) * RADEON_MAX_BOS);
- priv->bo_count = 0;
+ radeon_cs_space_reset_bos(priv->cs);
+
+ /* Reset CS.
+ * Someday, when we care about performance, we should really find a way
+ * to rotate between two or three CS objects so that the GPU can be
+ * spinning through one CS while another one is being filled. */
+ radeon_cs_erase(priv->cs);
}
/* Helper function to do the ioctls needed for setup and init. */
static void do_ioctls(struct r300_winsys* winsys, int fd)
{
struct drm_radeon_gem_info gem_info = {0};
- drm_radeon_getparam_t gp = {0};
struct drm_radeon_info info = {0};
int target = 0;
int retval;
- info.value = &target;
- gp.value = &target;
+ info.value = (unsigned long)&target;
+
+ /* First, get the number of pixel pipes */
+ info.request = RADEON_INFO_NUM_GB_PIPES;
+ retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
+ if (retval) {
+ fprintf(stderr, "%s: Failed to get GB pipe count, "
+ "error number %d\n", __FUNCTION__, retval);
+ exit(1);
+ }
+ winsys->gb_pipes = target;
- /* First, get PCI ID */
+ /* Then, get PCI ID */
info.request = RADEON_INFO_DEVICE_ID;
retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
if (retval) {
- fprintf(stderr, "%s: New ioctl for PCI ID failed "
- "(error number %d), trying classic ioctl...\n",
- __FUNCTION__, retval);
- gp.param = RADEON_PARAM_DEVICE_ID;
- retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp,
- sizeof(gp));
- if (retval) {
- fprintf(stderr, "%s: Failed to get PCI ID, "
- "error number %d\n", __FUNCTION__, retval);
- exit(1);
- }
+ fprintf(stderr, "%s: Failed to get PCI ID, "
+ "error number %d\n", __FUNCTION__, retval);
+ exit(1);
}
winsys->pci_id = target;
- /* Then, retrieve MM info */
+ /* Finally, retrieve MM info */
retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
&gem_info, sizeof(gem_info));
if (retval) {
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h
index a2e0e58248..775d7937fd 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h
@@ -20,29 +20,23 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
+#ifndef RADEON_R300_H
+#define RADEON_R300_H
+
/* XXX WTF is this! I shouldn't have to include those first three! FUCK! */
#include <stdint.h>
#include <stdlib.h>
#include "drm.h"
#include "radeon_drm.h"
-#include "radeon_cs.h"
+#include "radeon_cs_gem.h"
#include "r300_winsys.h"
#include "radeon_buffer.h"
-/* protect us from bonghits */
-#ifndef RADEON_INFO_DEVICE_ID
-#define RADEON_INFO_DEVICE_ID 0
-#endif
-#ifndef DRM_RADEON_INFO
-#define DRM_RADEON_INFO 0x1
-struct drm_radeon_info {
- uint32_t request;
- uint32_t pad;
- uint64_t value;
-};
-#endif
+struct radeon_winsys;
struct r300_winsys*
radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys);
+
+#endif /* RADEON_R300_H */
diff --git a/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c b/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
index 36824251f0..837f2aa8fe 100644
--- a/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
+++ b/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
@@ -48,8 +48,8 @@ static SymTabRec radeon_xorg_chipsets[] = {
};
static PciChipsets radeon_xorg_pci_devices[] = {
- {PCI_MATCH_ANY, PCI_MATCH_ANY, RES_SHARED_VGA},
- {-1, -1, RES_UNDEFINED}
+ {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
+ {-1, -1, NULL}
};
static XF86ModuleVersionInfo radeon_xorg_version = {
@@ -106,12 +106,6 @@ radeon_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
xf86AddDriver(&modesetting, module, HaveDriverFuncs);
/*
- * Tell the loader about symbols from other modules that this module
- * might refer to.
- */
- xorg_tracker_loader_ref_sym_lists();
-
- /*
* The return value must be non-NULL on success even though there
* is no TearDownProc.
*/
@@ -141,7 +135,7 @@ radeon_xorg_pci_probe(DriverPtr driver,
NULL, NULL, NULL, NULL, NULL);
if (scrn != NULL) {
scrn->driverVersion = 1;
- scrn->driverName = "modesetting";
+ scrn->driverName = "radeon";
scrn->name = "modesetting";
scrn->Probe = NULL;