diff options
Diffstat (limited to 'src/gallium/winsys/drm')
53 files changed, 1187 insertions, 2172 deletions
diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template index 9f92cb4207..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) \ @@ -118,7 +120,7 @@ clean: install: $(LIBNAME) $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) - $(INSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) + $(MINSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) include depend diff --git a/src/gallium/winsys/drm/intel/SConscript b/src/gallium/winsys/drm/intel/SConscript new file mode 100644 index 0000000000..50d7b75ed6 --- /dev/null +++ b/src/gallium/winsys/drm/intel/SConscript @@ -0,0 +1,7 @@ +Import('*') + +SConscript(['gem/SConscript',]) + +if 'mesa' in env['statetrackers']: + + SConscript(['dri/SConscript']) diff --git a/src/gallium/winsys/drm/intel/dri/Makefile b/src/gallium/winsys/drm/intel/dri/Makefile index ac0891a646..5e212b62a4 100644 --- a/src/gallium/winsys/drm/intel/dri/Makefile +++ b/src/gallium/winsys/drm/intel/dri/Makefile @@ -6,7 +6,9 @@ LIBNAME = i915_dri.so PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \ $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/identity/libidentity.a \ $(TOP)/src/gallium/drivers/i915simple/libi915simple.a diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript new file mode 100644 index 0000000000..6c00861f51 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/SConscript @@ -0,0 +1,19 @@ +Import('*') + +env = drienv.Clone() + +env.ParseConfig('pkg-config --cflags --libs libdrm_intel') + +drivers = [ + st_dri, + inteldrm, + softpipe, + i915simple, + trace, +] + +env.SharedLibrary( + target ='i915_dri.so', + source = COMMON_GALLIUM_SOURCES, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], +) 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 new file mode 100644 index 0000000000..26717f391f --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/SConscript @@ -0,0 +1,17 @@ +Import('*') + +env = drienv.Clone() + +inteldrm_sources = [ + 'intel_drm_api.c', + 'intel_drm_batchbuffer.c', + 'intel_drm_buffer.c', + 'intel_drm_fence.c', +] + +inteldrm = env.ConvenienceLibrary( + target ='inteldrm', + source = inteldrm_sources, +) + +Export('inteldrm') 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 f4ef7c2d88..0000000000 --- a/src/gallium/winsys/drm/intel/gem/intel_be_api.c +++ /dev/null @@ -1,15 +0,0 @@ - -#include "intel_be_api.h" -#include "i915simple/i915_winsys.h" - -struct drm_api drm_api_hooks = -{ - /* 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 deleted file mode 100644 index 1c622f3b97..0000000000 --- a/src/gallium/winsys/drm/intel/gem/intel_be_api.h +++ /dev/null @@ -1,15 +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" - -struct pipe_screen *intel_be_create_screen(int drmFD, - struct drm_create_screen_arg *arg); -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 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 fe0b138fbe..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 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 907ac86637..0000000000 --- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c +++ /dev/null @@ -1,347 +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; -} - -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; - - 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 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 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; - - /* - * 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; - } - - fgets(path, sizeof(path), file); - sscanf(path, "%x", device_id); - fclose(file); -} - -struct pipe_screen * -intel_be_create_screen(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); - drm_api_hooks.buffer_from_texture = softpipe_get_texture_buffer; - } 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 b32637ece2..0000000000 --- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h +++ /dev/null @@ -1,94 +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" - -/* - * 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; -}; - -/** - * 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 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..4c5a1d2ea8 --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c @@ -0,0 +1,202 @@ + +#include "state_tracker/drm_api.h" + +#include "intel_drm_winsys.h" +#include "util/u_memory.h" + +#include "i915simple/i915_context.h" +#include "i915simple/i915_screen.h" + + +/* + * Helper functions + */ + + +static void +intel_drm_get_device_id(unsigned int *device_id) +{ + char path[512]; + FILE *file; + void *shutup_gcc; + + /* + * FIXME: Fix this up to use a drm ioctl or whatever. + */ + + snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device"); + file = fopen(path, "r"); + if (!file) { + return; + } + + shutup_gcc = fgets(path, sizeof(path), file); + sscanf(path, "%x", device_id); + fclose(file); +} + +static struct intel_buffer * +intel_drm_buffer_from_handle(struct intel_drm_winsys *idws, + const char* name, unsigned handle) +{ + struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer); + + if (!buf) + return NULL; + + buf->magic = 0xDEAD1337; + buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, name, handle); + buf->flinked = TRUE; + buf->flink = handle; + + if (!buf->bo) + goto err; + + return (struct intel_buffer *)buf; + +err: + FREE(buf); + return NULL; +} + + +/* + * Exported functions + */ + + +static struct pipe_texture * +intel_drm_texture_from_shared_handle(struct drm_api *api, + struct pipe_screen *screen, + struct pipe_texture *templ, + const char* name, + unsigned pitch, + unsigned handle) +{ + struct intel_drm_winsys *idws = intel_drm_winsys(i915_screen(screen)->iws); + struct intel_buffer *buffer; + + buffer = intel_drm_buffer_from_handle(idws, name, handle); + if (!buffer) + return NULL; + + return i915_texture_blanket_intel(screen, templ, pitch, buffer); +} + +static boolean +intel_drm_shared_handle_from_texture(struct drm_api *api, + struct pipe_screen *screen, + struct pipe_texture *texture, + unsigned *pitch, + unsigned *handle) +{ + struct intel_drm_buffer *buf = NULL; + struct intel_buffer *buffer = NULL; + if (!i915_get_texture_buffer_intel(texture, &buffer, pitch)) + return FALSE; + + buf = intel_drm_buffer(buffer); + if (!buf->flinked) { + if (drm_intel_bo_flink(buf->bo, &buf->flink)) + return FALSE; + buf->flinked = TRUE; + } + + *handle = buf->flink; + + return TRUE; +} + +static boolean +intel_drm_local_handle_from_texture(struct drm_api *api, + struct pipe_screen *screen, + struct pipe_texture *texture, + unsigned *pitch, + unsigned *handle) +{ + struct intel_buffer *buffer = NULL; + if (!i915_get_texture_buffer_intel(texture, &buffer, pitch)) + return FALSE; + + *handle = intel_drm_buffer(buffer)->bo->handle; + + return TRUE; +} + +static void +intel_drm_winsys_destroy(struct intel_winsys *iws) +{ + struct intel_drm_winsys *idws = intel_drm_winsys(iws); + + drm_intel_bufmgr_destroy(idws->pools.gem); + + FREE(idws); +} + +static struct pipe_screen * +intel_drm_create_screen(struct drm_api *api, int drmFD, + struct drm_create_screen_arg *arg) +{ + struct intel_drm_winsys *idws; + unsigned int deviceID; + + if (arg != NULL) { + switch(arg->mode) { + case DRM_CREATE_NORMAL: + break; + default: + return NULL; + } + } + + idws = CALLOC_STRUCT(intel_drm_winsys); + if (!idws) + return NULL; + + intel_drm_get_device_id(&deviceID); + + intel_drm_winsys_init_batchbuffer_functions(idws); + intel_drm_winsys_init_buffer_functions(idws); + intel_drm_winsys_init_fence_functions(idws); + + idws->fd = drmFD; + idws->id = deviceID; + idws->max_batch_size = 16 * 4096; + + idws->base.destroy = intel_drm_winsys_destroy; + + idws->pools.gem = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size); + + idws->softpipe = FALSE; + idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE); + + return i915_create_screen(&idws->base, deviceID); +} + +static struct pipe_context * +intel_drm_create_context(struct drm_api *api, struct pipe_screen *screen) +{ + return i915_create_context(screen); +} + +static void +destroy(struct drm_api *api) +{ + +} + +struct drm_api intel_drm_api = +{ + .create_context = intel_drm_create_context, + .create_screen = intel_drm_create_screen, + .texture_from_shared_handle = intel_drm_texture_from_shared_handle, + .shared_handle_from_texture = intel_drm_shared_handle_from_texture, + .local_handle_from_texture = intel_drm_local_handle_from_texture, + .destroy = destroy, +}; + +struct drm_api * +drm_api_create() +{ + return &intel_drm_api; +} diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c new file mode 100644 index 0000000000..5ca3ad9762 --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c @@ -0,0 +1,214 @@ + +#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 + +struct intel_drm_batchbuffer +{ + struct intel_batchbuffer base; + + size_t actual_size; + + drm_intel_bo *bo; +}; + +static INLINE struct intel_drm_batchbuffer * +intel_drm_batchbuffer(struct intel_batchbuffer *batch) +{ + return (struct intel_drm_batchbuffer *)batch; +} + +static void +intel_drm_batchbuffer_reset(struct intel_drm_batchbuffer *batch) +{ + struct intel_drm_winsys *idws = intel_drm_winsys(batch->base.iws); + + if (batch->bo) + drm_intel_bo_unreference(batch->bo); + batch->bo = drm_intel_bo_alloc(idws->pools.gem, + "gallium3d_batchbuffer", + batch->actual_size, + 4096); + drm_intel_bo_map(batch->bo, TRUE); + batch->base.map = batch->bo->virtual; + + memset(batch->base.map, 0, batch->actual_size); + batch->base.ptr = batch->base.map; + batch->base.size = batch->actual_size - BATCH_RESERVED; + batch->base.relocs = 0; +} + +static struct intel_batchbuffer * +intel_drm_batchbuffer_create(struct intel_winsys *iws) +{ + struct intel_drm_winsys *idws = intel_drm_winsys(iws); + struct intel_drm_batchbuffer *batch = CALLOC_STRUCT(intel_drm_batchbuffer); + + batch->base.map = NULL; + batch->base.ptr = NULL; + batch->base.size = 0; + + batch->base.relocs = 0; + batch->base.max_relocs = 300;/*INTEL_DEFAULT_RELOCS;*/ + + batch->base.iws = iws; + + batch->actual_size = idws->max_batch_size; + + intel_drm_batchbuffer_reset(batch); + + return &batch->base; +} + +static int +intel_drm_batchbuffer_reloc(struct intel_batchbuffer *ibatch, + struct intel_buffer *buffer, + enum intel_buffer_usage usage, + unsigned pre_add) +{ + struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch); + unsigned write_domain = 0; + unsigned read_domain = 0; + unsigned offset; + int ret = 0; + + assert(batch->base.relocs < batch->base.max_relocs); + + if (usage == INTEL_USAGE_SAMPLER) { + write_domain = 0; + read_domain = I915_GEM_DOMAIN_SAMPLER; + + } else if (usage == INTEL_USAGE_RENDER) { + write_domain = I915_GEM_DOMAIN_RENDER; + read_domain = I915_GEM_DOMAIN_RENDER; + + } else if (usage == INTEL_USAGE_2D_TARGET) { + write_domain = I915_GEM_DOMAIN_RENDER; + read_domain = I915_GEM_DOMAIN_RENDER; + + } else if (usage == INTEL_USAGE_2D_SOURCE) { + write_domain = 0; + read_domain = I915_GEM_DOMAIN_RENDER; + + } else if (usage == INTEL_USAGE_VERTEX) { + write_domain = 0; + read_domain = I915_GEM_DOMAIN_VERTEX; + + } else { + assert(0); + return -1; + } + + offset = (unsigned)(batch->base.ptr - batch->base.map); + + ret = drm_intel_bo_emit_reloc(batch->bo, offset, + intel_bo(buffer), pre_add, + read_domain, + write_domain); + + ((uint32_t*)batch->base.ptr)[0] = intel_bo(buffer)->offset + pre_add; + batch->base.ptr += 4; + + if (!ret) + batch->base.relocs++; + + return ret; +} + +static void +intel_drm_batchbuffer_flush(struct intel_batchbuffer *ibatch, + struct pipe_fence_handle **fence) +{ + struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch); + unsigned used = 0; + int ret = 0; + int i; + + assert(intel_batchbuffer_space(ibatch) >= 0); + + used = batch->base.ptr - batch->base.map; + assert((used & 3) == 0); + + if (used & 4) { + // MI_FLUSH | FLUSH_MAP_CACHE; + intel_batchbuffer_dword(ibatch, (0x0<<29)|(0x4<<23)|(1<<0)); + // MI_NOOP + intel_batchbuffer_dword(ibatch, (0x0<<29)|(0x0<<23)); + // MI_BATCH_BUFFER_END; + intel_batchbuffer_dword(ibatch, (0x0<<29)|(0xA<<23)); + } else { + //MI_FLUSH | FLUSH_MAP_CACHE; + intel_batchbuffer_dword(ibatch, (0x0<<29)|(0x4<<23)|(1<<0)); + // MI_BATCH_BUFFER_END; + intel_batchbuffer_dword(ibatch, (0x0<<29)|(0xA<<23)); + } + + used = batch->base.ptr - batch->base.map; + + drm_intel_bo_unmap(batch->bo); + + /* Do the sending to HW */ + ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0); + assert(ret == 0); + + if (intel_drm_winsys(ibatch->iws)->dump_cmd) { + unsigned *ptr; + drm_intel_bo_map(batch->bo, FALSE); + ptr = (unsigned*)batch->bo->virtual; + + debug_printf("%s:\n", __func__); + for (i = 0; i < used / 4; i++, ptr++) { + debug_printf("\t%08x: %08x\n", i*4, *ptr); + } + + drm_intel_bo_unmap(batch->bo); + } else { +#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); + + 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..e017cd2e98 --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c @@ -0,0 +1,134 @@ + +#include "intel_drm_winsys.h" +#include "util/u_memory.h" + +#include "i915_drm.h" + +static struct intel_buffer * +intel_drm_buffer_create(struct intel_winsys *iws, + unsigned size, unsigned alignment, + enum intel_buffer_type type) +{ + struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer); + struct intel_drm_winsys *idws = intel_drm_winsys(iws); + drm_intel_bufmgr *pool; + char *name; + + if (!buf) + return NULL; + + buf->magic = 0xDEAD1337; + buf->flinked = FALSE; + buf->flink = 0; + buf->map_gtt = FALSE; + + if (type == INTEL_NEW_TEXTURE) { + name = "gallium3d_texture"; + pool = idws->pools.gem; + } else if (type == INTEL_NEW_VERTEX) { + name = "gallium3d_vertex"; + pool = idws->pools.gem; + } else if (type == INTEL_NEW_SCANOUT) { + name = "gallium3d_scanout"; + pool = idws->pools.gem; + buf->map_gtt = TRUE; + } else { + assert(0); + name = "gallium3d_unknown"; + pool = idws->pools.gem; + } + + buf->bo = drm_intel_bo_alloc(pool, name, size, alignment); + + if (!buf->bo) + goto err; + + return (struct intel_buffer *)buf; + +err: + assert(0); + FREE(buf); + return NULL; +} + +static int +intel_drm_buffer_set_fence_reg(struct intel_winsys *iws, + struct intel_buffer *buffer, + unsigned stride, + enum intel_buffer_tile tile) +{ + assert(I915_TILING_NONE == INTEL_TILE_NONE); + assert(I915_TILING_X == INTEL_TILE_X); + assert(I915_TILING_Y == INTEL_TILE_Y); + + return drm_intel_bo_set_tiling(intel_bo(buffer), &tile, stride); +} + +static void * +intel_drm_buffer_map(struct intel_winsys *iws, + struct intel_buffer *buffer, + boolean write) +{ + struct intel_drm_buffer *buf = intel_drm_buffer(buffer); + drm_intel_bo *bo = intel_bo(buffer); + int ret = 0; + + assert(bo); + + if (buf->map_count) + goto out; + + if (buf->map_gtt) + ret = drm_intel_gem_bo_map_gtt(bo); + else + ret = drm_intel_bo_map(bo, write); + + buf->ptr = bo->virtual; + + assert(ret == 0); +out: + if (ret) + return NULL; + + buf->map_count++; + return buf->ptr; +} + +static void +intel_drm_buffer_unmap(struct intel_winsys *iws, + struct intel_buffer *buffer) +{ + struct intel_drm_buffer *buf = intel_drm_buffer(buffer); + + if (--buf->map_count) + return; + + if (buf->map_gtt) + drm_intel_gem_bo_unmap_gtt(intel_bo(buffer)); + else + drm_intel_bo_unmap(intel_bo(buffer)); +} + +static void +intel_drm_buffer_destroy(struct intel_winsys *iws, + struct intel_buffer *buffer) +{ + drm_intel_bo_unreference(intel_bo(buffer)); + +#ifdef DEBUG + intel_drm_buffer(buffer)->magic = 0; + intel_drm_buffer(buffer)->bo = NULL; +#endif + + FREE(buffer); +} + +void +intel_drm_winsys_init_buffer_functions(struct intel_drm_winsys *idws) +{ + idws->base.buffer_create = intel_drm_buffer_create; + idws->base.buffer_set_fence_reg = intel_drm_buffer_set_fence_reg; + idws->base.buffer_map = intel_drm_buffer_map; + idws->base.buffer_unmap = intel_drm_buffer_unmap; + idws->base.buffer_destroy = intel_drm_buffer_destroy; +} diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c b/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c new file mode 100644 index 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 b1b6b9362b..9e56853b02 100644 --- a/src/gallium/winsys/drm/intel/xorg/Makefile +++ b/src/gallium/winsys/drm/intel/xorg/Makefile @@ -1,36 +1,39 @@ TARGET = modesetting_drv.so CFILES = $(wildcard ./*.c) OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES)) -GALLIUMDIR = ../../../.. TOP = ../../../../../.. -include ${TOP}/configs/current +include $(TOP)/configs/current -CFLAGS = -DHAVE_CONFIG_H \ - -g -Wall -Wimplicit-function-declaration -fPIC \ - $(shell pkg-config --cflags pixman-1 xorg-server libdrm xproto) \ - -I../gem \ - -I${GALLIUMDIR}/include \ - -I${GALLIUMDIR}/drivers \ - -I${GALLIUMDIR}/auxiliary \ - -I${TOP}/src/mesa \ - -I$(TOP)/include \ - -I$(TOP)/src/egl/main +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 = \ - $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a \ - $(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \ + $(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) +DRIVER_DEFINES = \ + -DHAVE_CONFIG_H + + ############################################# all default: $(TARGET) -$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a $(LIBS) +$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS) $(TOP)/bin/mklib -noprefix -o $@ \ $(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel @@ -39,6 +42,16 @@ clean: install: $(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR) - $(INSTALL) -m 755 $(TARGET) $(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/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/Makefile b/src/gallium/winsys/drm/nouveau/Makefile index f8c8135854..6c9cbef26d 100644 --- a/src/gallium/winsys/drm/nouveau/Makefile +++ b/src/gallium/winsys/drm/nouveau/Makefile @@ -2,7 +2,7 @@ TOP = ../../../../.. include $(TOP)/configs/current -SUBDIRS = drm dri dri2 +SUBDIRS = drm $(GALLIUM_STATE_TRACKERS_DIRS) default install clean: @for dir in $(SUBDIRS) ; do \ diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/winsys/drm/nouveau/dri/Makefile index f7db6201fe..0937f68c34 100644 --- a/src/gallium/winsys/drm/nouveau/dri/Makefile +++ b/src/gallium/winsys/drm/nouveau/dri/Makefile @@ -3,32 +3,25 @@ include $(TOP)/configs/current LIBNAME = nouveau_dri.so -MINIGLX_SOURCES = - PIPE_DRIVERS = \ + $(TOP)/src/gallium/state_trackers/dri/libdridrm.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 - -DRIVER_SOURCES = \ - nouveau_context.c \ - nouveau_screen.c \ - nouveau_swapbuffers.c \ - nouveau_lock.c + $(TOP)/src/gallium/drivers/nv50/libnv50.a \ + $(TOP)/src/gallium/drivers/nouveau/libnouveau.a + +DRIVER_SOURCES = C_SOURCES = \ $(COMMON_GALLIUM_SOURCES) \ $(DRIVER_SOURCES) -ASM_SOURCES = +include ../../Makefile.template -DRIVER_DEFINES = $(shell pkg-config libdrm_nouveau --cflags) DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs) -include ../../Makefile.template - symlinks: diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c deleted file mode 100644 index deb6ffcff1..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c +++ /dev/null @@ -1,118 +0,0 @@ -#include <main/glheader.h> -#include <glapi/glthread.h> -#include <GL/internal/glcore.h> -#include <utils.h> - -#include <state_tracker/st_public.h> -#include <state_tracker/st_context.h> -#include <state_tracker/drm_api.h> -#include <pipe/p_defines.h> -#include <pipe/p_context.h> -#include <pipe/p_screen.h> - -#include "nouveau_context.h" -#include "nouveau_screen.h" - -#include "nouveau_drmif.h" - -GLboolean -nouveau_context_create(const __GLcontextModes *glVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate) -{ - __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv; - struct nouveau_screen *nv_screen = driScrnPriv->private; - struct nouveau_context *nv; - struct pipe_context *pipe; - struct st_context *st_share = NULL; - - if (sharedContextPrivate) - st_share = ((struct nouveau_context *)sharedContextPrivate)->st; - - nv = CALLOC_STRUCT(nouveau_context); - if (!nv) - return GL_FALSE; - - { - struct nouveau_device_priv *nvdev = - nouveau_device(nv_screen->device); - - nvdev->ctx = driContextPriv->hHWContext; - nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock; - } - - pipe = drm_api_hooks.create_context(nv_screen->pscreen); - if (!pipe) { - FREE(nv); - return GL_FALSE; - } - pipe->priv = nv; - - driContextPriv->driverPrivate = nv; - nv->dri_screen = driScrnPriv; - - driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, - nv->dri_screen->myNum, "nouveau"); - - nv->st = st_create_context(pipe, glVis, st_share); - return GL_TRUE; -} - -void -nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) -{ - struct nouveau_context *nv = driContextPriv->driverPrivate; - - assert(nv); - - st_finish(nv->st); - st_destroy_context(nv->st); - - FREE(nv); -} - -GLboolean -nouveau_context_bind(__DRIcontextPrivate *driContextPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv) -{ - struct nouveau_context *nv; - struct nouveau_framebuffer *draw, *read; - - if (!driContextPriv) { - st_make_current(NULL, NULL, NULL); - return GL_TRUE; - } - - nv = driContextPriv->driverPrivate; - draw = driDrawPriv->driverPrivate; - read = driReadPriv->driverPrivate; - - st_make_current(nv->st, draw->stfb, read->stfb); - - if ((nv->dri_drawable != driDrawPriv) || - (nv->last_stamp != driDrawPriv->lastStamp)) { - nv->dri_drawable = driDrawPriv; - st_resize_framebuffer(draw->stfb, driDrawPriv->w, - driDrawPriv->h); - nv->last_stamp = driDrawPriv->lastStamp; - } - - if (driDrawPriv != driReadPriv) { - st_resize_framebuffer(read->stfb, driReadPriv->w, - driReadPriv->h); - } - - return GL_TRUE; -} - -GLboolean -nouveau_context_unbind(__DRIcontextPrivate *driContextPriv) -{ - struct nouveau_context *nv = driContextPriv->driverPrivate; - (void)nv; - - st_flush(nv->st, 0, NULL); - return GL_TRUE; -} - diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h deleted file mode 100644 index 2779b092e6..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __NOUVEAU_CONTEXT_DRI_H__ -#define __NOUVEAU_CONTEXT_DRI_H__ - -#include <dri_util.h> -#include <xmlconfig.h> - -#include "nouveau/nouveau_winsys.h" - -#define NOUVEAU_ERR(fmt, args...) debug_printf("%s: "fmt, __func__, ##args) - -struct nouveau_framebuffer { - struct st_framebuffer *stfb; -}; - -struct nouveau_context { - struct st_context *st; - - /* DRI stuff */ - __DRIscreenPrivate *dri_screen; - __DRIdrawablePrivate *dri_drawable; - unsigned int last_stamp; - driOptionCache dri_option_cache; - drm_context_t drm_context; - drmLock drm_lock; - int locked; -}; - -extern GLboolean nouveau_context_create(const __GLcontextModes *, - __DRIcontextPrivate *, void *); -extern void nouveau_context_destroy(__DRIcontextPrivate *); -extern GLboolean nouveau_context_bind(__DRIcontextPrivate *, - __DRIdrawablePrivate *draw, - __DRIdrawablePrivate *read); -extern GLboolean nouveau_context_unbind(__DRIcontextPrivate *); - -extern void nouveau_contended_lock(struct nouveau_context *nv); -extern void LOCK_HARDWARE(struct nouveau_context *nv); -extern void UNLOCK_HARDWARE(struct nouveau_context *nv); - -#ifdef DEBUG -extern int __nouveau_debug; - -#define DEBUG_BO (1 << 0) - -#define DBG(flag, ...) do { \ - if (__nouveau_debug & (DEBUG_##flag)) \ - NOUVEAU_ERR(__VA_ARGS__); \ -} while(0) -#else -#define DBG(flag, ...) -#endif - -#endif diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c deleted file mode 100644 index 92f5bd09c9..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 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. - * - **************************************************************************/ - -#include <pipe/p_thread.h> -#include "nouveau_context.h" -#include "nouveau_screen.h" -#include "nouveau_drmif.h" - -pipe_static_mutex(lockMutex); - -/* Lock the hardware and validate our state. - */ -void -LOCK_HARDWARE(struct nouveau_context *nv) -{ - struct nouveau_screen *nv_screen = nv->dri_screen->private; - struct nouveau_device *dev = nv_screen->device; - struct nouveau_device_priv *nvdev = nouveau_device(dev); - char __ret=0; - - assert(!nv->locked); - pipe_mutex_lock(lockMutex); - - DRM_CAS(nvdev->lock, nvdev->ctx, - (DRM_LOCK_HELD | nvdev->ctx), __ret); - - if (__ret) { - drmGetLock(nvdev->fd, nvdev->ctx, 0); - nouveau_contended_lock(nv); - } - nv->locked = 1; -} - -/* Unlock the hardware using the global current context - */ -void -UNLOCK_HARDWARE(struct nouveau_context *nv) -{ - struct nouveau_screen *nv_screen = nv->dri_screen->private; - struct nouveau_device *dev = nv_screen->device; - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - assert(nv->locked); - nv->locked = 0; - - DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx); - - pipe_mutex_unlock(lockMutex); -} diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c deleted file mode 100644 index 4e9b76a909..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c +++ /dev/null @@ -1,330 +0,0 @@ -#include <utils.h> -#include <vblank.h> -#include <xmlpool.h> - -#include <pipe/p_context.h> -#include <state_tracker/st_public.h> -#include <state_tracker/st_cb_fbo.h> -#include <state_tracker/drm_api.h> - -#include "nouveau_context.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" -#include "nouveau_dri.h" - -#include "nouveau_drm.h" -#include "nouveau_drmif.h" - -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 12 -#error nouveau_drm.h version does not match expected version -#endif - -/* Extension stuff, enabling of extensions handled by Gallium's GL state - * tracker. But, we still need to define the entry points we want. - */ -#define need_GL_ARB_fragment_program -#define need_GL_ARB_multisample -#define need_GL_ARB_occlusion_query -#define need_GL_ARB_point_parameters -#define need_GL_ARB_shader_objects -#define need_GL_ARB_texture_compression -#define need_GL_ARB_vertex_program -#define need_GL_ARB_vertex_shader -#define need_GL_ARB_vertex_buffer_object -#define need_GL_EXT_compiled_vertex_array -#define need_GL_EXT_fog_coord -#define need_GL_EXT_secondary_color -#define need_GL_EXT_framebuffer_object -#define need_GL_VERSION_2_0 -#define need_GL_VERSION_2_1 -#include "extension_helper.h" - -const struct dri_extension card_extensions[] = -{ - { "GL_ARB_multisample", GL_ARB_multisample_functions }, - { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions }, - { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, - { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions }, - { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions }, - { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions }, - { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, - { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, - { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions }, - { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, - { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions }, - { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, - { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, - { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, - { NULL, 0 } -}; - -PUBLIC const char __driConfigOptions[] = -DRI_CONF_BEGIN -DRI_CONF_END; -static const GLuint __driNConfigOptions = 0; - -extern const struct dri_extension common_extensions[]; -extern const struct dri_extension nv40_extensions[]; - -static GLboolean -nouveau_create_buffer(__DRIscreenPrivate * driScrnPriv, - __DRIdrawablePrivate * driDrawPriv, - const __GLcontextModes *glVis, GLboolean pixmapBuffer) -{ - struct nouveau_framebuffer *nvfb; - enum pipe_format colour, depth, stencil; - - if (pixmapBuffer) - return GL_FALSE; - - nvfb = CALLOC_STRUCT(nouveau_framebuffer); - if (!nvfb) - return GL_FALSE; - - if (glVis->redBits == 5) - colour = PIPE_FORMAT_R5G6B5_UNORM; - else - colour = PIPE_FORMAT_A8R8G8B8_UNORM; - - if (glVis->depthBits == 16) - depth = PIPE_FORMAT_Z16_UNORM; - else if (glVis->depthBits == 24) - depth = PIPE_FORMAT_Z24S8_UNORM; - else - depth = PIPE_FORMAT_NONE; - - if (glVis->stencilBits == 8) - stencil = PIPE_FORMAT_Z24S8_UNORM; - else - stencil = PIPE_FORMAT_NONE; - - nvfb->stfb = st_create_framebuffer(glVis, colour, depth, stencil, - driDrawPriv->w, driDrawPriv->h, - (void*)nvfb); - if (!nvfb->stfb) { - free(nvfb); - return GL_FALSE; - } - - driDrawPriv->driverPrivate = (void *)nvfb; - return GL_TRUE; -} - -static void -nouveau_destroy_buffer(__DRIdrawablePrivate * driDrawPriv) -{ - struct nouveau_framebuffer *nvfb; - - nvfb = (struct nouveau_framebuffer *)driDrawPriv->driverPrivate; - st_unreference_framebuffer(nvfb->stfb); - free(nvfb); -} - -static __DRIconfig ** -nouveau_fill_in_modes(__DRIscreenPrivate *psp, - unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) -{ - __DRIconfig **configs; - unsigned depth_buffer_factor; - unsigned back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, - }; - - uint8_t depth_bits_array[3]; - uint8_t stencil_bits_array[3]; - uint8_t msaa_samples_array[1]; - - depth_bits_array[0] = 0; - depth_bits_array[1] = depth_bits; - depth_bits_array[2] = depth_bits; - - /* Just like with the accumulation buffer, always provide some modes - * with a stencil buffer. It will be a sw fallback, but some apps won't - * care about that. - */ - stencil_bits_array[0] = 0; - stencil_bits_array[1] = 0; - if (depth_bits == 24) - stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; - stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; - - msaa_samples_array[0] = 0; - - depth_buffer_factor = - ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; - back_buffer_factor = (have_back_buffer) ? 3 : 1; - - if (pixel_bits == 16) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; - } - else { - fb_format = GL_BGRA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - configs = driCreateConfigs(fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, msaa_samples_array, 1); - if (configs == NULL) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__); - return NULL; - } - - return configs; -} - -static struct pipe_surface * -dri_surface_from_handle(struct pipe_screen *screen, - 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 = drm_api_hooks.buffer_from_handle(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; -} - -static const __DRIconfig ** -nouveau_screen_create(__DRIscreenPrivate *psp) -{ - struct nouveau_dri *nv_dri = psp->pDevPriv; - struct nouveau_screen *nv_screen; - static const __DRIversion ddx_expected = - { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL }; - static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = - { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL }; - - if (!driCheckDriDdxDrmVersions2("nouveau", - &psp->dri_version, &dri_expected, - &psp->ddx_version, &ddx_expected, - &psp->drm_version, &drm_expected)) { - return NULL; - } - - if (drm_expected.patch != psp->drm_version.patch) { - fprintf(stderr, "Incompatible DRM patch level.\n" - "Expected: %d\n" "Current : %d\n", - drm_expected.patch, psp->drm_version.patch); - return NULL; - } - - driInitExtensions(NULL, card_extensions, GL_FALSE); - - if (psp->devPrivSize != sizeof(struct nouveau_dri)) { - NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n"); - return NULL; - } - - nv_screen = CALLOC_STRUCT(nouveau_screen); - if (!nv_screen) - return NULL; - - nouveau_device_open_existing(&nv_screen->device, 0, psp->fd, 0); - - nv_screen->pscreen = drm_api_hooks.create_screen(psp->fd, NULL); - if (!nv_screen->pscreen) { - FREE(nv_screen); - return NULL; - } - nv_screen->pscreen->flush_frontbuffer = nouveau_flush_frontbuffer; - - { - enum pipe_format format; - - if (nv_dri->bpp == 16) - format = PIPE_FORMAT_R5G6B5_UNORM; - else - format = PIPE_FORMAT_A8R8G8B8_UNORM; - - nv_screen->fb = dri_surface_from_handle(nv_screen->pscreen, - nv_dri->front_offset, - format, - nv_dri->width, - nv_dri->height, - nv_dri->front_pitch * - nv_dri->bpp / 8); - } - - driParseOptionInfo(&nv_screen->option_cache, - __driConfigOptions, __driNConfigOptions); - - nv_screen->driScrnPriv = psp; - psp->private = (void *)nv_screen; - - return (const __DRIconfig **) - nouveau_fill_in_modes(psp, nv_dri->bpp, - (nv_dri->bpp == 16) ? 16 : 24, - (nv_dri->bpp == 16) ? 0 : 8, 1); -} - -static void -nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv) -{ - struct nouveau_screen *nv_screen = driScrnPriv->private; - - driScrnPriv->private = NULL; - FREE(nv_screen); -} - -const struct __DriverAPIRec -driDriverAPI = { - .InitScreen = nouveau_screen_create, - .DestroyScreen = nouveau_screen_destroy, - .CreateContext = nouveau_context_create, - .DestroyContext = nouveau_context_destroy, - .CreateBuffer = nouveau_create_buffer, - .DestroyBuffer = nouveau_destroy_buffer, - .SwapBuffers = nouveau_swap_buffers, - .MakeCurrent = nouveau_context_bind, - .UnbindContext = nouveau_context_unbind, - .CopySubBuffer = nouveau_copy_sub_buffer, - - .InitScreen2 = NULL, /* one day, I promise! */ -}; - diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h deleted file mode 100644 index ac078f3c63..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __NOUVEAU_SCREEN_DRI_H__ -#define __NOUVEAU_SCREEN_DRI_H__ - -#include "xmlconfig.h" - -struct nouveau_screen { - __DRIscreenPrivate *driScrnPriv; - driOptionCache option_cache; - - struct nouveau_device *device; - - struct pipe_screen *pscreen; - struct pipe_surface *fb; -}; - -#endif diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c deleted file mode 100644 index 9c841a0b2d..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c +++ /dev/null @@ -1,115 +0,0 @@ -#include <main/glheader.h> -#include <glapi/glthread.h> -#include <GL/internal/glcore.h> - -#include <pipe/p_context.h> -#include <state_tracker/st_public.h> -#include <state_tracker/st_context.h> -#include <state_tracker/st_cb_fbo.h> - -#include "nouveau_context.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" - -#include "nouveau_pushbuf.h" - -void -nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, - const drm_clip_rect_t *rect) -{ - struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate; - struct nouveau_screen *nv_screen = nv->dri_screen->private; - struct pipe_context *pipe = nv->st->pipe; - drm_clip_rect_t *pbox; - int nbox, i; - - LOCK_HARDWARE(nv); - if (!dPriv->numClipRects) { - UNLOCK_HARDWARE(nv); - return; - } - pbox = dPriv->pClipRects; - nbox = dPriv->numClipRects; - - for (i = 0; i < nbox; i++, pbox++) { - int sx, sy, dx, dy, w, h; - - sx = pbox->x1 - dPriv->x; - sy = pbox->y1 - dPriv->y; - dx = pbox->x1; - dy = pbox->y1; - w = pbox->x2 - pbox->x1; - h = pbox->y2 - pbox->y1; - - pipe->surface_copy(pipe, nv_screen->fb, dx, dy, surf, - sx, sy, w, h); - } - - pipe->flush(pipe, 0, NULL); - UNLOCK_HARDWARE(nv); - - if (nv->last_stamp != dPriv->lastStamp) { - struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; - st_resize_framebuffer(nvfb->stfb, dPriv->w, dPriv->h); - nv->last_stamp = dPriv->lastStamp; - } -} - -void -nouveau_copy_sub_buffer(__DRIdrawablePrivate *dPriv, int x, int y, int w, int h) -{ - struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; - struct pipe_surface *surf; - - st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT, &surf); - if (surf) { - drm_clip_rect_t rect; - rect.x1 = x; - rect.y1 = y; - rect.x2 = x + w; - rect.y2 = y + h; - - st_notify_swapbuffers(nvfb->stfb); - nouveau_copy_buffer(dPriv, surf, &rect); - } -} - -void -nouveau_swap_buffers(__DRIdrawablePrivate *dPriv) -{ - struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; - struct pipe_surface *surf; - - st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT, &surf); - if (surf) { - st_notify_swapbuffers(nvfb->stfb); - nouveau_copy_buffer(dPriv, surf, NULL); - } -} - -void -nouveau_flush_frontbuffer(struct pipe_screen *pscreen, struct pipe_surface *ps, - void *context_private) -{ - struct nouveau_context *nv = context_private; - __DRIdrawablePrivate *dPriv = nv->dri_drawable; - - nouveau_copy_buffer(dPriv, ps, NULL); -} - -void -nouveau_contended_lock(struct nouveau_context *nv) -{ - struct nouveau_context *nv_sub = (struct nouveau_context*)nv; - __DRIdrawablePrivate *dPriv = nv_sub->dri_drawable; - __DRIscreenPrivate *sPriv = nv_sub->dri_screen; - - /* If the window moved, may need to set a new cliprect now. - * - * NOTE: This releases and regains the hw lock, so all state - * checking must be done *after* this call: - */ - if (dPriv) - DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); -} - diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h deleted file mode 100644 index 4ca9cc2283..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __NOUVEAU_SWAPBUFFERS_H__ -#define __NOUVEAU_SWAPBUFFERS_H__ - -void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *, - const drm_clip_rect_t *); -void nouveau_copy_sub_buffer(__DRIdrawablePrivate *, int x, int y, int w, int h); -void nouveau_swap_buffers(__DRIdrawablePrivate *); -void nouveau_flush_frontbuffer(struct pipe_screen *, struct pipe_surface *, - void *context_private); - -#endif diff --git a/src/gallium/winsys/drm/nouveau/dri2/Makefile b/src/gallium/winsys/drm/nouveau/dri2/Makefile deleted file mode 100644 index 377a80d518..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri2/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -TOP = ../../../../../.. -include $(TOP)/configs/current - -LIBNAME = nouveau_dri2.so - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/state_trackers/dri/libdridrm.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 - -DRIVER_SOURCES = - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -include ../../Makefile.template - -DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs) - -symlinks: diff --git a/src/gallium/winsys/drm/nouveau/drm/Makefile b/src/gallium/winsys/drm/nouveau/drm/Makefile index 2da78d8690..54c3b26c75 100644 --- a/src/gallium/winsys/drm/nouveau/drm/Makefile +++ b/src/gallium/winsys/drm/nouveau/drm/Makefile @@ -3,9 +3,7 @@ include $(TOP)/configs/current LIBNAME = nouveaudrm -C_SOURCES = nouveau_drm_api.c \ - nouveau_winsys_pipe.c \ - nouveau_winsys.c +C_SOURCES = nouveau_drm_api.c LIBRARY_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I) LIBRARY_DEFINES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-other) diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h index 1207c2d609..1207c2d609 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h 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 a558fda140..091cbbcfed 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c @@ -1,20 +1,70 @@ +#include "pipe/p_context.h" +#include "pipe/p_state.h" #include "util/u_memory.h" #include "nouveau_drm_api.h" -#include "nouveau_winsys_pipe.h" #include "nouveau_drmif.h" #include "nouveau_channel.h" #include "nouveau_bo.h" +#include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_screen.h" + +static struct pipe_surface * +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 *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 * +nouveau_dri1_front_surface(struct pipe_context *pipe) +{ + return nouveau_winsys_screen(pipe->screen)->front; +} + +static struct dri1_api nouveau_dri1_api = { + nouveau_dri1_front_surface, +}; + static struct pipe_screen * -nouveau_drm_create_screen(int fd, struct drm_create_screen_arg *arg) +nouveau_drm_create_screen(struct drm_api *api, int fd, + struct drm_create_screen_arg *arg) { - struct pipe_winsys *ws; + struct dri1_create_screen_arg *dri1 = (void *)arg; struct nouveau_winsys *nvws; + struct pipe_winsys *ws; struct nouveau_device *dev = NULL; struct pipe_screen *(*init)(struct pipe_winsys *, - struct nouveau_winsys *); + struct nouveau_device *); int ret; ret = nouveau_device_open_existing(&dev, 0, fd, 0); @@ -49,33 +99,53 @@ nouveau_drm_create_screen(int fd, struct drm_create_screen_arg *arg) return NULL; } - ws = nouveau_pipe_winsys_new(dev); - if (!ws) { + nvws = CALLOC_STRUCT(nouveau_winsys); + if (!nvws) { nouveau_device_close(&dev); return NULL; } + ws = &nvws->base; - nvws = nouveau_winsys_new(ws); - if (!nvws) { + nvws->pscreen = init(ws, dev); + if (!nvws->pscreen) { ws->destroy(ws); return NULL; } - nouveau_pipe_winsys(ws)->pscreen = init(ws, nvws); - if (!nouveau_pipe_winsys(ws)->pscreen) { - ws->destroy(ws); - return NULL; + if (arg->mode == DRM_CREATE_DRI1) { + struct nouveau_dri *nvdri = dri1->ddx_info; + enum pipe_format format; + + if (nvdri->bpp == 16) + format = PIPE_FORMAT_R5G6B5_UNORM; + else + format = PIPE_FORMAT_A8R8G8B8_UNORM; + + nvws->front = dri_surface_from_handle(api, nvws->pscreen, + nvdri->front_offset, + format, nvdri->width, + nvdri->height, + nvdri->front_pitch * + (nvdri->bpp / 8)); + if (!nvws->front) { + debug_printf("%s: error referencing front buffer\n", + __func__); + ws->destroy(ws); + return NULL; + } + + dri1->api = &nouveau_dri1_api; } - return nouveau_pipe_winsys(ws)->pscreen; + return nvws->pscreen; } static struct pipe_context * -nouveau_drm_create_context(struct pipe_screen *pscreen) +nouveau_drm_create_context(struct drm_api *api, struct pipe_screen *pscreen) { - struct nouveau_pipe_winsys *nvpws = nouveau_screen(pscreen); + struct nouveau_winsys *nvws = nouveau_winsys_screen(pscreen); struct pipe_context *(*init)(struct pipe_screen *, unsigned); - unsigned chipset = nvpws->channel->device->chipset; + unsigned chipset = nouveau_screen(pscreen)->device->chipset; int i; switch (chipset & 0xf0) { @@ -106,89 +176,88 @@ nouveau_drm_create_context(struct pipe_screen *pscreen) } /* Find a free slot for a pipe context, allocate a new one if needed */ - for (i = 0; i < nvpws->nr_pctx; i++) { - if (nvpws->pctx[i] == NULL) + for (i = 0; i < nvws->nr_pctx; i++) { + if (nvws->pctx[i] == NULL) break; } - if (i == nvpws->nr_pctx) { - nvpws->nr_pctx++; - nvpws->pctx = realloc(nvpws->pctx, - sizeof(*nvpws->pctx) * nvpws->nr_pctx); + if (i == nvws->nr_pctx) { + nvws->nr_pctx++; + nvws->pctx = realloc(nvws->pctx, + sizeof(*nvws->pctx) * nvws->nr_pctx); } - nvpws->pctx[i] = init(pscreen, i); - return nvpws->pctx[i]; -} - -static boolean -nouveau_drm_pb_from_pt(struct pipe_texture *pt, struct pipe_buffer **ppb, - unsigned *stride) -{ - return false; + nvws->pctx[i] = init(pscreen, i); + return nvws->pctx[i]; } -static struct pipe_buffer * -nouveau_drm_pb_from_handle(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_pipe_winsys *nvpws = nouveau_screen(pscreen); - struct nouveau_device *dev = nvpws->channel->device; - struct nouveau_pipe_buffer *nvpb; + struct nouveau_device *dev = nouveau_screen(pscreen)->device; + struct pipe_buffer *pb; int ret; - nvpb = CALLOC_STRUCT(nouveau_pipe_buffer); - if (!nvpb) + pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*)); + if (!pb) return NULL; - ret = nouveau_bo_handle_ref(dev, handle, &nvpb->bo); + ret = nouveau_bo_handle_ref(dev, handle, (struct nouveau_bo**)(pb+1)); if (ret) { debug_printf("%s: ref name 0x%08x failed with %d\n", __func__, handle, ret); - FREE(nvpb); + FREE(pb); return NULL; } - pipe_reference_init(&nvpb->base.reference, 1); - nvpb->base.screen = pscreen; - nvpb->base.alignment = 0; - nvpb->base.usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE | - PIPE_BUFFER_USAGE_CPU_READ_WRITE; - nvpb->base.size = nvpb->bo->size; - return &nvpb->base; + pipe_reference_init(&pb->reference, 1); + pb->screen = pscreen; + pb->alignment = 0; + pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE | + PIPE_BUFFER_USAGE_CPU_READ_WRITE; + pb->size = nouveau_bo(pb)->size; + return pscreen->texture_blanket(pscreen, templ, &stride, pb); } static boolean -nouveau_drm_handle_from_pb(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_pipe_buffer *nvpb = nouveau_pipe_buffer(pb); + struct nouveau_miptree *mt = nouveau_miptree(pt); - if (!nvpb) - return FALSE; + if (!mt || !mt->bo) + return false; - *handle = nvpb->bo->handle; - return TRUE; + return nouveau_bo_handle_get(mt->bo, handle) == 0; } static boolean -nouveau_drm_name_from_pb(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_pipe_buffer *nvpb = nouveau_pipe_buffer(pb); + struct nouveau_miptree *mt = nouveau_miptree(pt); - if (!nvpb) - return FALSE; + if (!mt || !mt->bo) + return false; - return nouveau_bo_handle_get(nvpb->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 * +drm_api_create() { + return &drm_api_hooks; +} + diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h index 2782c83c0e..e61e0e0957 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h @@ -1,5 +1,34 @@ #ifndef __NOUVEAU_DRM_API_H__ #define __NOUVEAU_DRM_API_H__ + #include "state_tracker/drm_api.h" +#include "state_tracker/dri1_api.h" + +#include "pipe/internal/p_winsys_screen.h" + +#include "nouveau_dri.h" + +struct nouveau_winsys { + struct pipe_winsys base; + + struct pipe_screen *pscreen; + + unsigned nr_pctx; + struct pipe_context **pctx; + + struct pipe_surface *front; +}; + +static INLINE struct nouveau_winsys * +nouveau_winsys(struct pipe_winsys *ws) +{ + return (struct nouveau_winsys *)ws; +} + +static INLINE struct nouveau_winsys * +nouveau_winsys_screen(struct pipe_screen *pscreen) +{ + return nouveau_winsys(pscreen->winsys); +} #endif diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c deleted file mode 100644 index e3175fd775..0000000000 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "util/u_memory.h" - -#include "nouveau_winsys_pipe.h" - -static int -nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count, - struct nouveau_notifier **notify) -{ - struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(nvws->ws); - - return nouveau_notifier_alloc(nvpws->channel, nvpws->next_handle++, - count, notify); -} - -static int -nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass, - struct nouveau_grobj **grobj) -{ - struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(nvws->ws); - struct nouveau_channel *chan = nvpws->channel; - int ret; - - ret = nouveau_grobj_alloc(chan, nvpws->next_handle++, grclass, grobj); - if (ret) - return ret; - - BEGIN_RING(chan, *grobj, 0x0000, 1); - OUT_RING (chan, (*grobj)->handle); - (*grobj)->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT; - return 0; -} - -static int -nouveau_pipe_push_reloc(struct nouveau_winsys *nvws, void *ptr, - struct pipe_buffer *buf, uint32_t data, - uint32_t flags, uint32_t vor, uint32_t tor) -{ - struct nouveau_bo *bo = nouveau_pipe_buffer(buf)->bo; - - return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, bo, - data, flags, vor, tor); -} - -static int -nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size, - struct pipe_fence_handle **fence) -{ - if (fence) - *fence = NULL; - - return nouveau_pushbuf_flush(nvws->channel, size); -} - -static struct nouveau_bo * -nouveau_pipe_get_bo(struct pipe_buffer *pb) -{ - return nouveau_pipe_buffer(pb)->bo; -} - -struct nouveau_winsys * -nouveau_winsys_new(struct pipe_winsys *ws) -{ - struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws); - struct nouveau_winsys *nvws; - - nvws = CALLOC_STRUCT(nouveau_winsys); - if (!nvws) - return NULL; - - nvws->ws = ws; - nvws->channel = nvpws->channel; - - nvws->res_init = nouveau_resource_init; - nvws->res_alloc = nouveau_resource_alloc; - nvws->res_free = nouveau_resource_free; - - nvws->push_reloc = nouveau_pipe_push_reloc; - nvws->push_flush = nouveau_pipe_push_flush; - - nvws->grobj_alloc = nouveau_pipe_grobj_alloc; - nvws->grobj_free = nouveau_grobj_free; - - nvws->notifier_alloc = nouveau_pipe_notifier_alloc; - nvws->notifier_free = nouveau_notifier_free; - nvws->notifier_reset = nouveau_notifier_reset; - nvws->notifier_status = nouveau_notifier_status; - nvws->notifier_retval = nouveau_notifier_return_val; - nvws->notifier_wait = nouveau_notifier_wait_status; - - nvws->get_bo = nouveau_pipe_get_bo; - - return nvws; -} - diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c deleted file mode 100644 index 9e03a9f5db..0000000000 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c +++ /dev/null @@ -1,204 +0,0 @@ -#include "pipe/internal/p_winsys_screen.h" -#include <pipe/p_defines.h> -#include <pipe/p_inlines.h> -#include <util/u_memory.h> - -#include "nouveau_winsys_pipe.h" - -#include "nouveau_drmif.h" -#include "nouveau_bo.h" - -static const char * -nouveau_get_name(struct pipe_winsys *pws) -{ - return "Nouveau/DRI"; -} - -static uint32_t -nouveau_flags_from_usage(struct pipe_winsys *ws, unsigned usage) -{ - struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws); - struct pipe_screen *pscreen = nvpws->pscreen; - uint32_t flags = NOUVEAU_BO_LOCAL; - - if (usage & NOUVEAU_BUFFER_USAGE_TRANSFER) - flags |= NOUVEAU_BO_GART; - - if (usage & PIPE_BUFFER_USAGE_PIXEL) { - if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) - flags |= NOUVEAU_BO_GART; - if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE)) - flags |= NOUVEAU_BO_VRAM; - - switch (nvpws->channel->device->chipset & 0xf0) { - case 0x50: - case 0x80: - case 0x90: - flags |= NOUVEAU_BO_TILED; - if (usage & NOUVEAU_BUFFER_USAGE_ZETA) - flags |= NOUVEAU_BO_ZTILE; - break; - default: - break; - } - } - - if (usage & PIPE_BUFFER_USAGE_VERTEX) { - if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF)) - flags |= NOUVEAU_BO_GART; - } - - if (usage & PIPE_BUFFER_USAGE_INDEX) { - if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF)) - flags |= NOUVEAU_BO_GART; - } - - return flags; -} - -static struct pipe_buffer * -nouveau_pipe_bo_create(struct pipe_winsys *ws, unsigned alignment, - unsigned usage, unsigned size) -{ - struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws); - struct nouveau_device *dev = nvpws->channel->device; - struct nouveau_pipe_buffer *nvbuf; - uint32_t flags; - - nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer); - if (!nvbuf) - return NULL; - pipe_reference_init(&nvbuf->base.reference, 1); - nvbuf->base.alignment = alignment; - nvbuf->base.usage = usage; - nvbuf->base.size = size; - - flags = nouveau_flags_from_usage(ws, usage); - if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) { - FREE(nvbuf); - return NULL; - } - - return &nvbuf->base; -} - -static struct pipe_buffer * -nouveau_pipe_bo_user_create(struct pipe_winsys *ws, void *ptr, unsigned bytes) -{ - struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws); - struct nouveau_device *dev = nvpws->channel->device; - struct nouveau_pipe_buffer *nvbuf; - - nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer); - if (!nvbuf) - return NULL; - pipe_reference_init(&nvbuf->base.reference, 1); - nvbuf->base.size = bytes; - - if (nouveau_bo_user(dev, ptr, bytes, &nvbuf->bo)) { - FREE(nvbuf); - return NULL; - } - - return &nvbuf->base; -} - -static void -nouveau_pipe_bo_del(struct pipe_buffer *buf) -{ - struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf); - - nouveau_bo_ref(NULL, &nvbuf->bo); - FREE(nvbuf); -} - -static void * -nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, - unsigned flags) -{ - struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf); - uint32_t map_flags = 0; - - if (flags & PIPE_BUFFER_USAGE_CPU_READ) - map_flags |= NOUVEAU_BO_RD; - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) - map_flags |= NOUVEAU_BO_WR; - - if (nouveau_bo_map(nvbuf->bo, map_flags)) - return NULL; - return nvbuf->bo->map; -} - -static void -nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) -{ - struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf); - - nouveau_bo_unmap(nvbuf->bo); -} - -static void -nouveau_pipe_fence_reference(struct pipe_winsys *ws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *pfence) -{ - *ptr = pfence; -} - -static int -nouveau_pipe_fence_signalled(struct pipe_winsys *ws, - struct pipe_fence_handle *pfence, unsigned flag) -{ - return 0; -} - -static int -nouveau_pipe_fence_finish(struct pipe_winsys *ws, - struct pipe_fence_handle *pfence, unsigned flag) -{ - return 0; -} - -static void -nouveau_destroy(struct pipe_winsys *ws) -{ - struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws); - - nouveau_device_close(&nvpws->channel->device); - FREE(nvpws); -} - -struct pipe_winsys * -nouveau_pipe_winsys_new(struct nouveau_device *dev) -{ - struct nouveau_pipe_winsys *nvpws; - int ret; - - nvpws = CALLOC_STRUCT(nouveau_pipe_winsys); - if (!nvpws) - return NULL; - - ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202, - &nvpws->channel); - if (ret) { - debug_printf("%s: error opening GPU channel: %d\n", - __func__, ret); - FREE(nvpws); - return NULL; - } - nvpws->next_handle = 0x77000000; - - nvpws->base.buffer_create = nouveau_pipe_bo_create; - nvpws->base.buffer_destroy = nouveau_pipe_bo_del; - nvpws->base.user_buffer_create = nouveau_pipe_bo_user_create; - nvpws->base.buffer_map = nouveau_pipe_bo_map; - nvpws->base.buffer_unmap = nouveau_pipe_bo_unmap; - - nvpws->base.fence_reference = nouveau_pipe_fence_reference; - nvpws->base.fence_signalled = nouveau_pipe_fence_signalled; - nvpws->base.fence_finish = nouveau_pipe_fence_finish; - - nvpws->base.get_name = nouveau_get_name; - nvpws->base.destroy = nouveau_destroy; - return &nvpws->base; -} diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h deleted file mode 100644 index 10e1e269e8..0000000000 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef NOUVEAU_PIPE_WINSYS_H -#define NOUVEAU_PIPE_WINSYS_H - -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_context.h" - -#include "nouveau/nouveau_winsys.h" - -#include "nouveau_device.h" - -struct nouveau_pipe_buffer { - struct pipe_buffer base; - struct nouveau_bo *bo; -}; - -static INLINE struct nouveau_pipe_buffer * -nouveau_pipe_buffer(struct pipe_buffer *buf) -{ - return (struct nouveau_pipe_buffer *)buf; -} - -struct nouveau_pipe_winsys { - struct pipe_winsys base; - - struct pipe_screen *pscreen; - - struct nouveau_channel *channel; - uint32_t next_handle; - - unsigned nr_pctx; - struct pipe_context **pctx; -}; - -static INLINE struct nouveau_pipe_winsys * -nouveau_pipe_winsys(struct pipe_winsys *ws) -{ - return (struct nouveau_pipe_winsys *)ws; -} - -static INLINE struct nouveau_pipe_winsys * -nouveau_screen(struct pipe_screen *pscreen) -{ - return nouveau_pipe_winsys(pscreen->winsys); -} - -struct pipe_winsys * -nouveau_pipe_winsys_new(struct nouveau_device *); - -struct nouveau_winsys * -nouveau_winsys_new(struct pipe_winsys *ws); - -#endif diff --git a/src/gallium/winsys/drm/radeon/SConscript b/src/gallium/winsys/drm/radeon/SConscript index 8f99055b2f..b2dfd504d4 100644 --- a/src/gallium/winsys/drm/radeon/SConscript +++ b/src/gallium/winsys/drm/radeon/SConscript @@ -4,4 +4,4 @@ SConscript(['core/SConscript',]) if 'mesa' in env['statetrackers']: - SConscript(['dri2/SConscript']) + SConscript(['dri/SConscript']) diff --git a/src/gallium/winsys/drm/radeon/core/SConscript b/src/gallium/winsys/drm/radeon/core/SConscript index 578174e32b..2ad68e403f 100644 --- a/src/gallium/winsys/drm/radeon/core/SConscript +++ b/src/gallium/winsys/drm/radeon/core/SConscript @@ -11,7 +11,9 @@ radeon_sources = [ env.Append(CPPPATH = '#/src/gallium/drivers/r300') -env.ConvenienceLibrary( +radeonwinsys = env.ConvenienceLibrary( target ='radeonwinsys', source = radeon_sources, ) + +Export('radeonwinsys') diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c index a15487352b..07551e7cd1 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c @@ -1,8 +1,8 @@ -/* +/* * Copyright © 2008 Jérôme Glisse * 2009 Corbin Simpson * 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 @@ -10,14 +10,14 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * The above copyright notice and this permission notice (including the @@ -72,6 +72,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; } @@ -93,6 +94,29 @@ static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws, return &radeon_buffer->base; } +static struct pipe_buffer *radeon_surface_buffer_create(struct pipe_winsys *ws, + unsigned width, + unsigned height, + enum pipe_format format, + unsigned usage, + unsigned *stride) +{ + struct pipe_format_block block; + unsigned nblocksx, nblocksy, size; + + pf_get_block(format, &block); + + nblocksx = pf_get_nblocksx(&block, width); + nblocksy = pf_get_nblocksy(&block, height); + + /* Radeons enjoy things in multiples of 32. */ + /* XXX this can be 32 when POT */ + *stride = (nblocksx * block.size + 63) & ~63; + size = *stride * nblocksy; + + return radeon_buffer_create(ws, 64, usage, size); +} + static void radeon_buffer_del(struct pipe_buffer *buffer) { struct radeon_pipe_buffer *radeon_buffer = @@ -110,16 +134,17 @@ static void *radeon_buffer_map(struct pipe_winsys *ws, (struct radeon_pipe_buffer*)buffer; int write = 0; - if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { - /* XXX Remove this when radeon_bo_map supports DONTBLOCK */ - return NULL; + if (!(flags & PIPE_BUFFER_USAGE_DONTBLOCK)) { + radeon_bo_wait(radeon_buffer->bo); } if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) { write = 1; } - if (radeon_bo_map(radeon_buffer->bo, write)) + if (radeon_bo_map(radeon_buffer->bo, write)) { return NULL; + } + return radeon_buffer->bo->ptr; } @@ -175,15 +200,17 @@ struct radeon_winsys* radeon_pipe_winsys(int fd) return NULL; } + radeon_ws->priv->fd = fd; radeon_ws->priv->bom = radeon_bo_manager_gem_ctor(fd); radeon_ws->base.flush_frontbuffer = radeon_flush_frontbuffer; radeon_ws->base.buffer_create = radeon_buffer_create; - radeon_ws->base.buffer_destroy = radeon_buffer_del; radeon_ws->base.user_buffer_create = radeon_buffer_user_create; + radeon_ws->base.surface_buffer_create = radeon_surface_buffer_create; radeon_ws->base.buffer_map = radeon_buffer_map; radeon_ws->base.buffer_unmap = radeon_buffer_unmap; + radeon_ws->base.buffer_destroy = radeon_buffer_del; radeon_ws->base.fence_reference = radeon_fence_reference; radeon_ws->base.fence_signalled = radeon_fence_signalled; diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h index ca8bbb3c11..f5153b06af 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h @@ -1,7 +1,7 @@ -/* +/* * Copyright © 2008 Jérôme Glisse * 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 @@ -9,14 +9,14 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * The above copyright notice and this permission notice (including the @@ -48,19 +48,19 @@ struct radeon_pipe_buffer { struct pipe_buffer base; struct radeon_bo *bo; + boolean flinked; + uint32_t flink; }; #define RADEON_MAX_BOS 24 struct radeon_winsys_priv { + /* DRM FD */ + int fd; + /* 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 428d3f65a1..47376a0f07 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c @@ -1,7 +1,7 @@ -/* +/* * Copyright © 2009 Corbin Simpson * 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 @@ -9,14 +9,14 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * The above copyright notice and this permission notice (including the @@ -26,13 +26,15 @@ /* * Authors: * Corbin Simpson <MostAwesomeDude@gmail.com> + * Joakim Sindholt <opensource@zhasha.com> */ #include "radeon_drm.h" /* Create a pipe_screen. */ -struct pipe_screen* radeon_create_screen(int drmFB, - struct drm_create_screen_arg *arg) +struct pipe_screen* radeon_create_screen(struct drm_api* api, + int drmFB, + struct drm_create_screen_arg *arg) { struct radeon_winsys* winsys = radeon_pipe_winsys(drmFB); @@ -46,25 +48,30 @@ struct pipe_screen* radeon_create_screen(int drmFB, } /* Create a pipe_context. */ -struct pipe_context* radeon_create_context(struct pipe_screen* screen) +struct pipe_context* radeon_create_context(struct drm_api* api, + struct pipe_screen* screen) { 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); } } -boolean radeon_buffer_from_texture(struct pipe_texture* texture, +boolean radeon_buffer_from_texture(struct drm_api* api, + struct pipe_texture* texture, struct pipe_buffer** buffer, unsigned* stride) { - return FALSE; + /* XXX fix this */ + return r300_get_texture_buffer(texture, buffer, stride); } /* Create a buffer from a handle. */ /* XXX what's up with name? */ -struct pipe_buffer* radeon_buffer_from_handle(struct pipe_screen* screen, +struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api, + struct pipe_screen* screen, const char* name, unsigned handle) { @@ -91,33 +98,89 @@ struct pipe_buffer* radeon_buffer_from_handle(struct pipe_screen* screen, return &radeon_buffer->base; } -boolean radeon_handle_from_buffer(struct pipe_screen* screen, - struct pipe_buffer* buffer, - unsigned* handle) +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 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_shared_handle_from_texture(struct drm_api *api, + struct pipe_screen *screen, + struct pipe_texture *texture, + unsigned *stride, + unsigned *handle) { - struct radeon_pipe_buffer* radeon_buffer = - (struct radeon_pipe_buffer*)buffer; - *handle = radeon_buffer->bo->handle; + int retval, fd; + struct drm_gem_flink flink; + struct radeon_pipe_buffer* radeon_buffer; + struct pipe_buffer* buffer = &radeon_buffer->base; + if (!radeon_buffer_from_texture(api, texture, buffer, stride)) { + return FALSE; + } + + if (!radeon_buffer->flinked) { + fd = ((struct radeon_winsys*)screen->winsys)->priv->fd; + + flink.handle = radeon_buffer->bo->handle; + + retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); + if (retval) { + debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n", + retval); + return FALSE; + } + + radeon_buffer->flink = flink.name; + radeon_buffer->flinked = TRUE; + } + + *handle = radeon_buffer->flink; return TRUE; } -boolean radeon_global_handle_from_buffer(struct pipe_screen* screen, - struct pipe_buffer* buffer, - unsigned* handle) +boolean radeon_local_handle_from_texture(struct drm_api *api, + struct pipe_screen *screen, + struct pipe_texture *texture, + unsigned *stride, + unsigned *handle) { - /* XXX WTF is the difference here? global? */ - struct radeon_pipe_buffer* radeon_buffer = - (struct radeon_pipe_buffer*)buffer; - *handle = radeon_buffer->bo->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, - /* XXX fix this */ - .buffer_from_texture = r300_get_texture_buffer, - .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() +{ +#ifdef DEBUG + return trace_drm_create(&drm_api_hooks); +#else + return &drm_api_hooks; +#endif +} diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h index 049f9984db..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,25 +45,35 @@ #include "radeon_r300.h" #include "radeon_winsys_softpipe.h" -struct pipe_screen* radeon_create_screen(int drmFB, +/* XXX */ +#include "r300_screen.h" + +struct pipe_screen* radeon_create_screen(struct drm_api* api, + int drmFB, struct drm_create_screen_arg *arg); -struct pipe_context* radeon_create_context(struct pipe_screen* screen); +struct pipe_context* radeon_create_context(struct drm_api* api, + struct pipe_screen* screen); -boolean radeon_buffer_from_texture(struct pipe_texture* texture, +boolean radeon_buffer_from_texture(struct drm_api* api, + struct pipe_texture* texture, struct pipe_buffer** buffer, unsigned* stride); -struct pipe_buffer* radeon_buffer_from_handle(struct pipe_screen* screen, +struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api, + struct pipe_screen* screen, const char* name, unsigned handle); -boolean radeon_handle_from_buffer(struct pipe_screen* screen, +boolean radeon_handle_from_buffer(struct drm_api* api, + struct pipe_screen* screen, struct pipe_buffer* buffer, unsigned* handle); -boolean radeon_global_handle_from_buffer(struct pipe_screen* screen, +boolean radeon_global_handle_from_buffer(struct drm_api* api, + struct pipe_screen* screen, struct pipe_buffer* buffer, unsigned* handle); +void radeon_destroy_drm_api(struct drm_api* api); #endif diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index da233203d7..d723876221 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -22,54 +22,30 @@ #include "radeon_r300.h" -static void radeon_r300_add_buffer(struct r300_winsys* winsys, - struct pipe_buffer* pbuffer, - uint32_t rd, - uint32_t wd) +static boolean radeon_r300_add_buffer(struct r300_winsys* winsys, + struct pipe_buffer* pbuffer, + 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 < RADEON_MAX_BOS; i++) { - if (sc[i].bo == bo) { - return; - } else if (sc[i].bo == NULL) { - sc[i].bo = bo; - sc[i].read_domains = rd; - sc[i].write_domain = wd; - priv->bo_count = i + 1; - return; - } - } - - assert(FALSE && "Oh God too many BOs!"); + radeon_cs_space_add_persistent_bo(priv->cs, bo, rd, wd); + return TRUE; } static boolean radeon_r300_validate(struct r300_winsys* winsys) { - int retval; 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. */ - exit(1); - } else if (retval == RADEON_CS_SPACE_FLUSH) { - /* We must flush before more rendering can commence. */ - 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) @@ -108,9 +84,15 @@ static void radeon_r300_write_cs_reloc(struct r300_winsys* winsys, { struct radeon_winsys_priv* priv = (struct radeon_winsys_priv*)winsys->radeon_winsys; + int retval = 0; - radeon_cs_write_reloc(priv->cs, + retval = radeon_cs_write_reloc(priv->cs, ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags); + + if (retval) { + debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", + pbuffer, rd, wd, flags); + } } static void radeon_r300_end_cs(struct r300_winsys* winsys, @@ -128,57 +110,66 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys) { struct radeon_winsys_priv* priv = (struct radeon_winsys_priv*)winsys->radeon_winsys; - int retval = 0; + int retval; + /* Emit the CS. */ retval = radeon_cs_emit(priv->cs); if (retval) { debug_printf("radeon: Bad CS, dumping...\n"); radeon_cs_print(priv->cs, stderr); } + + /* Clean out BOs. */ + 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 info; - drm_radeon_getparam_t gp; - int target; + struct drm_radeon_gem_info gem_info = {0}; + struct drm_radeon_info info = {0}; + int target = 0; int retval; - gp.value = ⌖ + info.value = ⌖ /* First, get the number of pixel pipes */ - gp.param = RADEON_PARAM_NUM_GB_PIPES; - retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); + 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); + fprintf(stderr, "%s: Failed to get GB pipe count, " + "error number %d\n", __FUNCTION__, retval); exit(1); } winsys->gb_pipes = target; /* Then, get PCI ID */ - gp.param = RADEON_PARAM_DEVICE_ID; - retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); + info.request = RADEON_INFO_DEVICE_ID; + retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); if (retval) { - fprintf(stderr, "%s: Failed to get PCI ID, error number %d\n", - __FUNCTION__, retval); + fprintf(stderr, "%s: Failed to get PCI ID, " + "error number %d\n", __FUNCTION__, retval); exit(1); } winsys->pci_id = target; /* Finally, retrieve MM info */ retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO, - &info, sizeof(info)); + &gem_info, sizeof(gem_info)); if (retval) { fprintf(stderr, "%s: Failed to get MM info, error number %d\n", __FUNCTION__, retval); exit(1); } - winsys->gart_size = info.gart_size; + winsys->gart_size = gem_info.gart_size; /* XXX */ - winsys->vram_size = info.vram_visible; + winsys->vram_size = gem_info.vram_visible; } struct r300_winsys* diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h index 5c373cd084..775d7937fd 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h @@ -20,16 +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" +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/dri/Makefile b/src/gallium/winsys/drm/radeon/dri/Makefile index c218ee9d01..a9889444de 100644 --- a/src/gallium/winsys/drm/radeon/dri/Makefile +++ b/src/gallium/winsys/drm/radeon/dri/Makefile @@ -10,6 +10,7 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \ $(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/r300/libr300.a C_SOURCES = \ diff --git a/src/gallium/winsys/drm/radeon/dri/SConscript b/src/gallium/winsys/drm/radeon/dri/SConscript index f2cdee97d9..aea987a3ac 100644 --- a/src/gallium/winsys/drm/radeon/dri/SConscript +++ b/src/gallium/winsys/drm/radeon/dri/SConscript @@ -2,7 +2,10 @@ Import('*') env = drienv.Clone() +env.ParseConfig('pkg-config --cflags --libs libdrm_radeon') + drivers = [ + trace, softpipe, r300 ] @@ -10,5 +13,5 @@ drivers = [ env.SharedLibrary( target ='radeon_dri.so', source = COMMON_GALLIUM_SOURCES, - LIBS = drivers + mesa + auxiliaries + env['LIBS'], + LIBS = st_dri + radeonwinsys + mesa + drivers + auxiliaries + env['LIBS'], ) diff --git a/src/gallium/winsys/drm/radeon/egl/Makefile b/src/gallium/winsys/drm/radeon/egl/Makefile index d989b3aa93..6a1448d1b9 100644 --- a/src/gallium/winsys/drm/radeon/egl/Makefile +++ b/src/gallium/winsys/drm/radeon/egl/Makefile @@ -8,6 +8,7 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ $(GALLIUMDIR)/winsys/drm/radeon/core/libradeonwinsys.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/r300/libr300.a DRIVER_SOURCES = diff --git a/src/gallium/winsys/drm/radeon/xorg/Makefile b/src/gallium/winsys/drm/radeon/xorg/Makefile index 6ffd4a3a54..0241625f69 100644 --- a/src/gallium/winsys/drm/radeon/xorg/Makefile +++ b/src/gallium/winsys/drm/radeon/xorg/Makefile @@ -37,6 +37,6 @@ clean: install: $(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR) - $(INSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR) + $(MINSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR) .PHONY = all clean install 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; |