From b642730be93149baa7556e5791393168ab396175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Feb 2008 17:35:24 +0900 Subject: Code reorganization: move files into their places. This is in a separate commit to ensure renames are properly preserved. --- src/gallium/winsys/dri/intel/Makefile | 38 + src/gallium/winsys/dri/intel/SConscript | 41 + src/gallium/winsys/dri/intel/intel_batchbuffer.c | 357 +++ src/gallium/winsys/dri/intel/intel_batchbuffer.h | 149 + src/gallium/winsys/dri/intel/intel_batchpool.c | 424 +++ src/gallium/winsys/dri/intel/intel_batchpool.h | 37 + src/gallium/winsys/dri/intel/intel_context.c | 304 ++ src/gallium/winsys/dri/intel/intel_context.h | 158 + src/gallium/winsys/dri/intel/intel_lock.c | 102 + src/gallium/winsys/dri/intel/intel_reg.h | 53 + src/gallium/winsys/dri/intel/intel_screen.c | 537 ++++ src/gallium/winsys/dri/intel/intel_screen.h | 113 + src/gallium/winsys/dri/intel/intel_swapbuffers.c | 253 ++ src/gallium/winsys/dri/intel/intel_swapbuffers.h | 47 + src/gallium/winsys/dri/intel/intel_winsys.h | 73 + src/gallium/winsys/dri/intel/intel_winsys_i915.c | 154 + src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 302 ++ .../winsys/dri/intel/intel_winsys_softpipe.c | 81 + src/gallium/winsys/dri/intel/server/i830_common.h | 226 ++ src/gallium/winsys/dri/intel/server/i830_dri.h | 63 + src/gallium/winsys/dri/intel/server/intel.h | 331 ++ src/gallium/winsys/dri/intel/server/intel_dri.c | 1306 ++++++++ src/gallium/winsys/xlib/brw_aub.c | 392 +++ src/gallium/winsys/xlib/brw_aub.h | 114 + src/gallium/winsys/xlib/fakeglx.c | 3188 ++++++++++++++++++++ src/gallium/winsys/xlib/glxapi.c | 1408 +++++++++ src/gallium/winsys/xlib/glxapi.h | 228 ++ src/gallium/winsys/xlib/glxheader.h | 62 + src/gallium/winsys/xlib/realglx.c | 180 ++ src/gallium/winsys/xlib/realglx.h | 326 ++ src/gallium/winsys/xlib/xfonts.c | 377 +++ src/gallium/winsys/xlib/xfonts.h | 41 + src/gallium/winsys/xlib/xm_api.c | 1380 +++++++++ src/gallium/winsys/xlib/xm_image.c | 133 + src/gallium/winsys/xlib/xm_image.h | 77 + src/gallium/winsys/xlib/xm_winsys.c | 466 +++ src/gallium/winsys/xlib/xm_winsys_aub.c | 589 ++++ src/gallium/winsys/xlib/xm_winsys_aub.h | 67 + src/gallium/winsys/xlib/xmesaP.h | 176 ++ 39 files changed, 14353 insertions(+) create mode 100644 src/gallium/winsys/dri/intel/Makefile create mode 100644 src/gallium/winsys/dri/intel/SConscript create mode 100644 src/gallium/winsys/dri/intel/intel_batchbuffer.c create mode 100644 src/gallium/winsys/dri/intel/intel_batchbuffer.h create mode 100644 src/gallium/winsys/dri/intel/intel_batchpool.c create mode 100644 src/gallium/winsys/dri/intel/intel_batchpool.h create mode 100644 src/gallium/winsys/dri/intel/intel_context.c create mode 100644 src/gallium/winsys/dri/intel/intel_context.h create mode 100644 src/gallium/winsys/dri/intel/intel_lock.c create mode 100644 src/gallium/winsys/dri/intel/intel_reg.h create mode 100644 src/gallium/winsys/dri/intel/intel_screen.c create mode 100644 src/gallium/winsys/dri/intel/intel_screen.h create mode 100644 src/gallium/winsys/dri/intel/intel_swapbuffers.c create mode 100644 src/gallium/winsys/dri/intel/intel_swapbuffers.h create mode 100644 src/gallium/winsys/dri/intel/intel_winsys.h create mode 100644 src/gallium/winsys/dri/intel/intel_winsys_i915.c create mode 100644 src/gallium/winsys/dri/intel/intel_winsys_pipe.c create mode 100644 src/gallium/winsys/dri/intel/intel_winsys_softpipe.c create mode 100644 src/gallium/winsys/dri/intel/server/i830_common.h create mode 100644 src/gallium/winsys/dri/intel/server/i830_dri.h create mode 100644 src/gallium/winsys/dri/intel/server/intel.h create mode 100644 src/gallium/winsys/dri/intel/server/intel_dri.c create mode 100644 src/gallium/winsys/xlib/brw_aub.c create mode 100644 src/gallium/winsys/xlib/brw_aub.h create mode 100644 src/gallium/winsys/xlib/fakeglx.c create mode 100644 src/gallium/winsys/xlib/glxapi.c create mode 100644 src/gallium/winsys/xlib/glxapi.h create mode 100644 src/gallium/winsys/xlib/glxheader.h create mode 100644 src/gallium/winsys/xlib/realglx.c create mode 100644 src/gallium/winsys/xlib/realglx.h create mode 100644 src/gallium/winsys/xlib/xfonts.c create mode 100644 src/gallium/winsys/xlib/xfonts.h create mode 100644 src/gallium/winsys/xlib/xm_api.c create mode 100644 src/gallium/winsys/xlib/xm_image.c create mode 100644 src/gallium/winsys/xlib/xm_image.h create mode 100644 src/gallium/winsys/xlib/xm_winsys.c create mode 100644 src/gallium/winsys/xlib/xm_winsys_aub.c create mode 100644 src/gallium/winsys/xlib/xm_winsys_aub.h create mode 100644 src/gallium/winsys/xlib/xmesaP.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile new file mode 100644 index 0000000000..9ae0f01325 --- /dev/null +++ b/src/gallium/winsys/dri/intel/Makefile @@ -0,0 +1,38 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = i915tex_dri.so + +MINIGLX_SOURCES = server/intel_dri.c + +PIPE_DRIVERS = \ + $(TOP)/src/mesa/pipe/softpipe/libsoftpipe.a \ + $(TOP)/src/mesa/pipe/i915simple/libi915simple.a + +DRIVER_SOURCES = \ + intel_winsys_pipe.c \ + intel_winsys_softpipe.c \ + intel_winsys_i915.c \ + intel_batchbuffer.c \ + intel_swapbuffers.c \ + intel_context.c \ + intel_lock.c \ + intel_screen.c \ + intel_batchpool.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(COMMON_BM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") + +include ../Makefile.template + +intel_tex_layout.o: ../intel/intel_tex_layout.c + +symlinks: diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript new file mode 100644 index 0000000000..a7cc10450e --- /dev/null +++ b/src/gallium/winsys/dri/intel/SConscript @@ -0,0 +1,41 @@ +Import('*') + +env = drienv.Clone() + +env.Append(CPPPATH = [ + '../intel', + 'server' +]) + +#MINIGLX_SOURCES = server/intel_dri.c + +pipe_drivers = [ + softpipe, + i915simple +] + +DRIVER_SOURCES = [ + 'intel_winsys_pipe.c', + 'intel_winsys_softpipe.c', + 'intel_winsys_i915.c', + 'intel_batchbuffer.c', + 'intel_swapbuffers.c', + 'intel_context.c', + 'intel_lock.c', + 'intel_screen.c', + 'intel_batchpool.c', +] + +sources = \ + COMMON_GALLIUM_SOURCES + \ + COMMON_BM_SOURCES + \ + DRIVER_SOURCES + +# DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ +# && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") + +env.SharedLibrary( + target ='i915tex_dri.so', + source = sources, + LIBS = pipe_drivers + env['LIBS'], +) \ No newline at end of file diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c new file mode 100644 index 0000000000..49e04d81ec --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -0,0 +1,357 @@ +/************************************************************************** + * + * Copyright 2006 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 +#include "intel_batchbuffer.h" +#include "intel_context.h" +#include "intel_screen.h" +#include "intel_reg.h" +#include "drm.h" + +/* Relocations in kernel space: + * - pass dma buffer seperately + * - memory manager knows how to patch + * - pass list of dependent buffers + * - pass relocation list + * + * Either: + * - get back an offset for buffer to fire + * - memory manager knows how to fire buffer + * + * Really want the buffer to be AGP and pinned. + * + */ + +/* Cliprect fence: The highest fence protecting a dma buffer + * containing explicit cliprect information. Like the old drawable + * lock but irq-driven. X server must wait for this fence to expire + * before changing cliprects [and then doing sw rendering?]. For + * other dma buffers, the scheduler will grab current cliprect info + * and mix into buffer. X server must hold the lock while changing + * cliprects??? Make per-drawable. Need cliprects in shared memory + * -- beats storing them with every cmd buffer in the queue. + * + * ==> X server must wait for this fence to expire before touching the + * framebuffer with new cliprects. + * + * ==> Cliprect-dependent buffers associated with a + * cliprect-timestamp. All of the buffers associated with a timestamp + * must go to hardware before any buffer with a newer timestamp. + * + * ==> Dma should be queued per-drawable for correct X/GL + * synchronization. Or can fences be used for this? + * + * Applies to: Blit operations, metaops, X server operations -- X + * server automatically waits on its own dma to complete before + * modifying cliprects ??? + */ + +static void +intel_dump_batchbuffer(uint offset, uint * ptr, uint count) +{ + int i; + printf("\n\n\nSTART BATCH (%d dwords):\n", count / 4); + for (i = 0; i < count / 4; i += 1) + printf("\t0x%08x\n", ptr[i]); + printf("END BATCH\n\n\n"); +} + + +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) +{ + int i; + + if (batch->map) { + driBOUnmap(batch->buffer); + batch->map = NULL; + } + + /* + * Get a new, free batchbuffer. + */ + batch->size = BATCH_SZ; + driBOData(batch->buffer, batch->size, NULL, 0); + + driBOResetList(&batch->list); + + /* + * Unreference buffers previously on the relocation list. + */ + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + driBOUnReference(r->buf); + } + + batch->list_count = 0; + batch->nr_relocs = 0; + batch->flags = 0; + + /* + * We don't refcount the batchbuffer itself since we can't destroy it + * while it's on the list. + */ + + driBOAddListItem(&batch->list, batch->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE); + + + batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->ptr = batch->map; +} + + +/*====================================================================== + * Public functions + */ +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_context *intel) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + + driGenBuffers(intel->intelScreen->batchPool, "batchbuffer", 1, + &batch->buffer, 4096, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); + batch->last_fence = NULL; + driBOCreateList(20, &batch->list); + intel_batchbuffer_reset(batch); + return batch; +} + + +void +intel_batchbuffer_free(struct intel_batchbuffer *batch) +{ + if (batch->last_fence) { + driFenceFinish(batch->last_fence, + DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, + GL_FALSE); + driFenceUnReference(batch->last_fence); + batch->last_fence = NULL; + } + if (batch->map) { + driBOUnmap(batch->buffer); + batch->map = NULL; + } + driBOUnReference(batch->buffer); + batch->buffer = NULL; + free(batch); +} + + +static void +intel_batch_ioctl(struct intel_context *intel, + uint start_offset, uint used, boolean allow_unlock) +{ + drmI830BatchBuffer batch; + + batch.start = start_offset; + batch.used = used; + batch.cliprects = NULL; /* unused */ + batch.num_cliprects = 0; + batch.DR1 = 0; + batch.DR4 = 0; /* still need this ? */ + + DBG(IOCTL, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n", + __FUNCTION__, + batch.start, + batch.start + batch.used * 4, batch.DR4, batch.num_cliprects); + + if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch, + sizeof(batch))) { + printf("DRM_I830_BATCHBUFFER: %d\n", -errno); + UNLOCK_HARDWARE(intel); + exit(1); + } +} + + +/* TODO: Push this whole function into bufmgr. + */ +static void +do_flush_locked(struct intel_batchbuffer *batch, + uint used, boolean allow_unlock) +{ + uint *ptr; + uint i, fenceFlags; + struct _DriFenceObject *fo; + + driBOValidateList(batch->intel->driFd, &batch->list); + + /* Apply the relocations. This nasty map indicates to me that the + * whole task should be done internally by the memory manager, and + * that dma buffers probably need to be pinned within agp space. + */ + ptr = (uint *) driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_ALLOW_UNFENCED_MAP); + + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + + ptr[r->offset / 4] = driBOOffset(r->buf) + r->delta; + } + + if (0) + intel_dump_batchbuffer(0, ptr, used); + + driBOUnmap(batch->buffer); + batch->map = NULL; + + intel_batch_ioctl(batch->intel, + driBOOffset(batch->buffer), + used, allow_unlock); + + /* + * Kernel fencing. The flags tells the kernel that we've + * programmed an MI_FLUSH. + */ + fenceFlags = DRM_I915_FENCE_FLAG_FLUSHED; + fo = driFenceBuffers(batch->intel->driFd, "Batch fence", fenceFlags); + + /* + * User space fencing. + */ + driBOFence(batch->buffer, fo); + + if (driFenceType(fo) == DRM_FENCE_TYPE_EXE) { + /* + * Oops. We only validated a batch buffer. This means we + * didn't do any proper rendering. Discard this fence object. + */ + driFenceUnReference(fo); + } + else { + driFenceUnReference(batch->last_fence); + batch->last_fence = fo; + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + driBOFence(r->buf, fo); + } + } +} + + +struct _DriFenceObject * +intel_batchbuffer_flush(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + uint used = batch->ptr - batch->map; + const boolean was_locked = intel->locked; + + if (used == 0) + return batch->last_fence; + +#define MI_FLUSH ((0 << 29) | (4 << 23)) + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ + if (used & 4) { + ((int *) batch->ptr)[0] = MI_FLUSH; + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = MI_FLUSH; + ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } + + driBOUnmap(batch->buffer); + batch->ptr = NULL; + batch->map = NULL; + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!was_locked) + LOCK_HARDWARE(intel); + + do_flush_locked(batch, used, GL_FALSE); + + if (!was_locked) + UNLOCK_HARDWARE(intel); + + /* Reset the buffer: + */ + intel_batchbuffer_reset(batch); + return batch->last_fence; +} + + +void +intel_batchbuffer_finish(struct intel_batchbuffer *batch) +{ + struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); + if (fence) { + driFenceReference(fence); + driFenceFinish(fence, + DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, + GL_FALSE); + driFenceUnReference(fence); + } +} + + +/* This is the only way buffers get added to the validate list. + */ +boolean +intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + struct _DriBufferObject *buffer, + uint flags, uint mask, uint delta) +{ + assert(batch->nr_relocs < MAX_RELOCS); + + driBOAddListItem(&batch->list, buffer, flags, mask); + + { + struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; + driBOReference(buffer); + r->buf = buffer; + r->offset = batch->ptr - batch->map; + r->delta = delta; + *(uint *) batch->ptr = 0x12345678; + } + + batch->ptr += 4; + return GL_TRUE; +} + + +void +intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, uint bytes, uint flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; +} diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h new file mode 100644 index 0000000000..82feafa21f --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -0,0 +1,149 @@ +/************************************************************************** + * + * Copyright 2007 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. + * + **************************************************************************/ + +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "pipe/p_compiler.h" +#include "dri_bufmgr.h" + +struct intel_context; + +#define BATCH_SZ 16384 +#define BATCH_RESERVED 16 + +#define MAX_RELOCS 4096 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct buffer_reloc +{ + struct _DriBufferObject *buf; + uint offset; + uint delta; /* not needed? */ +}; + +struct intel_batchbuffer +{ + struct bufmgr *bm; + struct intel_context *intel; + + struct _DriBufferObject *buffer; + struct _DriFenceObject *last_fence; + uint flags; + + drmBOList list; + uint list_count; + ubyte *map; + ubyte *ptr; + + struct buffer_reloc reloc[MAX_RELOCS]; + uint nr_relocs; + uint size; +}; + +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context *intel); + +void intel_batchbuffer_free(struct intel_batchbuffer *batch); + + +void intel_batchbuffer_finish(struct intel_batchbuffer *batch); + +struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer + *batch); + +void intel_batchbuffer_reset(struct intel_batchbuffer *batch); + + +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multiple + * intel_buffer_dword() calls. + */ +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, uint bytes, uint flags); + +void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, + uint bytes); + +boolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + struct _DriBufferObject *buffer, + uint flags, + uint mask, uint offset); + +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static INLINE uint +intel_batchbuffer_space(struct intel_batchbuffer *batch) +{ + return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); +} + + +static INLINE void +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, uint dword) +{ + assert(batch->map); + assert(intel_batchbuffer_space(batch) >= 4); + *(uint *) (batch->ptr) = dword; + batch->ptr += 4; +} + +static INLINE void +intel_batchbuffer_require_space(struct intel_batchbuffer *batch, + uint sz, uint flags) +{ + assert(sz < batch->size - 8); + if (intel_batchbuffer_space(batch) < sz || + (batch->flags != 0 && flags != 0 && batch->flags != flags)) + intel_batchbuffer_flush(batch); + + batch->flags |= flags; +} + +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS + +#define BEGIN_BATCH(n, flags) do { \ + intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ +} while (0) + +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) + +#define OUT_RELOC(buf,flags,mask,delta) do { \ + assert((delta) >= 0); \ + intel_batchbuffer_emit_reloc(intel->batch, buf, flags, mask, delta); \ +} while (0) + +#define ADVANCE_BATCH() do { } while(0) + + +#endif diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.c b/src/gallium/winsys/dri/intel/intel_batchpool.c new file mode 100644 index 0000000000..33b56817f6 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_batchpool.c @@ -0,0 +1,424 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +/** + * XXX NOTE: there are no intel dependencies in this file. + * Rename to dri_batchpool.c? + */ + +#include +#include +#include +#include "imports.h" +#include "glthread.h" +#include "dri_bufpool.h" +#include "dri_bufmgr.h" +#include "intel_batchpool.h" + + +typedef struct +{ + drmMMListHead head; + struct _BPool *parent; + struct _DriFenceObject *fence; + unsigned long start; + int unfenced; + int mapped; +} BBuf; + +typedef struct _BPool +{ + _glthread_Mutex mutex; + unsigned long bufSize; + unsigned poolSize; + unsigned numFree; + unsigned numTot; + unsigned numDelayed; + unsigned checkDelayed; + drmMMListHead free; + drmMMListHead delayed; + drmMMListHead head; + drmBO kernelBO; + void *virtual; + BBuf *bufs; +} BPool; + + +static BPool * +createBPool(int fd, unsigned long bufSize, unsigned numBufs, unsigned flags, + unsigned checkDelayed) +{ + BPool *p = (BPool *) malloc(sizeof(*p)); + BBuf *buf; + int i; + + if (!p) + return NULL; + + p->bufs = (BBuf *) malloc(numBufs * sizeof(*p->bufs)); + if (!p->bufs) { + free(p); + return NULL; + } + + DRMINITLISTHEAD(&p->free); + DRMINITLISTHEAD(&p->head); + DRMINITLISTHEAD(&p->delayed); + + p->numTot = numBufs; + p->numFree = numBufs; + p->bufSize = bufSize; + p->numDelayed = 0; + p->checkDelayed = checkDelayed; + + _glthread_INIT_MUTEX(p->mutex); + + if (drmBOCreate(fd, 0, numBufs * bufSize, 0, NULL, drm_bo_type_dc, + flags, DRM_BO_HINT_DONT_FENCE, &p->kernelBO)) { + free(p->bufs); + free(p); + return NULL; + } + if (drmBOMap(fd, &p->kernelBO, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, + &p->virtual)) { + drmBODestroy(fd, &p->kernelBO); + free(p->bufs); + free(p); + return NULL; + } + + /* + * We unmap the buffer so that we can validate it later. Note that this is + * just a synchronizing operation. The buffer will have a virtual mapping + * until it is destroyed. + */ + + drmBOUnmap(fd, &p->kernelBO); + + buf = p->bufs; + for (i = 0; i < numBufs; ++i) { + buf->parent = p; + buf->fence = NULL; + buf->start = i * bufSize; + buf->mapped = 0; + buf->unfenced = 0; + DRMLISTADDTAIL(&buf->head, &p->free); + buf++; + } + + return p; +} + + +static void +pool_checkFree(BPool * p, int wait) +{ + drmMMListHead *list, *prev; + BBuf *buf; + int signaled = 0; + int i; + + list = p->delayed.next; + + if (p->numDelayed > 3) { + for (i = 0; i < p->numDelayed; i += 3) { + list = list->next; + } + } + + prev = list->prev; + for (; list != &p->delayed; list = prev, prev = list->prev) { + + buf = DRMLISTENTRY(BBuf, list, head); + + if (!signaled) { + if (wait) { + driFenceFinish(buf->fence, DRM_FENCE_TYPE_EXE, 1); + signaled = 1; + } + else { + signaled = driFenceSignaled(buf->fence, DRM_FENCE_TYPE_EXE); + } + } + + if (!signaled) + break; + + driFenceUnReference(buf->fence); + buf->fence = NULL; + DRMLISTDEL(list); + p->numDelayed--; + DRMLISTADD(list, &p->free); + p->numFree++; + } +} + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, unsigned flags, unsigned hint, + unsigned alignment) +{ + BPool *p = (BPool *) pool->data; + + drmMMListHead *item; + + if (alignment && (alignment != 4096)) + return NULL; + + _glthread_LOCK_MUTEX(p->mutex); + + if (p->numFree == 0) + pool_checkFree(p, GL_TRUE); + + if (p->numFree == 0) { + fprintf(stderr, "Out of fixed size buffer objects\n"); + BM_CKFATAL(-ENOMEM); + } + + item = p->free.next; + + if (item == &p->free) { + fprintf(stderr, "Fixed size buffer pool corruption\n"); + } + + DRMLISTDEL(item); + --p->numFree; + + _glthread_UNLOCK_MUTEX(p->mutex); + return (void *) DRMLISTENTRY(BBuf, item, head); +} + + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + _glthread_LOCK_MUTEX(p->mutex); + + if (buf->fence) { + DRMLISTADDTAIL(&buf->head, &p->delayed); + p->numDelayed++; + } + else { + buf->unfenced = 0; + DRMLISTADD(&buf->head, &p->free); + p->numFree++; + } + + if ((p->numDelayed % p->checkDelayed) == 0) + pool_checkFree(p, 0); + + _glthread_UNLOCK_MUTEX(p->mutex); + return 0; +} + + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, void **virtual) +{ + + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + _glthread_LOCK_MUTEX(p->mutex); + + /* + * Currently Mesa doesn't have any condition variables to resolve this + * cleanly in a multithreading environment. + * We bail out instead. + */ + + if (buf->mapped) { + fprintf(stderr, "Trying to map already mapped buffer object\n"); + BM_CKFATAL(-EINVAL); + } + +#if 0 + if (buf->unfenced && !(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) { + fprintf(stderr, "Trying to map an unfenced buffer object 0x%08x" + " 0x%08x %d\n", hint, flags, buf->start); + BM_CKFATAL(-EINVAL); + } + +#endif + + if (buf->fence) { + _glthread_UNLOCK_MUTEX(p->mutex); + return -EBUSY; + } + + buf->mapped = GL_TRUE; + *virtual = (unsigned char *) p->virtual + buf->start; + _glthread_UNLOCK_MUTEX(p->mutex); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) +{ + BBuf *buf = (BBuf *) private; + driFenceFinish(buf->fence, 0x0, lazy); + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + + buf->mapped = 0; + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + return p->kernelBO.offset + buf->start; +} + +static unsigned +pool_flags(struct _DriBufferPool *pool, void *private) +{ + BPool *p = (BPool *) pool->data; + + return p->kernelBO.flags; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + BPool *p = (BPool *) pool->data; + + return p->bufSize; +} + + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + _glthread_LOCK_MUTEX(p->mutex); + if (buf->fence) { + driFenceUnReference(buf->fence); + } + buf->fence = fence; + buf->unfenced = 0; + driFenceReference(buf->fence); + _glthread_UNLOCK_MUTEX(p->mutex); + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + return &p->kernelBO; +} + +static int +pool_validate(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + _glthread_LOCK_MUTEX(p->mutex); + buf->unfenced = GL_TRUE; + _glthread_UNLOCK_MUTEX(p->mutex); + return 0; +} + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + BPool *p = (BPool *) pool->data; + + /* + * Wait on outstanding fences. + */ + + _glthread_LOCK_MUTEX(p->mutex); + while ((p->numFree < p->numTot) && p->numDelayed) { + _glthread_UNLOCK_MUTEX(p->mutex); + sched_yield(); + pool_checkFree(p, GL_TRUE); + _glthread_LOCK_MUTEX(p->mutex); + } + + drmBODestroy(pool->fd, &p->kernelBO); + free(p->bufs); + _glthread_UNLOCK_MUTEX(p->mutex); + free(p); + free(pool); +} + + +struct _DriBufferPool * +driBatchPoolInit(int fd, unsigned flags, + unsigned long bufSize, + unsigned numBufs, unsigned checkDelayed) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + if (!pool) + return NULL; + + pool->data = createBPool(fd, bufSize, numBufs, flags, checkDelayed); + if (!pool->data) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = &pool_validate; + pool->waitIdle = &pool_waitIdle; + pool->setstatic = NULL; + pool->takeDown = &pool_takedown; + return pool; +} diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.h b/src/gallium/winsys/dri/intel/intel_batchpool.h new file mode 100644 index 0000000000..f6a95723bc --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_batchpool.h @@ -0,0 +1,37 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef INTEL_BATCHPOOL_H +#define INTEL_BATCHPOOL_H + +extern struct _DriBufferPool *driBatchPoolInit(int fd, unsigned flags, + unsigned long bufSize, + unsigned numBufs, + unsigned checkDelayed); + + +#endif /* INTEL_BATCHPOOL_H */ diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c new file mode 100644 index 0000000000..c033f2a592 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -0,0 +1,304 @@ +/************************************************************************** + * + * 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 "i830_dri.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_swapbuffers.h" +#include "intel_winsys.h" +#include "intel_batchbuffer.h" + +#include "state_tracker/st_public.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" + +#include "utils.h" + + +#ifdef DEBUG +int __intel_debug = 0; +#endif + + +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_NV_vertex_program +#include "extension_helper.h" + + +/** + * Extension strings exported by the intel driver. + * + * \note + * It appears that ARB_texture_env_crossbar has "disappeared" compared to the + * old i830-specific driver. + */ +const struct dri_extension card_extensions[] = { + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, + {"GL_SGIS_generate_mipmap", NULL }, + {NULL, NULL} +}; + + + +#ifdef DEBUG +static const struct dri_debug_control debug_control[] = { + {"ioctl", DEBUG_IOCTL}, + {"bat", DEBUG_BATCH}, + {"lock", DEBUG_LOCK}, + {"swap", DEBUG_SWAP}, + {NULL, 0} +}; +#endif + + + +GLboolean +intelCreateContext(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + struct intel_context *intel = CALLOC_STRUCT(intel_context); + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + struct intel_screen *intelScreen = intel_screen(sPriv); + drmI830Sarea *saPriv = intelScreen->sarea; + int fthrottle_mode; + GLboolean havePools; + struct pipe_context *pipe; + struct st_context *st_share = NULL; + + if (sharedContextPrivate) { + st_share = ((struct intel_context *) sharedContextPrivate)->st; + } + + driContextPriv->driverPrivate = intel; + intel->intelScreen = intelScreen; + intel->driScreen = sPriv; + intel->sarea = saPriv; + + driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, "i915"); + + + /* + * memory pools + */ + DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + havePools = intelCreatePools(sPriv); + DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + if (!havePools) + return GL_FALSE; + + + /* Dri stuff */ + intel->hHWContext = driContextPriv->hHWContext; + intel->driFd = sPriv->fd; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + + fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); + intel->iw.irq_seq = -1; + intel->irqsEmitted = 0; + + intel->batch = intel_batchbuffer_alloc(intel); + intel->last_swap_fence = NULL; + intel->first_swap_fence = NULL; + +#ifdef DEBUG + __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); +#endif + + /* + * Pipe-related setup + */ + if (!getenv("INTEL_HW")) { + pipe = intel_create_softpipe( intel, intelScreen->winsys ); + } + else { + switch (intel->intelScreen->deviceID) { + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + case PCI_CHIP_I945_GME: + case PCI_CHIP_G33_G: + case PCI_CHIP_Q33_G: + case PCI_CHIP_Q35_G: + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + pipe = intel_create_i915simple( intel, intelScreen->winsys ); + break; + default: + fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", + intel->intelScreen->deviceID, __FUNCTION__); + + pipe = intel_create_softpipe( intel, intelScreen->winsys ); + break; + } + } + + pipe->priv = intel; + + intel->st = st_create_context(pipe, visual, st_share); + + return GL_TRUE; +} + + +void +intelDestroyContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = intel_context(driContextPriv); + + assert(intel); /* should never be null */ + if (intel) { + st_flush(intel->st, PIPE_FLUSH_WAIT); + + intel_batchbuffer_free(intel->batch); + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + if (intel->first_swap_fence) { + driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(intel->first_swap_fence); + intel->first_swap_fence = NULL; + } + + if (intel->intelScreen->dummyContext == intel) + intel->intelScreen->dummyContext = NULL; + + st_destroy_context(intel->st); + free(intel); + } +} + + +GLboolean +intelUnbindContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = intel_context(driContextPriv); + st_flush(intel->st, 0x0); + /* XXX make_current(NULL)? */ + return GL_TRUE; +} + + +GLboolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) +{ + if (driContextPriv) { + struct intel_context *intel = intel_context(driContextPriv); + struct intel_framebuffer *draw_fb = intel_framebuffer(driDrawPriv); + struct intel_framebuffer *read_fb = intel_framebuffer(driReadPriv); + + assert(draw_fb->stfb); + assert(read_fb->stfb); + + /* This is for situations in which we need a rendering context but + * there may not be any currently bound. + */ + intel->intelScreen->dummyContext = intel; + + st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); + + if ((intel->driDrawable != driDrawPriv) || + (intel->lastStamp != driDrawPriv->lastStamp)) { + intel->driDrawable = driDrawPriv; + intelUpdateWindowSize(driDrawPriv); + intel->lastStamp = driDrawPriv->lastStamp; + } + + /* The size of the draw buffer will have been updated above. + * If the readbuffer is a different window, check/update its size now. + */ + if (driReadPriv != driDrawPriv) { + intelUpdateWindowSize(driReadPriv); + } + + } + else { + st_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h new file mode 100644 index 0000000000..b01370c049 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -0,0 +1,158 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef INTEL_CONTEXT_H +#define INTEL_CONTEXT_H + + +#include "drm.h" +#include "intel_screen.h" +#include "i915_drm.h" + + +struct pipe_context; +struct intel_context; +struct _DriBufferObject; +struct st_context; + + +#define INTEL_MAX_FIXUP 64 + +/** + * Intel rendering context, contains a state tracker and intel-specific info. + */ +struct intel_context +{ + struct st_context *st; + + struct _DriFenceObject *last_swap_fence; + struct _DriFenceObject *first_swap_fence; + + struct intel_batchbuffer *batch; + + boolean locked; + char *prevLockFile; + int prevLockLine; + + uint irqsEmitted; + drm_i915_irq_wait_t iw; + + drm_context_t hHWContext; + drmLock *driHwLock; + int driFd; + + __DRIdrawablePrivate *driDrawable; + __DRIscreenPrivate *driScreen; + struct intel_screen *intelScreen; + drmI830Sarea *sarea; + + uint lastStamp; + + /** + * Configuration cache + */ + driOptionCache optionCache; +}; + + + +/** + * Intel framebuffer. + */ +struct intel_framebuffer +{ + struct st_framebuffer *stfb; + + /* other fields TBD */ + int other; +}; + + + + +/* These are functions now: + */ +void LOCK_HARDWARE( struct intel_context *intel ); +void UNLOCK_HARDWARE( struct intel_context *intel ); + +extern char *__progname; + + + +/* ================================================================ + * Debugging: + */ +#ifdef DEBUG +extern int __intel_debug; + +#define DEBUG_SWAP 0x1 +#define DEBUG_LOCK 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BATCH 0x8 + +#define DBG(flag, ...) do { \ + if (__intel_debug & (DEBUG_##flag)) \ + printf(__VA_ARGS__); \ +} while(0) + +#else +#define DBG(flag, ...) +#endif + + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_Q33_G 0x29D2 + + +/** Cast wrapper */ +static INLINE struct intel_context * +intel_context(__DRIcontextPrivate *driContextPriv) +{ + return (struct intel_context *) driContextPriv->driverPrivate; +} + + +/** Cast wrapper */ +static INLINE struct intel_framebuffer * +intel_framebuffer(__DRIdrawablePrivate * driDrawPriv) +{ + return (struct intel_framebuffer *) driDrawPriv->driverPrivate; +} + + +#endif diff --git a/src/gallium/winsys/dri/intel/intel_lock.c b/src/gallium/winsys/dri/intel/intel_lock.c new file mode 100644 index 0000000000..70aa7ea5f4 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_lock.c @@ -0,0 +1,102 @@ +/************************************************************************** + * + * 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 "main/glheader.h" +#include "glapi/glthread.h" +#include +#include "state_tracker/st_public.h" +#include "intel_context.h" +#include "i830_dri.h" + + + +_glthread_DECLARE_STATIC_MUTEX( lockMutex ); + + +static void +intelContendedLock(struct intel_context *intel, uint flags) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIscreenPrivate *sPriv = intel->driScreen; + struct intel_screen *intelScreen = intel_screen(sPriv); + drmI830Sarea *sarea = intel->sarea; + + drmGetLock(intel->driFd, intel->hHWContext, flags); + + DBG(LOCK, "%s - got contended lock\n", __progname); + + /* 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); + + if (sarea->width != intelScreen->front.width || + sarea->height != intelScreen->front.height) { + + intelUpdateScreenRotation(sPriv, sarea); + } +} + + +/* Lock the hardware and validate our state. + */ +void LOCK_HARDWARE( struct intel_context *intel ) +{ + char __ret = 0; + + _glthread_LOCK_MUTEX(lockMutex); + assert(!intel->locked); + + DRM_CAS(intel->driHwLock, intel->hHWContext, + (DRM_LOCK_HELD|intel->hHWContext), __ret); + + if (__ret) + intelContendedLock( intel, 0 ); + + DBG(LOCK, "%s - locked\n", __progname); + + intel->locked = 1; +} + + +/* Unlock the hardware using the global current context + */ +void UNLOCK_HARDWARE( struct intel_context *intel ) +{ + assert(intel->locked); + intel->locked = 0; + + DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); + + _glthread_UNLOCK_MUTEX(lockMutex); + + DBG(LOCK, "%s - unlocked\n", __progname); +} diff --git a/src/gallium/winsys/dri/intel/intel_reg.h b/src/gallium/winsys/dri/intel/intel_reg.h new file mode 100644 index 0000000000..f37c24fda9 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_reg.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + + +#ifndef _INTEL_REG_H_ +#define _INTEL_REG_H_ + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) + +#define MI_BATCH_BUFFER_END (0xA<<23) + + +#endif diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c new file mode 100644 index 0000000000..9e31c013a9 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -0,0 +1,537 @@ +/************************************************************************** + * + * 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 "utils.h" +#include "vblank.h" +#include "xmlpool.h" + +#include "intel_context.h" +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_batchpool.h" +#include "intel_swapbuffers.h" +#include "intel_winsys.h" + +#include "i830_dri.h" +#include "dri_bufpool.h" + +#include "pipe/p_context.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_cb_fbo.h" + + + +PUBLIC const char __driConfigOptions[] = + DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY + DRI_CONF_FORCE_S3TC_ENABLE(false) + DRI_CONF_ALLOW_LARGE_TEXTURES(1) + DRI_CONF_SECTION_END DRI_CONF_END; + +const uint __driNConfigOptions = 4; + +#ifdef USE_NEW_INTERFACE +static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; +#endif /*USE_NEW_INTERFACE */ + +extern const struct dri_extension card_extensions[]; + + + + +static void +intelPrintDRIInfo(struct intel_screen * intelScreen, + __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) +{ + fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->front.size, intelScreen->front.offset, + intelScreen->front.pitch); + fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); +} + + +#if 0 +static void +intelPrintSAREA(const drmI830Sarea * sarea) +{ + fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, + sarea->height); + fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); + fprintf(stderr, + "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->front_offset, sarea->front_size, + (unsigned) sarea->front_handle); + fprintf(stderr, + "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->back_offset, sarea->back_size, + (unsigned) sarea->back_handle); + fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->depth_offset, sarea->depth_size, + (unsigned) sarea->depth_handle); + fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); + fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); + fprintf(stderr, + "SAREA: rotated offset: 0x%08x size: 0x%x\n", + sarea->rotated_offset, sarea->rotated_size); + fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); +} +#endif + + +/** + * Use the information in the sarea to update the screen parameters + * related to screen rotation. Needs to be called locked. + */ +void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) +{ + struct intel_screen *intelScreen = intel_screen(sPriv); + + if (intelScreen->front.map) { + drmUnmap(intelScreen->front.map, intelScreen->front.size); + intelScreen->front.map = NULL; + } + + if (intelScreen->front.buffer) + driDeleteBuffers(1, &intelScreen->front.buffer); + + intelScreen->front.width = sarea->width; + intelScreen->front.height = sarea->height; + intelScreen->front.offset = sarea->front_offset; + intelScreen->front.pitch = sarea->pitch * intelScreen->front.cpp; + intelScreen->front.size = sarea->front_size; + intelScreen->front.handle = sarea->front_handle; + + assert( sarea->front_size >= + intelScreen->front.pitch * intelScreen->front.height ); + + if (!sarea->front_handle) + return; + + if (drmMap(sPriv->fd, + sarea->front_handle, + intelScreen->front.size, + (drmAddress *) & intelScreen->front.map) != 0) { + fprintf(stderr, "drmMap(frontbuffer) failed!\n"); + return; + } + + if (intelScreen->staticPool) { + driGenBuffers(intelScreen->staticPool, "static region", 1, + &intelScreen->front.buffer, 64, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + + driBOSetStatic(intelScreen->front.buffer, + intelScreen->front.offset, + intelScreen->front.pitch * intelScreen->front.height, + intelScreen->front.map, 0); + } +} + + +boolean +intelCreatePools(__DRIscreenPrivate * sPriv) +{ + unsigned batchPoolSize = 1024*1024; + struct intel_screen *intelScreen = intel_screen(sPriv); + + if (intelScreen->havePools) + return GL_TRUE; + + intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); + if (!intelScreen->staticPool) + return GL_FALSE; + + batchPoolSize /= BATCH_SZ; + intelScreen->batchPool = driBatchPoolInit(sPriv->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_LOCAL, + BATCH_SZ, + batchPoolSize, 5); + if (!intelScreen->batchPool) { + fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); + return GL_FALSE; + } + + intelScreen->havePools = GL_TRUE; + + intelUpdateScreenRotation(sPriv, intelScreen->sarea); + + return GL_TRUE; +} + + +static boolean +intelInitDriver(__DRIscreenPrivate * sPriv) +{ + struct intel_screen *intelScreen; + I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; + + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> + getProcAddress("glxEnableExtension")); + void *const psc = sPriv->psc->screenConfigs; + + if (sPriv->devPrivSize != sizeof(I830DRIRec)) { + fprintf(stderr, + "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); + return GL_FALSE; + } + + /* Allocate the private area */ + intelScreen = CALLOC_STRUCT(intel_screen); + if (!intelScreen) + return GL_FALSE; + + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); + + sPriv->private = (void *) intelScreen; + + intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + + gDRIPriv->sarea_priv_offset); + intelScreen->deviceID = gDRIPriv->deviceID; + intelScreen->front.cpp = gDRIPriv->cpp; + intelScreen->drmMinor = sPriv->drmMinor; + + assert(gDRIPriv->bitsPerPixel == 16 || + gDRIPriv->bitsPerPixel == 32); + + intelUpdateScreenRotation(sPriv, intelScreen->sarea); + + if (0) + intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); + + if (glx_enable_extension != NULL) { + (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); + (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); + (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); + } + + intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd); + + return GL_TRUE; +} + + +static void +intelDestroyScreen(__DRIscreenPrivate * sPriv) +{ + struct intel_screen *intelScreen = intel_screen(sPriv); + + /* intelUnmapScreenRegions(intelScreen); */ + + if (intelScreen->havePools) { + driPoolTakeDown(intelScreen->staticPool); + driPoolTakeDown(intelScreen->batchPool); + } + FREE(intelScreen); + sPriv->private = NULL; +} + + +/** + * This is called when we need to set up GL rendering to a new X window. + */ +static boolean +intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, + __DRIdrawablePrivate * driDrawPriv, + const __GLcontextModes * visual, boolean isPixmap) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + + if (!intelfb) + return GL_FALSE; + + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + driDrawPriv->w, + driDrawPriv->h, + (void*) intelfb); + if (!intelfb->stfb) { + free(intelfb); + return GL_FALSE; + } + + driDrawPriv->driverPrivate = (void *) intelfb; + return GL_TRUE; + } +} + +static void +intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) +{ + struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv); + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); +} + + +/** + * Get information about previous buffer swaps. + */ +static int +intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) +{ + if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) + || (sInfo == NULL)) { + return -1; + } + + return 0; +} + + +static void +intelSetTexOffset(__DRIcontext *pDRICtx, int texname, + unsigned long long offset, int depth, uint pitch) +{ + abort(); +#if 0 + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct st_texture_object *stObj = st_texture_object(tObj); + + if (!stObj) + return; + + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); + + stObj->imageOverride = GL_TRUE; + stObj->depthOverride = depth; + stObj->pitchOverride = pitch; + + if (offset) + stObj->textureOffset = offset; +#endif +} + + +static const struct __DriverAPIRec intelAPI = { + .InitDriver = intelInitDriver, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = intelCopySubBuffer, + .setTexOffset = intelSetTexOffset, +}; + + +static __GLcontextModes * +intelFillInModes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, boolean have_back_buffer) +{ + __GLcontextModes *modes; + __GLcontextModes *m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + u_int8_t depth_bits_array[3]; + u_int8_t stencil_bits_array[3]; + + + 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; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + 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; + } + + modes = + (*dri_interface->createContextModes) (num_modes, + sizeof(__GLcontextModes)); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_DIRECT_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for (m = modes; m != NULL; m = m->next) { + if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, + __DRIscreen * psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 7, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 7, 0 }; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("i915", + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &intelAPI); + + if (psp != NULL) { + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + *driver_modes = intelFillInModes(dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create + * is called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + } + + return (void *) psp; +} + diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h new file mode 100644 index 0000000000..3396f9e564 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -0,0 +1,113 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef _INTEL_SCREEN_H_ +#define _INTEL_SCREEN_H_ + +#include "dri_util.h" +#include "i830_common.h" +#include "xmlconfig.h" +#include "dri_bufpool.h" + +#include "pipe/p_compiler.h" + + +struct intel_screen +{ + struct { + drm_handle_t handle; + + /* We create a static dri buffer for the frontbuffer. + */ + struct _DriBufferObject *buffer; + + char *map; /* memory map */ + int offset; /* from start of video mem, in bytes */ + int pitch; /* row stride, in bytes */ + int width; + int height; + int size; + int cpp; /* for front and back buffers */ + } front; + + int deviceID; + int drmMinor; + + drmI830Sarea *sarea; + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; + + struct _DriBufferPool *batchPool; + struct _DriBufferPool *staticPool; /** for the X screen/framebuffer */ + boolean havePools; + + /** + * Temporary(?) context to use for SwapBuffers or other situations in + * which we need a rendering context, but none is currently bound. + */ + struct intel_context *dummyContext; + + struct pipe_winsys *winsys; +}; + + + +/** cast wrapper */ +static INLINE struct intel_screen * +intel_screen(__DRIscreenPrivate *sPriv) +{ + return (struct intel_screen *) sPriv->private; +} + + +extern void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); + + +extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); + +extern boolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); + +extern boolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + + +extern boolean +intelCreatePools(__DRIscreenPrivate *sPriv); + +extern boolean +intelCreateContext(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + + +#endif diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c new file mode 100644 index 0000000000..56b86d6a63 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -0,0 +1,253 @@ +/************************************************************************** + * + * 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 "intel_screen.h" +#include "intel_context.h" +#include "intel_swapbuffers.h" +#include "intel_batchbuffer.h" +#include "intel_reg.h" +#include "intel_winsys.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" + + +/** + * Display a colorbuffer surface in an X window. + * Used for SwapBuffers and flushing front buffer rendering. + * + * \param dPriv the window/drawable to display into + * \param surf the surface to display + * \param rect optional subrect of surface to display (may be NULL). + */ +void +intelDisplaySurface(__DRIdrawablePrivate *dPriv, + struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + struct intel_context *intel = intelScreen->dummyContext; + + DBG(SWAP, "%s\n", __FUNCTION__); + + if (!intel) { + /* XXX this is where some kind of extra/meta context could be useful */ + return; + } + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); + driFenceUnReference(intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + /* if this drawable isn't currently bound the LOCK_HARDWARE done on the + * current context (which is what intelScreenContext should return) might + * not get a contended lock and thus cliprects not updated (tests/manywin) + */ + if (intel_context(dPriv->driContextPriv) != intel) + DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); + + + if (dPriv && dPriv->numClipRects) { + const int srcWidth = surf->width; + const int srcHeight = surf->height; + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; + const int cpp = intelScreen->front.cpp; + const int srcpitch = surf->pitch; + int BR13, CMD; + int i; + + ASSERT(surf->buffer); + ASSERT(surf->cpp == cpp); + + DBG(SWAP, "screen pitch %d src surface pitch %d\n", + pitch, surf->pitch); + + if (cpp == 2) { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + } + else { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + } + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + drm_clip_rect_t sbox; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->front.width || + pbox->y2 > intelScreen->front.height) { + /* invalid cliprect, skip it */ + continue; + } + + box = *pbox; + + if (rect) { + /* intersect cliprect with user-provided src rect */ + drm_clip_rect_t rrect; + + rrect.x1 = dPriv->x + rect->x1; + rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; + rrect.x2 = rect->x2 + rrect.x1; + rrect.y2 = rect->y2 + rrect.y1; + if (rrect.x1 > box.x1) + box.x1 = rrect.x1; + if (rrect.y1 > box.y1) + box.y1 = rrect.y1; + if (rrect.x2 < box.x2) + box.x2 = rrect.x2; + if (rrect.y2 < box.y2) + box.y2 = rrect.y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + /* restrict blit to size of actually rendered area */ + if (box.x2 - box.x1 > srcWidth) + box.x2 = srcWidth + box.x1; + if (box.y2 - box.y1 > srcHeight) + box.y2 = srcHeight + box.y1; + + DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", + box.x1, box.x2, box.y1, box.y2); + + sbox.x1 = box.x1 - dPriv->x; + sbox.y1 = box.y1 - dPriv->y; + + assert(box.x1 < box.x2); + assert(box.y1 < box.y2); + + /* XXX this could be done with pipe->surface_copy() */ + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((box.y1 << 16) | box.x1); + OUT_BATCH((box.y2 << 16) | box.x2); + + OUT_RELOC(intelScreen->front.buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + OUT_BATCH((sbox.y1 << 16) | sbox.x1); + OUT_BATCH((srcpitch * cpp) & 0xffff); + OUT_RELOC(dri_bo(surf->buffer), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + ADVANCE_BATCH(); + } + + if (intel->first_swap_fence) + driFenceUnReference(intel->first_swap_fence); + intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); + driFenceReference(intel->first_swap_fence); + } + + UNLOCK_HARDWARE(intel); + + if (intel->lastStamp != dPriv->lastStamp) { + intelUpdateWindowSize(dPriv); + intel->lastStamp = dPriv->lastStamp; + } +} + + + +/** + * This will be called whenever the currently bound window is moved/resized. + */ +void +intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) +{ + struct intel_framebuffer *intelfb = intel_framebuffer(dPriv); + assert(intelfb->stfb); + st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); +} + + + +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + st_notify_swapbuffers(intel_fb->stfb); + intelDisplaySurface(dPriv, back_surf, NULL); + st_notify_swapbuffers_complete(intel_fb->stfb); + } +} + + +/** + * Called via glXCopySubBufferMESA() to copy a subrect of the back + * buffer to the front buffer/screen. + */ +void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ + struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + drm_clip_rect_t rect; + rect.x1 = x; + rect.y1 = y; + rect.x2 = w; + rect.y2 = h; + + st_notify_swapbuffers(intel_fb->stfb); + intelDisplaySurface(dPriv, back_surf, &rect); + } +} diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.h b/src/gallium/winsys/dri/intel/intel_swapbuffers.h new file mode 100644 index 0000000000..7ae5fd15a5 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2006 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. + * + **************************************************************************/ + +#ifndef INTEL_SWAPBUFFERS_H +#define INTEL_SWAPBUFFERS_H + + +struct pipe_surface; + + +extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, + struct pipe_surface *surf, + const drm_clip_rect_t * rect); + +extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, + int x, int y, int w, int h); + +extern void intelUpdateWindowSize(__DRIdrawablePrivate *dPriv); + + +#endif /* INTEL_SWAPBUFFERS_H */ diff --git a/src/gallium/winsys/dri/intel/intel_winsys.h b/src/gallium/winsys/dri/intel/intel_winsys.h new file mode 100644 index 0000000000..ffc40782be --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_winsys.h @@ -0,0 +1,73 @@ +/************************************************************************** + * + * Copyright 2006 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. + * + **************************************************************************/ + +#ifndef INTEL_WINSYS_H +#define INTEL_WINSYS_H + +#include "pipe/p_state.h" + +struct intel_context; +struct pipe_context; +struct pipe_winsys; +struct pipe_buffer; +struct _DriBufferObject; + +struct pipe_winsys * +intel_create_pipe_winsys( int fd ); + +void +intel_destroy_pipe_winsys( struct pipe_winsys *winsys ); + +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ); + +struct pipe_context * +intel_create_i915simple( struct intel_context *intel, + struct pipe_winsys *winsys ); + + +struct intel_buffer { + struct pipe_buffer base; + struct _DriBufferObject *driBO; +}; + +static INLINE struct intel_buffer * +intel_buffer( struct pipe_buffer *buf ) +{ + return (struct intel_buffer *)buf; +} + +static INLINE struct _DriBufferObject * +dri_bo( struct pipe_buffer *buf ) +{ + return intel_buffer(buf)->driBO; +} + + + +#endif diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c new file mode 100644 index 0000000000..1ba6a9e1b2 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -0,0 +1,154 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include +#include +#include "dri_bufpool.h" +#include "dri_bufmgr.h" + +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_winsys.h" + +#include "pipe/p_util.h" +#include "pipe/i915simple/i915_winsys.h" + + +struct intel_i915_winsys { + struct i915_winsys winsys; /**< batch buffer funcs */ + struct intel_context *intel; +}; + + +/* Turn a i915simple winsys into an intel/i915simple winsys: + */ +static inline struct intel_i915_winsys * +intel_i915_winsys( struct i915_winsys *sws ) +{ + return (struct intel_i915_winsys *)sws; +} + + +/* Simple batchbuffer interface: + */ + +static unsigned *intel_i915_batch_start( struct i915_winsys *sws, + unsigned dwords, + unsigned relocs ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + + /* XXX: check relocs. + */ + if (intel_batchbuffer_space( intel->batch ) >= dwords * 4) { + /* XXX: Hmm, the driver can't really do much with this pointer: + */ + return (unsigned *)intel->batch->ptr; + } + else + return NULL; +} + +static void intel_i915_batch_dword( struct i915_winsys *sws, + unsigned dword ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + intel_batchbuffer_emit_dword( intel->batch, dword ); +} + +static void intel_i915_batch_reloc( struct i915_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + unsigned flags = DRM_BO_FLAG_MEM_TT; + unsigned mask = DRM_BO_MASK_MEM; + + if (access_flags & I915_BUFFER_ACCESS_WRITE) { + flags |= DRM_BO_FLAG_WRITE; + mask |= DRM_BO_FLAG_WRITE; + } + + if (access_flags & I915_BUFFER_ACCESS_READ) { + flags |= DRM_BO_FLAG_READ; + mask |= DRM_BO_FLAG_READ; + } + + intel_batchbuffer_emit_reloc( intel->batch, + dri_bo( buf ), + flags, mask, + delta ); +} + + + +static void intel_i915_batch_flush( struct i915_winsys *sws ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + + intel_batchbuffer_flush( intel->batch ); +// if (0) intel_i915_batch_wait_idle( sws ); +} + + +static void intel_i915_batch_finish( struct i915_winsys *sws ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + intel_batchbuffer_finish( intel->batch ); +} + + +/** + * Create i915 hardware rendering context. + */ +struct pipe_context * +intel_create_i915simple( struct intel_context *intel, + struct pipe_winsys *winsys ) +{ + struct intel_i915_winsys *iws = CALLOC_STRUCT( intel_i915_winsys ); + + /* Fill in this struct with callbacks that i915simple will need to + * communicate with the window system, buffer manager, etc. + */ + iws->winsys.batch_start = intel_i915_batch_start; + iws->winsys.batch_dword = intel_i915_batch_dword; + iws->winsys.batch_reloc = intel_i915_batch_reloc; + iws->winsys.batch_flush = intel_i915_batch_flush; + iws->winsys.batch_finish = intel_i915_batch_finish; + iws->intel = intel; + + /* Create the i915simple context: + */ + return i915_create( winsys, + &iws->winsys, + intel->intelScreen->deviceID ); +} diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c new file mode 100644 index 0000000000..789a386500 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -0,0 +1,302 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include +#include +#include "dri_bufpool.h" +#include "dri_bufmgr.h" + +#include "intel_context.h" +#include "intel_winsys.h" +#include "intel_swapbuffers.h" +#include "intel_batchbuffer.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + + + +struct intel_pipe_winsys { + struct pipe_winsys winsys; + struct _DriBufferPool *regionPool; +}; + + + +/* Turn a pipe winsys into an intel/pipe winsys: + */ +static inline struct intel_pipe_winsys * +intel_pipe_winsys( struct pipe_winsys *winsys ) +{ + return (struct intel_pipe_winsys *)winsys; +} + + +/* Most callbacks map direcly onto dri_bufmgr operations: + */ +static void *intel_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags ) +{ + unsigned drm_flags = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + drm_flags |= DRM_BO_FLAG_WRITE; + + if (flags & PIPE_BUFFER_USAGE_CPU_READ) + drm_flags |= DRM_BO_FLAG_READ; + + return driBOMap( dri_bo(buf), drm_flags, 0 ); +} + +static void intel_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnmap( dri_bo(buf) ); +} + + +static void +intel_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnReference( dri_bo(buf) ); +} + + +/* Pipe has no concept of pools. We choose the tex/region pool + * for all buffers. + * Grabs the hardware lock! + */ +static struct pipe_buffer * +intel_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size ) +{ + struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); + struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); + unsigned flags = 0; + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + if (usage & (PIPE_BUFFER_USAGE_VERTEX /*| IWS_BUFFER_USAGE_LOCAL*/)) { + flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; + } else { + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + } + + if (usage & PIPE_BUFFER_USAGE_GPU_READ) + flags |= DRM_BO_FLAG_READ; + + if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) + flags |= DRM_BO_FLAG_WRITE; + + /* drm complains if we don't set any read/write flags. + */ + if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) + flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + +#if 0 + if (flags & IWS_BUFFER_USAGE_EXE) + flags |= DRM_BO_FLAG_EXE; + + if (usage & IWS_BUFFER_USAGE_CACHED) + flags |= DRM_BO_FLAG_CACHED; +#endif + + driGenBuffers( iws->regionPool, + "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); + + driBOData( buffer->driBO, size, NULL, 0 ); + + return &buffer->base; +} + + +static struct pipe_buffer * +intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) +{ + struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); + struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); + + driGenUserBuffer( iws->regionPool, + "pipe user buffer", &buffer->driBO, ptr, bytes); + + return &buffer->base; +} + + +/* The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +intel_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + intelDisplaySurface(dPriv, surf, NULL); +} + + +static struct pipe_surface * +intel_i915_surface_alloc(struct pipe_winsys *winsys) +{ + struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); + if (surf) { + surf->refcount = 1; + surf->winsys = winsys; + } + return surf; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +/** + * Copied from xm_winsys.c + */ +static int +intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags) +{ + const unsigned alignment = 64; + int ret; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if(!surf->buffer) + return -1; + + return 0; +} + + +static void +intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + + +static void +intel_printf( struct pipe_winsys *winsys, const char *fmtString, ... ) +{ + va_list args; + va_start( args, fmtString ); + vfprintf(stderr, fmtString, args); + va_end( args ); +} + +static const char * +intel_get_name( struct pipe_winsys *winsys ) +{ + return "Intel/DRI/ttm"; +} + + +struct pipe_winsys * +intel_create_pipe_winsys( int fd ) +{ + struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys ); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + * + * Pipe would be happy with a malloc based memory manager, but + * the SwapBuffers implementation in this winsys driver requires + * that rendering be done to an appropriate _DriBufferObject. + */ + iws->winsys.buffer_create = intel_buffer_create; + iws->winsys.user_buffer_create = intel_user_buffer_create; + iws->winsys.buffer_map = intel_buffer_map; + iws->winsys.buffer_unmap = intel_buffer_unmap; + iws->winsys.buffer_destroy = intel_buffer_destroy; + iws->winsys.flush_frontbuffer = intel_flush_frontbuffer; + iws->winsys.printf = intel_printf; + iws->winsys.get_name = intel_get_name; + iws->winsys.surface_alloc = intel_i915_surface_alloc; + iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; + iws->winsys.surface_release = intel_i915_surface_release; + + if (fd) + iws->regionPool = driDRMPoolInit(fd); + + return &iws->winsys; +} + + +void +intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) +{ + struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); + if (iws->regionPool) { + driPoolTakeDown(iws->regionPool); + } + free(iws); +} + diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c new file mode 100644 index 0000000000..cec3437831 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c @@ -0,0 +1,81 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include "intel_context.h" +#include "intel_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_format.h" +#include "pipe/softpipe/sp_winsys.h" + + +struct intel_softpipe_winsys { + struct softpipe_winsys sws; + struct intel_context *intel; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean +intel_is_format_supported(struct softpipe_winsys *sws, + enum pipe_format format) +{ + switch(format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: + return TRUE; + default: + return FALSE; + } +} + + +/** + * Create rendering context which uses software rendering. + */ +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ) +{ + struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); + + /* Fill in this struct with callbacks that softpipe will need to + * communicate with the window system, buffer manager, etc. + */ + isws->sws.is_format_supported = intel_is_format_supported; + isws->intel = intel; + + /* Create the softpipe context: + */ + return softpipe_create( winsys, &isws->sws ); +} diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h new file mode 100644 index 0000000000..d4d58886ce --- /dev/null +++ b/src/gallium/winsys/dri/intel/server/i830_common.h @@ -0,0 +1,226 @@ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. +Copyright 2002 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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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. + +**************************************************************************/ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ + +#ifndef _I830_COMMON_H_ +#define _I830_COMMON_H_ + + +#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ +#define I830_LOG_MIN_TEX_REGION_SIZE 14 + + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_I830_INIT 0x00 +#define DRM_I830_FLUSH 0x01 +#define DRM_I830_FLIP 0x02 +#define DRM_I830_BATCHBUFFER 0x03 +#define DRM_I830_IRQ_EMIT 0x04 +#define DRM_I830_IRQ_WAIT 0x05 +#define DRM_I830_GETPARAM 0x06 +#define DRM_I830_SETPARAM 0x07 +#define DRM_I830_ALLOC 0x08 +#define DRM_I830_FREE 0x09 +#define DRM_I830_INIT_HEAP 0x0a +#define DRM_I830_CMDBUFFER 0x0b +#define DRM_I830_DESTROY_HEAP 0x0c +#define DRM_I830_SET_VBLANK_PIPE 0x0d +#define DRM_I830_GET_VBLANK_PIPE 0x0e + +typedef struct { + enum { + I830_INIT_DMA = 0x01, + I830_CLEANUP_DMA = 0x02, + I830_RESUME_DMA = 0x03 + } func; + unsigned int mmio_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; + unsigned int back_pitch; + unsigned int depth_pitch; + unsigned int cpp; + unsigned int chipset; +} drmI830Init; + +typedef struct { + drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; + int last_upload; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int ctxOwner; /* last context to upload state */ + int texAge; + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + int perf_boxes; /* performance boxes to be displayed */ + int width, height; /* screen size in pixels */ + + drm_handle_t front_handle; + int front_offset; + int front_size; + + drm_handle_t back_handle; + int back_offset; + int back_size; + + drm_handle_t depth_handle; + int depth_offset; + int depth_size; + + drm_handle_t tex_handle; + int tex_offset; + int tex_size; + int log_tex_granularity; + int pitch; + int rotation; /* 0, 90, 180 or 270 */ + int rotated_offset; + int rotated_size; + int rotated_pitch; + int virtualX, virtualY; + + unsigned int front_tiled; + unsigned int back_tiled; + unsigned int depth_tiled; + unsigned int rotated_tiled; + unsigned int rotated2_tiled; + + int pipeA_x; + int pipeA_y; + int pipeA_w; + int pipeA_h; + int pipeB_x; + int pipeB_y; + int pipeB_w; + int pipeB_h; + + /* Triple buffering */ + drm_handle_t third_handle; + int third_offset; + int third_size; + unsigned int third_tiled; +} drmI830Sarea; + +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + + +typedef struct { + int start; /* agp offset */ + int used; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830BatchBuffer; + +typedef struct { + char *buf; /* agp offset */ + int sz; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830CmdBuffer; + +typedef struct { + int *irq_seq; +} drmI830IrqEmit; + +typedef struct { + int irq_seq; +} drmI830IrqWait; + +typedef struct { + int param; + int *value; +} drmI830GetParam; + +#define I830_PARAM_IRQ_ACTIVE 1 +#define I830_PARAM_ALLOW_BATCHBUFFER 2 + +typedef struct { + int param; + int value; +} drmI830SetParam; + +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 +#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 +#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 + + +/* A memory manager for regions of shared memory: + */ +#define I830_MEM_REGION_AGP 1 + +typedef struct { + int region; + int alignment; + int size; + int *region_offset; /* offset from start of fb or agp */ +} drmI830MemAlloc; + +typedef struct { + int region; + int region_offset; +} drmI830MemFree; + +typedef struct { + int region; + int size; + int start; +} drmI830MemInitHeap; + +typedef struct { + int region; +} drmI830MemDestroyHeap; + +#define DRM_I830_VBLANK_PIPE_A 1 +#define DRM_I830_VBLANK_PIPE_B 2 + +typedef struct { + int pipe; +} drmI830VBlankPipe; + +#endif /* _I830_DRM_H_ */ diff --git a/src/gallium/winsys/dri/intel/server/i830_dri.h b/src/gallium/winsys/dri/intel/server/i830_dri.h new file mode 100644 index 0000000000..c2a3af8cbf --- /dev/null +++ b/src/gallium/winsys/dri/intel/server/i830_dri.h @@ -0,0 +1,63 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ + +#ifndef _I830_DRI_H +#define _I830_DRI_H + +#include "xf86drm.h" +#include "i830_common.h" + +#define I830_MAX_DRAWABLES 256 + +#define I830_MAJOR_VERSION 1 +#define I830_MINOR_VERSION 7 +#define I830_PATCHLEVEL 2 + +#define I830_REG_SIZE 0x80000 + +typedef struct _I830DRIRec { + drm_handle_t regs; + drmSize regsSize; + + drmSize unused1; /* backbufferSize */ + drm_handle_t unused2; /* backbuffer */ + + drmSize unused3; /* depthbufferSize */ + drm_handle_t unused4; /* depthbuffer */ + + drmSize unused5; /* rotatedSize */ + drm_handle_t unused6; /* rotatedbuffer */ + + drm_handle_t unused7; /* textures */ + int unused8; /* textureSize */ + + drm_handle_t unused9; /* agp_buffers */ + drmSize unused10; /* agp_buf_size */ + + int deviceID; + int width; + int height; + int mem; + int cpp; + int bitsPerPixel; + + int unused11[8]; /* was front/back/depth/rotated offset/pitch */ + + int unused12; /* logTextureGranularity */ + int unused13; /* textureOffset */ + + int irq; + int sarea_priv_offset; +} I830DRIRec, *I830DRIPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830ConfigPrivRec, *I830ConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830DRIContextRec, *I830DRIContextPtr; + + +#endif diff --git a/src/gallium/winsys/dri/intel/server/intel.h b/src/gallium/winsys/dri/intel/server/intel.h new file mode 100644 index 0000000000..6ea72499c1 --- /dev/null +++ b/src/gallium/winsys/dri/intel/server/intel.h @@ -0,0 +1,331 @@ +#ifndef _INTEL_H_ +#define _INTEL_H_ + +#include "xf86drm.h" /* drm_handle_t, etc */ + +/* Intel */ +#ifndef PCI_CHIP_I810 +#define PCI_CHIP_I810 0x7121 +#define PCI_CHIP_I810_DC100 0x7123 +#define PCI_CHIP_I810_E 0x7125 +#define PCI_CHIP_I815 0x1132 +#define PCI_CHIP_I810_BRIDGE 0x7120 +#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 +#define PCI_CHIP_I810_E_BRIDGE 0x7124 +#define PCI_CHIP_I815_BRIDGE 0x1130 +#endif + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 + +#ifndef PCI_CHIP_I855_GM +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I855_GM_BRIDGE 0x3580 +#endif + +#ifndef PCI_CHIP_I865_G +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I865_G_BRIDGE 0x2570 +#endif + +#ifndef PCI_CHIP_I915_G +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_G_BRIDGE 0x2580 +#endif + +#ifndef PCI_CHIP_I915_GM +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I915_GM_BRIDGE 0x2590 +#endif + +#ifndef PCI_CHIP_E7221_G +#define PCI_CHIP_E7221_G 0x258A +/* Same as I915_G_BRIDGE */ +#define PCI_CHIP_E7221_G_BRIDGE 0x2580 +#endif + +#ifndef PCI_CHIP_I945_G +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_G_BRIDGE 0x2770 +#endif + +#ifndef PCI_CHIP_I945_GM +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 +#endif + +#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \ + pI810->Chipset == PCI_CHIP_I810_DC100 || \ + pI810->Chipset == PCI_CHIP_I810_E) +#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815) +#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M) +#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G) +#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM) +#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) +#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) +#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G) + +#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G) +#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM) +#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G) +#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM) +#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) + +#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) + +#define I830_GMCH_CTRL 0x52 + +#define I830_GMCH_MEM_MASK 0x1 +#define I830_GMCH_MEM_64M 0x1 +#define I830_GMCH_MEM_128M 0 + +#define I830_GMCH_GMS_MASK 0x70 +#define I830_GMCH_GMS_DISABLED 0x00 +#define I830_GMCH_GMS_LOCAL 0x10 +#define I830_GMCH_GMS_STOLEN_512 0x20 +#define I830_GMCH_GMS_STOLEN_1024 0x30 +#define I830_GMCH_GMS_STOLEN_8192 0x40 + +#define I855_GMCH_GMS_MASK (0x7 << 4) +#define I855_GMCH_GMS_DISABLED 0x00 +#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) +#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) +#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) +#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) +#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) +#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) +#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) + +typedef unsigned char Bool; +#define TRUE 1 +#define FALSE 0 + +#define PIPE_NONE 0<<0 +#define PIPE_CRT 1<<0 +#define PIPE_TV 1<<1 +#define PIPE_DFP 1<<2 +#define PIPE_LFP 1<<3 +#define PIPE_CRT2 1<<4 +#define PIPE_TV2 1<<5 +#define PIPE_DFP2 1<<6 +#define PIPE_LFP2 1<<7 + +typedef struct _I830MemPool *I830MemPoolPtr; +typedef struct _I830MemRange *I830MemRangePtr; +typedef struct _I830MemRange { + long Start; + long End; + long Size; + unsigned long Physical; + unsigned long Offset; /* Offset of AGP-allocated portion */ + unsigned long Alignment; + drm_handle_t Key; + unsigned long Pitch; // add pitch + I830MemPoolPtr Pool; +} I830MemRange; + +typedef struct _I830MemPool { + I830MemRange Total; + I830MemRange Free; + I830MemRange Fixed; + I830MemRange Allocated; +} I830MemPool; + +typedef struct { + int tail_mask; + I830MemRange mem; + unsigned char *virtual_start; + int head; + int tail; + int space; +} I830RingBuffer; + +typedef struct _I830Rec { + unsigned char *MMIOBase; + unsigned char *FbBase; + int cpp; + uint32_t aper_size; + unsigned int bios_version; + + /* These are set in PreInit and never changed. */ + long FbMapSize; + long TotalVideoRam; + I830MemRange StolenMemory; /* pre-allocated memory */ + long BIOSMemorySize; /* min stolen pool size */ + int BIOSMemSizeLoc; + + /* These change according to what has been allocated. */ + long FreeMemory; + I830MemRange MemoryAperture; + I830MemPool StolenPool; + long allocatedMemory; + + /* Regions allocated either from the above pools, or from agpgart. */ + /* for single and dual head configurations */ + I830MemRange FrontBuffer; + I830MemRange FrontBuffer2; + I830MemRange Scratch; + I830MemRange Scratch2; + + I830RingBuffer *LpRing; + + I830MemRange BackBuffer; + I830MemRange DepthBuffer; + I830MemRange TexMem; + int TexGranularity; + I830MemRange ContextMem; + int drmMinor; + Bool have3DWindows; + + Bool NeedRingBufferLow; + Bool allowPageFlip; + Bool disableTiling; + + int Chipset; + unsigned long LinearAddr; + unsigned long MMIOAddr; + + drmSize registerSize; /**< \brief MMIO register map size */ + drm_handle_t registerHandle; /**< \brief MMIO register map handle */ + // IOADDRESS ioBase; + int irq; /**< \brief IRQ number */ + int GttBound; + + drm_handle_t ring_map; + unsigned int Fence[8]; + +} I830Rec; + +/* + * 12288 is set as the maximum, chosen because it is enough for + * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. + */ +#define I830_MAXIMUM_VBIOS_MEM 12288 +#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024) +#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024) + +/* Flags for memory allocation function */ +#define FROM_ANYWHERE 0x00000000 +#define FROM_POOL_ONLY 0x00000001 +#define FROM_NEW_ONLY 0x00000002 +#define FROM_MASK 0x0000000f + +#define ALLOCATE_AT_TOP 0x00000010 +#define ALLOCATE_AT_BOTTOM 0x00000020 +#define FORCE_GAPS 0x00000040 + +#define NEED_PHYSICAL_ADDR 0x00000100 +#define ALIGN_BOTH_ENDS 0x00000200 +#define FORCE_LOW 0x00000400 + +#define ALLOC_NO_TILING 0x00001000 +#define ALLOC_INITIAL 0x00002000 + +#define ALLOCATE_DRY_RUN 0x80000000 + +/* Chipset registers for VIDEO BIOS memory RW access */ +#define _855_DRAM_RW_CONTROL 0x58 +#define _845_DRAM_RW_CONTROL 0x90 +#define DRAM_WRITE 0x33330000 + +#define KB(x) ((x) * 1024) +#define MB(x) ((x) * KB(1024)) + +#define GTT_PAGE_SIZE KB(4) +#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) +#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) +#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) +#define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) +#define PRIMARY_RINGBUFFER_SIZE KB(128) + + +/* Ring buffer registers, p277, overview p19 + */ +#define LP_RING 0x2030 +#define HP_RING 0x2040 + +#define RING_TAIL 0x00 +#define TAIL_ADDR 0x000FFFF8 +#define I830_TAIL_MASK 0x001FFFF8 + +#define RING_HEAD 0x04 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define I830_HEAD_MASK 0x001FFFFC + +#define RING_START 0x08 +#define START_ADDR 0x03FFFFF8 +#define I830_RING_START_MASK 0xFFFFF000 + +#define RING_LEN 0x0C +#define RING_NR_PAGES 0x001FF000 +#define I830_RING_NR_PAGES 0x001FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 + + +/* Fence/Tiling ranges [0..7] + */ +#define FENCE 0x2000 +#define FENCE_NR 8 + +#define I915G_FENCE_START_MASK 0x0ff00000 + +#define I830_FENCE_START_MASK 0x07f80000 + +#define FENCE_START_MASK 0x03F80000 +#define FENCE_X_MAJOR 0x00000000 +#define FENCE_Y_MAJOR 0x00001000 +#define FENCE_SIZE_MASK 0x00000700 +#define FENCE_SIZE_512K 0x00000000 +#define FENCE_SIZE_1M 0x00000100 +#define FENCE_SIZE_2M 0x00000200 +#define FENCE_SIZE_4M 0x00000300 +#define FENCE_SIZE_8M 0x00000400 +#define FENCE_SIZE_16M 0x00000500 +#define FENCE_SIZE_32M 0x00000600 +#define FENCE_SIZE_64M 0x00000700 +#define I915G_FENCE_SIZE_1M 0x00000000 +#define I915G_FENCE_SIZE_2M 0x00000100 +#define I915G_FENCE_SIZE_4M 0x00000200 +#define I915G_FENCE_SIZE_8M 0x00000300 +#define I915G_FENCE_SIZE_16M 0x00000400 +#define I915G_FENCE_SIZE_32M 0x00000500 +#define I915G_FENCE_SIZE_64M 0x00000600 +#define I915G_FENCE_SIZE_128M 0x00000700 +#define FENCE_PITCH_1 0x00000000 +#define FENCE_PITCH_2 0x00000010 +#define FENCE_PITCH_4 0x00000020 +#define FENCE_PITCH_8 0x00000030 +#define FENCE_PITCH_16 0x00000040 +#define FENCE_PITCH_32 0x00000050 +#define FENCE_PITCH_64 0x00000060 +#define FENCE_VALID 0x00000001 + +#include + +# define MMIO_IN8(base, offset) \ + *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) +# define MMIO_IN32(base, offset) \ + read_MMIO_LE32(base, offset) +# define MMIO_OUT8(base, offset, val) \ + *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) +# define MMIO_OUT32(base, offset, val) \ + *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val) + + + /* Memory mapped register access macros */ +#define INREG8(addr) MMIO_IN8(MMIO, addr) +#define INREG(addr) MMIO_IN32(MMIO, addr) +#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val) + +#define DSPABASE 0x70184 + +#endif diff --git a/src/gallium/winsys/dri/intel/server/intel_dri.c b/src/gallium/winsys/dri/intel/server/intel_dri.c new file mode 100644 index 0000000000..e49c4214ad --- /dev/null +++ b/src/gallium/winsys/dri/intel/server/intel_dri.c @@ -0,0 +1,1306 @@ +/** + * \file server/intel_dri.c + * \brief File to perform the device-specific initialization tasks typically + * done in the X server. + * + * Here they are converted to run in the client (or perhaps a standalone + * process), and to work with the frame buffer device rather than the X + * server infrastructure. + * + * Copyright (C) 2006 Dave Airlie (airlied@linux.ie) + + 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 THE COPYRIGHT HOLDERS AND/OR THEIR 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 +#include +#include +#include +#include + +#include "driver.h" +#include "drm.h" + +#include "intel.h" +#include "i830_dri.h" + +#include "memops.h" +#include "pciaccess.h" + +static size_t drm_page_size; +static int nextTile = 0; +#define xf86DrvMsg(...) do {} while(0) + +static const int pitches[] = { + 128 * 8, + 128 * 16, + 128 * 32, + 128 * 64, + 0 +}; + +static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea); + +static unsigned long +GetBestTileAlignment(unsigned long size) +{ + unsigned long i; + + for (i = KB(512); i < size; i <<= 1) + ; + + if (i > MB(64)) + i = MB(64); + + return i; +} + +static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830) +{ + int i; + unsigned char *MMIO = ctx->MMIOAddress; + + for (i = 0; i < 8; i++) { + OUTREG(FENCE + i * 4, pI830->Fence[i]); + // if (I810_DEBUG & DEBUG_VERBOSE_VGA) + fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]); + } +} + +/* Tiled memory is good... really, really good... + * + * Need to make it less likely that we miss out on this - probably + * need to move the frontbuffer away from the 'guarenteed' alignment + * of the first memory segment, or perhaps allocate a discontigous + * framebuffer to get more alignment 'sweet spots'. + */ +static void +SetFence(const DRIDriverContext *ctx, I830Rec *pI830, + int nr, unsigned int start, unsigned int pitch, + unsigned int size) +{ + unsigned int val; + unsigned int fence_mask = 0; + unsigned int fence_pitch; + + if (nr < 0 || nr > 7) { + fprintf(stderr, + "SetFence: fence %d out of range\n",nr); + return; + } + + pI830->Fence[nr] = 0; + + if (IS_I9XX(pI830)) + fence_mask = ~I915G_FENCE_START_MASK; + else + fence_mask = ~I830_FENCE_START_MASK; + + if (start & fence_mask) { + fprintf(stderr, + "SetFence: %d: start (0x%08x) is not %s aligned\n", + nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); + return; + } + + if (start % size) { + fprintf(stderr, + "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", + nr, start, size / 1024); + return; + } + + if (pitch & 127) { + fprintf(stderr, + "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", + nr, pitch); + return; + } + + val = (start | FENCE_X_MAJOR | FENCE_VALID); + + if (IS_I9XX(pI830)) { + switch (size) { + case MB(1): + val |= I915G_FENCE_SIZE_1M; + break; + case MB(2): + val |= I915G_FENCE_SIZE_2M; + break; + case MB(4): + val |= I915G_FENCE_SIZE_4M; + break; + case MB(8): + val |= I915G_FENCE_SIZE_8M; + break; + case MB(16): + val |= I915G_FENCE_SIZE_16M; + break; + case MB(32): + val |= I915G_FENCE_SIZE_32M; + break; + case MB(64): + val |= I915G_FENCE_SIZE_64M; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); + return; + } + } else { + switch (size) { + case KB(512): + val |= FENCE_SIZE_512K; + break; + case MB(1): + val |= FENCE_SIZE_1M; + break; + case MB(2): + val |= FENCE_SIZE_2M; + break; + case MB(4): + val |= FENCE_SIZE_4M; + break; + case MB(8): + val |= FENCE_SIZE_8M; + break; + case MB(16): + val |= FENCE_SIZE_16M; + break; + case MB(32): + val |= FENCE_SIZE_32M; + break; + case MB(64): + val |= FENCE_SIZE_64M; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); + return; + } + } + + if (IS_I9XX(pI830)) + fence_pitch = pitch / 512; + else + fence_pitch = pitch / 128; + + switch (fence_pitch) { + case 1: + val |= FENCE_PITCH_1; + break; + case 2: + val |= FENCE_PITCH_2; + break; + case 4: + val |= FENCE_PITCH_4; + break; + case 8: + val |= FENCE_PITCH_8; + break; + case 16: + val |= FENCE_PITCH_16; + break; + case 32: + val |= FENCE_PITCH_32; + break; + case 64: + val |= FENCE_PITCH_64; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal pitch (%d)\n", nr, pitch); + return; + } + + pI830->Fence[nr] = val; +} + +static Bool +MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem) +{ + int pitch, ntiles, i; + + pitch = pMem->Pitch * ctx->cpp; + /* + * Simply try to break the region up into at most four pieces of size + * equal to the alignment. + */ + ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; + if (ntiles >= 4) { + return FALSE; + } + + for (i = 0; i < ntiles; i++, nextTile++) { + SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment, + pitch, pMem->Alignment); + } + return TRUE; +} + +static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830) +{ + int i; + + /* Clear out */ + for (i = 0; i < 8; i++) + pI830->Fence[i] = 0; + + nextTile = 0; + + if (pI830->BackBuffer.Alignment >= KB(512)) { + if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) { + fprintf(stderr, + "Activating tiled memory for the back buffer.\n"); + } else { + fprintf(stderr, + "MakeTiles failed for the back buffer.\n"); + pI830->allowPageFlip = FALSE; + } + } + + if (pI830->DepthBuffer.Alignment >= KB(512)) { + if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) { + fprintf(stderr, + "Activating tiled memory for the depth buffer.\n"); + } else { + fprintf(stderr, + "MakeTiles failed for the depth buffer.\n"); + } + } + + return; +} + +static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + struct pci_device host_bridge, ig_dev; + uint32_t gmch_ctrl; + int memsize = 0; + int range; + uint32_t aper_size; + uint32_t membase2 = 0; + + memset(&host_bridge, 0, sizeof(host_bridge)); + memset(&ig_dev, 0, sizeof(ig_dev)); + + ig_dev.dev = 2; + + pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL); + + if (IS_I830(pI830) || IS_845G(pI830)) { + if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { + aper_size = 0x80000000; + } else { + aper_size = 0x40000000; + } + } else { + if (IS_I9XX(pI830)) { + int ret; + ret = pci_device_cfg_read_u32(&ig_dev, &membase2, 0x18); + if (membase2 & 0x08000000) + aper_size = 0x8000000; + else + aper_size = 0x10000000; + + fprintf(stderr,"aper size is %08X %08x %d\n", aper_size, membase2, ret); + } else + aper_size = 0x8000000; + } + + pI830->aper_size = aper_size; + + + /* We need to reduce the stolen size, by the GTT and the popup. + * The GTT varying according the the FbMapSize and the popup is 4KB */ + range = (ctx->shared.fbSize / (1024*1024)) + 4; + + if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I855_GMCH_GMS_STOLEN_1M: + memsize = MB(1) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_4M: + memsize = MB(4) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_8M: + memsize = MB(8) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_16M: + memsize = MB(16) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_32M: + memsize = MB(32) - KB(range); + break; + case I915G_GMCH_GMS_STOLEN_48M: + if (IS_I9XX(pI830)) + memsize = MB(48) - KB(range); + break; + case I915G_GMCH_GMS_STOLEN_64M: + if (IS_I9XX(pI830)) + memsize = MB(64) - KB(range); + break; + } + } else { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I830_GMCH_GMS_STOLEN_512: + memsize = KB(512) - KB(range); + break; + case I830_GMCH_GMS_STOLEN_1024: + memsize = MB(1) - KB(range); + break; + case I830_GMCH_GMS_STOLEN_8192: + memsize = MB(8) - KB(range); + break; + case I830_GMCH_GMS_LOCAL: + memsize = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Local memory found, but won't be used.\n"); + break; + } + } + if (memsize > 0) { + fprintf(stderr, + "detected %d kB stolen memory.\n", memsize / 1024); + } else { + fprintf(stderr, + "no video memory detected.\n"); + } + return memsize; +} + +static int AgpInit(const DRIDriverContext *ctx, I830Rec *info) +{ + unsigned long mode = 0x4; + + if (drmAgpAcquire(ctx->drmFD) < 0) { + fprintf(stderr, "[gart] AGP not available\n"); + return 0; + } + + if (drmAgpEnable(ctx->drmFD, mode) < 0) { + fprintf(stderr, "[gart] AGP not enabled\n"); + drmAgpRelease(ctx->drmFD); + return 0; + } + else + fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); + + return 1; +} + +/* + * Allocate memory from the given pool. Grow the pool if needed and if + * possible. + */ +static unsigned long +AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830, + I830MemRange *result, I830MemPool *pool, + long size, unsigned long alignment, int flags) +{ + long needed, start, end; + + if (!result || !pool || !size) + return 0; + + /* Calculate how much space is needed. */ + if (alignment <= GTT_PAGE_SIZE) + needed = size; + else { + start = ROUND_TO(pool->Free.Start, alignment); + end = ROUND_TO(start + size, alignment); + needed = end - pool->Free.Start; + } + if (needed > pool->Free.Size) { + return 0; + } + + result->Start = ROUND_TO(pool->Free.Start, alignment); + pool->Free.Start += needed; + result->End = pool->Free.Start; + + pool->Free.Size = pool->Free.End - pool->Free.Start; + result->Size = result->End - result->Start; + result->Pool = pool; + result->Alignment = alignment; + return needed; +} + +static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result) +{ + unsigned long start, end; + unsigned long newApStart, newApEnd; + int ret; + if (!result || !size) + return 0; + + if (!alignment) + alignment = 4; + + start = ROUND_TO(pI830->MemoryAperture.Start, alignment); + end = ROUND_TO(start + size, alignment); + newApStart = end; + newApEnd = pI830->MemoryAperture.End; + + ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key)); + + if (ret) + { + fprintf(stderr,"drmAgpAlloc failed %d\n", ret); + return 0; + } + pI830->allocatedMemory += size; + pI830->MemoryAperture.Start = newApStart; + pI830->MemoryAperture.End = newApEnd; + pI830->MemoryAperture.Size = newApEnd - newApStart; + // pI830->FreeMemory -= size; + result->Start = start; + result->End = start + size; + result->Size = size; + result->Offset = start; + result->Alignment = alignment; + result->Pool = NULL; + + return size; +} + +unsigned long +I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, + I830MemRange *result, I830MemPool *pool, long size, + unsigned long alignment, int flags) +{ + unsigned long ret; + + if (!result) + return 0; + + /* Make sure these are initialised. */ + result->Size = 0; + result->Key = -1; + + if (!size) { + return 0; + } + + if (pool->Free.Size < size) { + ret = AllocFromAGP(ctx, pI830, size, alignment, result); + } + else { + ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags); + if (ret == 0) + ret = AllocFromAGP(ctx, pI830, size, alignment, result); + } + return ret; +} + +static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem) +{ + if (!mem) + return FALSE; + + if (mem->Key == -1) + return TRUE; + + return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset); +} + +/* simple memory allocation routines needed */ +/* put ring buffer in low memory */ +/* need to allocate front, back, depth buffers aligned correctly, + allocate ring buffer, +*/ + +/* */ +static Bool +I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned long size, ret; + unsigned long lines, lineSize, align; + + /* allocate ring buffer */ + memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); + pI830->LpRing->mem.Key = -1; + + size = PRIMARY_RINGBUFFER_SIZE; + + ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0); + + if (ret != size) + { + fprintf(stderr,"unable to allocate ring buffer %ld\n", ret); + return FALSE; + } + + pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; + + + /* allocate front buffer */ + memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); + pI830->FrontBuffer.Key = -1; + pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth; + + align = KB(512); + + lineSize = ctx->shared.virtualWidth * ctx->cpp; + lines = (ctx->shared.virtualHeight + 15) / 16 * 16; + size = lineSize * lines; + size = ROUND_TO_PAGE(size); + + align = GetBestTileAlignment(size); + + ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate front buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); + pI830->BackBuffer.Key = -1; + pI830->BackBuffer.Pitch = ctx->shared.virtualWidth; + + ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate back buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); + pI830->DepthBuffer.Key = -1; + pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth; + + ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate depth buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); + pI830->ContextMem.Key = -1; + size = KB(32); + + ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate context buffer %ld\n", ret); + return FALSE; + } + +#if 0 + memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); + pI830->TexMem.Key = -1; + + size = 32768 * 1024; + ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem); + if (ret < size) + { + fprintf(stderr,"unable to allocate texture memory %ld\n", ret); + return FALSE; + } +#endif + + return TRUE; +} + +static Bool +I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + if (!BindAgpRange(ctx, &pI830->LpRing->mem)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->FrontBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->BackBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->DepthBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->ContextMem)) + return FALSE; +#if 0 + if (!BindAgpRange(ctx, &pI830->TexMem)) + return FALSE; +#endif + return TRUE; +} + +static void SetupDRIMM(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned long aperEnd = ROUND_DOWN_TO(pI830->aper_size, GTT_PAGE_SIZE) / GTT_PAGE_SIZE; + unsigned long aperStart = ROUND_TO(pI830->aper_size - KB(32768), GTT_PAGE_SIZE) / GTT_PAGE_SIZE; + + fprintf(stderr, "aper size is %08X\n", ctx->shared.fbSize); + if (drmMMInit(ctx->drmFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) { + fprintf(stderr, + "DRM MM Initialization Failed\n"); + } else { + fprintf(stderr, + "DRM MM Initialized at offset 0x%lx length %d page\n", aperStart, aperEnd-aperStart); + } + +} + +static Bool +I830CleanupDma(const DRIDriverContext *ctx) +{ + drmI830Init info; + + memset(&info, 0, sizeof(drmI830Init)); + info.func = I830_CLEANUP_DMA; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, + &info, sizeof(drmI830Init))) { + fprintf(stderr, "I830 Dma Cleanup Failed\n"); + return FALSE; + } + + return TRUE; +} + +static Bool +I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830) +{ + I830RingBuffer *ring = pI830->LpRing; + drmI830Init info; + + memset(&info, 0, sizeof(drmI830Init)); + info.func = I830_INIT_DMA; + + info.ring_start = ring->mem.Start + pI830->LinearAddr; + info.ring_end = ring->mem.End + pI830->LinearAddr; + info.ring_size = ring->mem.Size; + + info.mmio_offset = (unsigned int)ctx->MMIOStart; + + info.sarea_priv_offset = sizeof(drm_sarea_t); + + info.front_offset = pI830->FrontBuffer.Start; + info.back_offset = pI830->BackBuffer.Start; + info.depth_offset = pI830->DepthBuffer.Start; + info.w = ctx->shared.virtualWidth; + info.h = ctx->shared.virtualHeight; + info.pitch = ctx->shared.virtualWidth; + info.back_pitch = pI830->BackBuffer.Pitch; + info.depth_pitch = pI830->DepthBuffer.Pitch; + info.cpp = ctx->cpp; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, + &info, sizeof(drmI830Init))) { + fprintf(stderr, + "I830 Dma Initialization Failed\n"); + return FALSE; + } + + return TRUE; +} + +static int I830CheckDRMVersion( const DRIDriverContext *ctx, + I830Rec *pI830 ) +{ + drmVersionPtr version; + + version = drmGetVersion(ctx->drmFD); + + if (version) { + int req_minor, req_patch; + + req_minor = 4; + req_patch = 0; + + if (version->version_major != 1 || + version->version_minor < req_minor || + (version->version_minor == req_minor && + version->version_patchlevel < req_patch)) { + /* Incompatible drm version */ + fprintf(stderr, + "[dri] I830DRIScreenInit failed because of a version " + "mismatch.\n" + "[dri] i915.o kernel module version is %d.%d.%d " + "but version 1.%d.%d or newer is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel, + req_minor, + req_patch); + drmFreeVersion(version); + return 0; + } + + pI830->drmMinor = version->version_minor; + drmFreeVersion(version); + } + return 1; +} + +static void +I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned int itemp; + unsigned char *MMIO = ctx->MMIOAddress; + + OUTREG(LP_RING + RING_LEN, 0); + OUTREG(LP_RING + RING_TAIL, 0); + OUTREG(LP_RING + RING_HEAD, 0); + + if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != + pI830->LpRing->mem.Start) { + fprintf(stderr, + "I830SetRingRegs: Ring buffer start (%lx) violates its " + "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); + } + /* Don't care about the old value. Reserved bits must be zero anyway. */ + itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; + OUTREG(LP_RING + RING_START, itemp); + + if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != + pI830->LpRing->mem.Size - 4096) { + fprintf(stderr, + "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " + "mask (%x)\n", pI830->LpRing->mem.Size - 4096, + I830_RING_NR_PAGES); + } + /* Don't care about the old value. Reserved bits must be zero anyway. */ + itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; + itemp |= (RING_NO_REPORT | RING_VALID); + OUTREG(LP_RING + RING_LEN, itemp); + + pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; + pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); + pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); + if (pI830->LpRing->space < 0) + pI830->LpRing->space += pI830->LpRing->mem.Size; + + SetFenceRegs(ctx, pI830); + + /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky + hacky hacky */ + OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr); + +} + +static Bool +I830SetParam(const DRIDriverContext *ctx, int param, int value) +{ + drmI830SetParam sp; + + memset(&sp, 0, sizeof(sp)); + sp.param = param; + sp.value = value; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { + fprintf(stderr, "I830 SetParam Failed\n"); + return FALSE; + } + + return TRUE; +} + +static Bool +I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + fprintf(stderr, + "[drm] Mapping front buffer\n"); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), + sarea->front_size, + DRM_FRAME_BUFFER, /*DRM_AGP,*/ + 0, + &sarea->front_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); + return FALSE; + } + ctx->shared.hFrameBuffer = sarea->front_handle; + ctx->shared.fbSize = sarea->front_size; + fprintf(stderr, "[drm] Front Buffer = 0x%08x\n", + sarea->front_handle); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)(sarea->back_offset), + sarea->back_size, DRM_AGP, 0, + &sarea->back_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] Back Buffer = 0x%08x\n", + sarea->back_handle); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)sarea->depth_offset, + sarea->depth_size, DRM_AGP, 0, + &sarea->depth_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n", + sarea->depth_handle); + +#if 0 + if (drmAddMap(ctx->drmFD, + (drm_handle_t)sarea->tex_offset, + sarea->tex_size, DRM_AGP, 0, + &sarea->tex_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] textures = 0x%08x\n", + sarea->tex_handle); +#endif + return TRUE; +} + + +static void +I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ +#if 1 + if (sarea->front_handle) { + drmRmMap(ctx->drmFD, sarea->front_handle); + sarea->front_handle = 0; + } +#endif + if (sarea->back_handle) { + drmRmMap(ctx->drmFD, sarea->back_handle); + sarea->back_handle = 0; + } + if (sarea->depth_handle) { + drmRmMap(ctx->drmFD, sarea->depth_handle); + sarea->depth_handle = 0; + } + if (sarea->tex_handle) { + drmRmMap(ctx->drmFD, sarea->tex_handle); + sarea->tex_handle = 0; + } +} + +static Bool +I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + if (drmAddMap(ctx->drmFD, + (drm_handle_t)pI830->LpRing->mem.Start, + pI830->LpRing->mem.Size, DRM_AGP, 0, + &pI830->ring_map) < 0) { + fprintf(stderr, + "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] ring buffer = 0x%08x\n", + pI830->ring_map); + + if (I830InitDma(ctx, pI830) == FALSE) { + return FALSE; + } + + /* init to zero to be safe */ + + I830DRIMapScreenRegions(ctx, pI830, sarea); + SetupDRIMM(ctx, pI830); + + if (ctx->pciDevice != PCI_CHIP_845_G && + ctx->pciDevice != PCI_CHIP_I830_M) { + I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); + } + + /* Okay now initialize the dma engine */ + { + pI830->irq = drmGetInterruptFromBusID(ctx->drmFD, + ctx->pciBus, + ctx->pciDevice, + ctx->pciFunc); + + if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) { + fprintf(stderr, + "[drm] failure adding irq handler\n"); + pI830->irq = 0; + return FALSE; + } + else + fprintf(stderr, + "[drm] dma control initialized, using IRQ %d\n", + pI830->irq); + } + + fprintf(stderr, "[dri] visual configs initialized\n"); + + return TRUE; +} + +static Bool +I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + /* need to drmMap front and back buffers and zero them */ + drmAddress map_addr; + int ret; + + ret = drmMap(ctx->drmFD, + sarea->front_handle, + sarea->front_size, + &map_addr); + + if (ret) + { + fprintf(stderr, "Unable to map front buffer\n"); + return FALSE; + } + + drimemsetio((char *)map_addr, + 0, + sarea->front_size); + drmUnmap(map_addr, sarea->front_size); + + + ret = drmMap(ctx->drmFD, + sarea->back_handle, + sarea->back_size, + &map_addr); + + if (ret) + { + fprintf(stderr, "Unable to map back buffer\n"); + return FALSE; + } + + drimemsetio((char *)map_addr, + 0, + sarea->back_size); + drmUnmap(map_addr, sarea->back_size); + + return TRUE; +} + +static Bool +I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830) + +{ + I830DRIPtr pI830DRI; + drmI830Sarea *pSAREAPriv; + int err; + + drm_page_size = getpagesize(); + + pI830->registerSize = ctx->MMIOSize; + /* This is a hack for now. We have to have more than a 4k page here + * because of the size of the state. However, the state should be + * in a per-context mapping. This will be added in the Mesa 3.5 port + * of the I830 driver. + */ + ctx->shared.SAREASize = SAREA_MAX; + + /* Note that drmOpen will try to load the kernel module, if needed. */ + ctx->drmFD = drmOpen("i915", NULL ); + if (ctx->drmFD < 0) { + fprintf(stderr, "[drm] drmOpen failed\n"); + return 0; + } + + if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { + fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", + ctx->drmFD, ctx->pciBusID, strerror(-err)); + return 0; + } + + if (drmAddMap( ctx->drmFD, + 0, + ctx->shared.SAREASize, + DRM_SHM, + DRM_CONTAINS_LOCK, + &ctx->shared.hSAREA) < 0) + { + fprintf(stderr, "[drm] drmAddMap failed\n"); + return 0; + } + + fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n", + ctx->shared.SAREASize, ctx->shared.hSAREA); + + if (drmMap( ctx->drmFD, + ctx->shared.hSAREA, + ctx->shared.SAREASize, + (drmAddressPtr)(&ctx->pSAREA)) < 0) + { + fprintf(stderr, "[drm] drmMap failed\n"); + return 0; + + } + + memset(ctx->pSAREA, 0, ctx->shared.SAREASize); + fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n", + ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); + + + if (drmAddMap(ctx->drmFD, + ctx->MMIOStart, + ctx->MMIOSize, + DRM_REGISTERS, + DRM_READ_ONLY, + &pI830->registerHandle) < 0) { + fprintf(stderr, "[drm] drmAddMap mmio failed\n"); + return 0; + } + fprintf(stderr, + "[drm] register handle = 0x%08x\n", pI830->registerHandle); + + + if (!I830CheckDRMVersion(ctx, pI830)) { + return FALSE; + } + + /* Create a 'server' context so we can grab the lock for + * initialization ioctls. + */ + if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { + fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); + return 0; + } + + DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); + + /* Initialize the SAREA private data structure */ + pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + + sizeof(drm_sarea_t)); + memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + + pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830); + pI830->StolenMemory.Start = 0; + pI830->StolenMemory.End = pI830->StolenMemory.Size; + + pI830->MemoryAperture.Start = pI830->StolenMemory.End; + pI830->MemoryAperture.End = KB(40000); + pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; + + pI830->StolenPool.Fixed = pI830->StolenMemory; + pI830->StolenPool.Total = pI830->StolenMemory; + pI830->StolenPool.Free = pI830->StolenPool.Total; + pI830->FreeMemory = pI830->StolenPool.Total.Size; + + if (!AgpInit(ctx, pI830)) + return FALSE; + + if (I830AllocateMemory(ctx, pI830) == FALSE) + { + return FALSE; + } + + if (I830BindMemory(ctx, pI830) == FALSE) + { + return FALSE; + } + + pSAREAPriv->rotated_offset = -1; + pSAREAPriv->rotated_size = 0; + pSAREAPriv->rotated_pitch = ctx->shared.virtualWidth; + + pSAREAPriv->front_offset = pI830->FrontBuffer.Start; + pSAREAPriv->front_size = pI830->FrontBuffer.Size; + pSAREAPriv->width = ctx->shared.virtualWidth; + pSAREAPriv->height = ctx->shared.virtualHeight; + pSAREAPriv->pitch = ctx->shared.virtualWidth; + pSAREAPriv->virtualX = ctx->shared.virtualWidth; + pSAREAPriv->virtualY = ctx->shared.virtualHeight; + pSAREAPriv->back_offset = pI830->BackBuffer.Start; + pSAREAPriv->back_size = pI830->BackBuffer.Size; + pSAREAPriv->depth_offset = pI830->DepthBuffer.Start; + pSAREAPriv->depth_size = pI830->DepthBuffer.Size; +#if 0 + pSAREAPriv->tex_offset = pI830->TexMem.Start; + pSAREAPriv->tex_size = pI830->TexMem.Size; +#endif + pSAREAPriv->log_tex_granularity = pI830->TexGranularity; + + ctx->driverClientMsg = malloc(sizeof(I830DRIRec)); + ctx->driverClientMsgSize = sizeof(I830DRIRec); + pI830DRI = (I830DRIPtr)ctx->driverClientMsg; + pI830DRI->deviceID = pI830->Chipset; + pI830DRI->regsSize = I830_REG_SIZE; + pI830DRI->width = ctx->shared.virtualWidth; + pI830DRI->height = ctx->shared.virtualHeight; + pI830DRI->mem = ctx->shared.fbSize; + pI830DRI->cpp = ctx->cpp; + + pI830DRI->bitsPerPixel = ctx->bpp; + pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t); + + err = I830DRIDoMappings(ctx, pI830, pSAREAPriv); + if (err == FALSE) + return FALSE; + + I830SetupMemoryTiling(ctx, pI830); + + /* Quick hack to clear the front & back buffers. Could also use + * the clear ioctl to do this, but would need to setup hw state + * first. + */ + I830ClearScreen(ctx, pI830, pSAREAPriv); + + I830SetRingRegs(ctx, pI830); + + return TRUE; +} + + +/** + * \brief Validate the fbdev mode. + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Saves some registers and returns 1. + * + * \sa radeonValidateMode(). + */ +static int i830ValidateMode( const DRIDriverContext *ctx ) +{ + return 1; +} + +/** + * \brief Examine mode returned by fbdev. + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Restores registers that fbdev has clobbered and returns 1. + * + * \sa i810ValidateMode(). + */ +static int i830PostValidateMode( const DRIDriverContext *ctx ) +{ + I830Rec *pI830 = ctx->driverPrivate; + + I830SetRingRegs(ctx, pI830); + return 1; +} + + +/** + * \brief Initialize the framebuffer device mode + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Fills in \p info with some default values and some information from \p ctx + * and then calls I810ScreenInit() for the screen initialization. + * + * Before exiting clears the framebuffer memory accessing it directly. + */ +static int i830InitFBDev( DRIDriverContext *ctx ) +{ + I830Rec *pI830 = calloc(1, sizeof(I830Rec)); + int i; + + { + int dummy = ctx->shared.virtualWidth; + + switch (ctx->bpp / 8) { + case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; + case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; + case 3: + case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; + } + + ctx->shared.virtualWidth = dummy; + ctx->shared.Width = ctx->shared.virtualWidth; + } + + + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= ctx->shared.virtualWidth) { + ctx->shared.virtualWidth = pitches[i]; + break; + } + } + + ctx->driverPrivate = (void *)pI830; + + pI830->LpRing = calloc(1, sizeof(I830RingBuffer)); + pI830->Chipset = ctx->chipset; + pI830->LinearAddr = ctx->FBStart; + + if (!I830ScreenInit( ctx, pI830 )) + return 0; + + + return 1; +} + + +/** + * \brief The screen is being closed, so clean up any state and free any + * resources used by the DRI. + * + * \param ctx display handle. + * + * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver + * private data. + */ +static void i830HaltFBDev( DRIDriverContext *ctx ) +{ + drmI830Sarea *pSAREAPriv; + I830Rec *pI830 = ctx->driverPrivate; + + if (pI830->irq) { + drmCtlUninstHandler(ctx->drmFD); + pI830->irq = 0; } + + I830CleanupDma(ctx); + + pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + + sizeof(drm_sarea_t)); + + I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv); + drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); + drmClose(ctx->drmFD); + + if (ctx->driverPrivate) { + free(ctx->driverPrivate); + ctx->driverPrivate = 0; + } +} + + +extern void i810NotifyFocus( int ); + +/** + * \brief Exported driver interface for Mini GLX. + * + * \sa DRIDriverRec. + */ +const struct DRIDriverRec __driDriver = { + i830ValidateMode, + i830PostValidateMode, + i830InitFBDev, + i830HaltFBDev, + NULL,//I830EngineShutdown, + NULL, //I830EngineRestore, +#ifndef _EMBEDDED + 0, +#else + i810NotifyFocus, +#endif +}; diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c new file mode 100644 index 0000000000..541d50c6e4 --- /dev/null +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -0,0 +1,392 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + 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, sublicense, 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 NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_aub.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "imports.h" +//#include "intel_winsys.h" + + +struct brw_aubfile { + FILE *file; + unsigned next_free_page; +}; + + +extern char *__progname; + + +struct aub_file_header { + unsigned int instruction_type; + unsigned int pad0:16; + unsigned int minor:8; + unsigned int major:8; + unsigned char application[8*4]; + unsigned int day:8; + unsigned int month:8; + unsigned int year:16; + unsigned int timezone:8; + unsigned int second:8; + unsigned int minute:8; + unsigned int hour:8; + unsigned int comment_length:16; + unsigned int pad1:16; +}; + +struct aub_block_header { + unsigned int instruction_type; + unsigned int operation:8; + unsigned int type:8; + unsigned int address_space:8; + unsigned int pad0:8; + unsigned int general_state_type:8; + unsigned int surface_state_type:8; + unsigned int pad1:16; + unsigned int address; + unsigned int length; +}; + +struct aub_dump_bmp { + unsigned int instruction_type; + unsigned int xmin:16; + unsigned int ymin:16; + unsigned int pitch:16; + unsigned int bpp:8; + unsigned int format:8; + unsigned int xsize:16; + unsigned int ysize:16; + unsigned int addr; + unsigned int unknown; +}; + +enum bh_operation { + BH_COMMENT, + BH_DATA_WRITE, + BH_COMMAND_WRITE, + BH_MMI0_WRITE32, + BH_END_SCENE, + BH_CONFIG_MEMORY_MAP, + BH_MAX_OPERATION +}; + +enum command_write_type { + CW_HWB_RING = 1, + CW_PRIMARY_RING_A, + CW_PRIMARY_RING_B, /* XXX - disagreement with listaub! */ + CW_PRIMARY_RING_C, + CW_MAX_TYPE +}; + +enum memory_map_type { + MM_DEFAULT, + MM_DYNAMIC, + MM_MAX_TYPE +}; + +enum address_space { + ADDR_GTT, + ADDR_LOCAL, + ADDR_MAIN, + ADDR_MAX +}; + + +#define AUB_FILE_HEADER 0xe085000b +#define AUB_BLOCK_HEADER 0xe0c10003 +#define AUB_DUMP_BMP 0xe09e0004 + +/* Registers to control page table + */ +#define PGETBL_CTL 0x2020 +#define PGETBL_ENABLED 0x1 + +#define NR_GTT_ENTRIES 65536 /* 256 mb */ + +#define FAIL \ +do { \ + fprintf(stderr, "failed to write aub data at %s/%d\n", __FUNCTION__, __LINE__); \ + exit(1); \ +} while (0) + + +/* Emit the headers at the top of each aubfile. Initialize the GTT. + */ +static void init_aubfile( FILE *aub_file ) +{ + struct aub_file_header fh; + struct aub_block_header bh; + unsigned int data; + + static int nr; + + nr++; + + /* Emit the aub header: + */ + memset(&fh, 0, sizeof(fh)); + + fh.instruction_type = AUB_FILE_HEADER; + fh.minor = 0x0; + fh.major = 0x7; + memcpy(fh.application, __progname, sizeof(fh.application)); + fh.day = (nr>>24) & 0xff; + fh.month = 0x0; + fh.year = 0x0; + fh.timezone = 0x0; + fh.second = nr & 0xff; + fh.minute = (nr>>8) & 0xff; + fh.hour = (nr>>16) & 0xff; + fh.comment_length = 0x0; + + if (fwrite(&fh, sizeof(fh), 1, aub_file) < 0) + FAIL; + + /* Setup the GTT starting at main memory address zero (!): + */ + memset(&bh, 0, sizeof(bh)); + + bh.instruction_type = AUB_BLOCK_HEADER; + bh.operation = BH_MMI0_WRITE32; + bh.type = 0x0; + bh.address_space = ADDR_GTT; /* ??? */ + bh.general_state_type = 0x0; + bh.surface_state_type = 0x0; + bh.address = PGETBL_CTL; + bh.length = 0x4; + + if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) + FAIL; + + data = 0x0 | PGETBL_ENABLED; + + if (fwrite(&data, sizeof(data), 1, aub_file) < 0) + FAIL; +} + + +static void init_aub_gtt( struct brw_aubfile *aubfile, + unsigned start_offset, + unsigned size ) +{ + FILE *aub_file = aubfile->file; + struct aub_block_header bh; + unsigned int i; + + assert(start_offset + size < NR_GTT_ENTRIES * 4096); + + + memset(&bh, 0, sizeof(bh)); + + bh.instruction_type = AUB_BLOCK_HEADER; + bh.operation = BH_DATA_WRITE; + bh.type = 0x0; + bh.address_space = ADDR_MAIN; + bh.general_state_type = 0x0; + bh.surface_state_type = 0x0; + bh.address = start_offset / 4096 * 4; + bh.length = size / 4096 * 4; + + if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) + FAIL; + + for (i = 0; i < size / 4096; i++) { + unsigned data = aubfile->next_free_page | 1; + + aubfile->next_free_page += 4096; + + if (fwrite(&data, sizeof(data), 1, aub_file) < 0) + FAIL; + } + +} + +static void write_block_header( FILE *aub_file, + struct aub_block_header *bh, + const unsigned *data, + unsigned sz ) +{ + sz = (sz + 3) & ~3; + + if (fwrite(bh, sizeof(*bh), 1, aub_file) < 0) + FAIL; + + if (fwrite(data, sz, 1, aub_file) < 0) + FAIL; + + fflush(aub_file); +} + + +static void write_dump_bmp( FILE *aub_file, + struct aub_dump_bmp *db ) +{ + if (fwrite(db, sizeof(*db), 1, aub_file) < 0) + FAIL; + + fflush(aub_file); +} + + + +void brw_aub_gtt_data( struct brw_aubfile *aubfile, + unsigned offset, + const void *data, + unsigned sz, + unsigned type, + unsigned state_type ) +{ + struct aub_block_header bh; + + bh.instruction_type = AUB_BLOCK_HEADER; + bh.operation = BH_DATA_WRITE; + bh.type = type; + bh.address_space = ADDR_GTT; + bh.pad0 = 0; + + if (type == DW_GENERAL_STATE) { + bh.general_state_type = state_type; + bh.surface_state_type = 0; + } + else { + bh.general_state_type = 0; + bh.surface_state_type = state_type; + } + + bh.pad1 = 0; + bh.address = offset; + bh.length = sz; + + write_block_header(aubfile->file, &bh, data, sz); +} + + + +void brw_aub_gtt_cmds( struct brw_aubfile *aubfile, + unsigned offset, + const void *data, + unsigned sz ) +{ + struct aub_block_header bh; + unsigned type = CW_PRIMARY_RING_A; + + + bh.instruction_type = AUB_BLOCK_HEADER; + bh.operation = BH_COMMAND_WRITE; + bh.type = type; + bh.address_space = ADDR_GTT; + bh.pad0 = 0; + bh.general_state_type = 0; + bh.surface_state_type = 0; + bh.pad1 = 0; + bh.address = offset; + bh.length = sz; + + write_block_header(aubfile->file, &bh, data, sz); +} + +void brw_aub_dump_bmp( struct brw_aubfile *aubfile, + struct pipe_surface *surface, + unsigned gtt_offset ) +{ + struct aub_dump_bmp db; + unsigned format; + + if (surface->cpp == 4) + format = 0x7; + else + format = 0x3; + + db.instruction_type = AUB_DUMP_BMP; + db.xmin = 0; + db.ymin = 0; + db.format = format; + db.bpp = surface->cpp * 8; + db.pitch = surface->pitch; + db.xsize = surface->width; + db.ysize = surface->height; + db.addr = gtt_offset; + db.unknown = /* surface->tiled ? 0x4 : */ 0x0; + + write_dump_bmp(aubfile->file, &db); +} + + + +struct brw_aubfile *brw_aubfile_create( void ) +{ + struct brw_aubfile *aubfile = CALLOC_STRUCT(brw_aubfile); + char filename[80]; + int val; + static int i = 0; + + i++; + + if (_mesa_getenv("INTEL_AUBFILE")) { + val = snprintf(filename, sizeof(filename), "%s%d.aub", _mesa_getenv("INTEL_AUBFILE"), i%4); + _mesa_printf("--> Aub file: %s\n", filename); + aubfile->file = fopen(filename, "w"); + } + else { + val = snprintf(filename, sizeof(filename), "%s.aub", __progname); + if (val < 0 || val > sizeof(filename)) + strcpy(filename, "default.aub"); + + _mesa_printf("--> Aub file: %s\n", filename); + aubfile->file = fopen(filename, "w"); + } + + if (!aubfile->file) { + _mesa_printf("couldn't open aubfile\n"); + exit(1); + } + + init_aubfile(aubfile->file); + + /* The GTT is located starting address zero in main memory. Pages + * to populate the gtt start after this point. + */ + aubfile->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095; + + /* More or less correspond with all the agp regions mapped by the + * driver: + */ + init_aub_gtt(aubfile, 0, 4096*4); + init_aub_gtt(aubfile, AUB_BUF_START, AUB_BUF_SIZE); + + return aubfile; +} + +void brw_aub_destroy( struct brw_aubfile *aubfile ) +{ + fclose(aubfile->file); + FREE(aubfile); +} diff --git a/src/gallium/winsys/xlib/brw_aub.h b/src/gallium/winsys/xlib/brw_aub.h new file mode 100644 index 0000000000..f5c60c7be2 --- /dev/null +++ b/src/gallium/winsys/xlib/brw_aub.h @@ -0,0 +1,114 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + 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, sublicense, 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 NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#ifndef BRW_AUB_H +#define BRW_AUB_H + +/* We set up this region, buffers may be allocated here: + */ +#define AUB_BUF_START (4096*4) +#define AUB_BUF_SIZE (8*1024*1024) + +struct intel_context; +struct pipe_surface; + +struct brw_aubfile *brw_aubfile_create( void ); + +void brw_aub_destroy( struct brw_aubfile *aubfile ); + +void brw_aub_gtt_data( struct brw_aubfile *aubfile, + unsigned offset, + const void *data, + unsigned sz, + unsigned type, + unsigned state_type ); + +void brw_aub_gtt_cmds( struct brw_aubfile *aubfile, + unsigned offset, + const void *data, + unsigned sz ); + +void brw_aub_dump_bmp( struct brw_aubfile *aubfile, + struct pipe_surface *surface, + unsigned gtt_offset ); + + +enum data_write_type { + DW_NOTYPE, + DW_BATCH_BUFFER, + DW_BIN_BUFFER, + DW_BIN_POINTER_LIST, + DW_SLOW_STATE_BUFFER, + DW_VERTEX_BUFFER, + DW_2D_MAP, + DW_CUBE_MAP, + DW_INDIRECT_STATE_BUFFER, + DW_VOLUME_MAP, + DW_1D_MAP, + DW_CONSTANT_BUFFER, + DW_CONSTANT_URB_ENTRY, + DW_INDEX_BUFFER, + DW_GENERAL_STATE, + DW_SURFACE_STATE, + DW_MEDIA_OBJECT_INDIRECT_DATA, + DW_MAX_TYPE +}; + +enum data_write_general_state_type { + DWGS_NOTYPE, + DWGS_VERTEX_SHADER_STATE, + DWGS_GEOMETRY_SHADER_STATE , + DWGS_CLIPPER_STATE, + DWGS_STRIPS_FANS_STATE, + DWGS_WINDOWER_IZ_STATE, + DWGS_COLOR_CALC_STATE, + DWGS_CLIPPER_VIEWPORT_STATE, /* was 0x7 */ + DWGS_STRIPS_FANS_VIEWPORT_STATE, + DWGS_COLOR_CALC_VIEWPORT_STATE, /* was 0x9 */ + DWGS_SAMPLER_STATE, + DWGS_KERNEL_INSTRUCTIONS, + DWGS_SCRATCH_SPACE, + DWGS_SAMPLER_DEFAULT_COLOR, + DWGS_INTERFACE_DESCRIPTOR, + DWGS_VLD_STATE, + DWGS_VFE_STATE, + DWGS_MAX_TYPE +}; + +enum data_write_surface_state_type { + DWSS_NOTYPE, + DWSS_BINDING_TABLE_STATE, + DWSS_SURFACE_STATE, + DWSS_MAX_TYPE +}; + + +#endif diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c new file mode 100644 index 0000000000..902a755075 --- /dev/null +++ b/src/gallium/winsys/xlib/fakeglx.c @@ -0,0 +1,3188 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + + +/* + * This is an emulation of the GLX API which allows Mesa/GLX-based programs + * to run on X servers which do not have the real GLX extension. + * + * Thanks to the contributors: + * + * Initial version: Philip Brown (phil@bolthole.com) + * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu) + * Further visual-handling refinements: Wolfram Gloger + * (wmglo@Dent.MED.Uni-Muenchen.DE). + * + * Notes: + * Don't be fooled, stereo isn't supported yet. + */ + + + +#include "glxheader.h" +#include "glxapi.h" +#include "GL/xmesa.h" +#include "context.h" +#include "config.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" +#include "version.h" +#include "xfonts.h" +#include "xmesaP.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_public.h" + + +#ifdef __VMS +#define _mesa_sprintf sprintf +#endif + +/* This indicates the client-side GLX API and GLX encoder version. */ +#define CLIENT_MAJOR_VERSION 1 +#define CLIENT_MINOR_VERSION 4 /* but don't have 1.3's pbuffers, etc yet */ + +/* This indicates the server-side GLX decoder version. + * GLX 1.4 indicates OpenGL 1.3 support + */ +#define SERVER_MAJOR_VERSION 1 +#define SERVER_MINOR_VERSION 4 + +/* This is appended onto the glXGetClient/ServerString version strings. */ +#define MESA_GLX_VERSION "Mesa " MESA_VERSION_STRING + +/* Who implemented this GLX? */ +#define VENDOR "Brian Paul" + +#define EXTENSIONS \ + "GLX_MESA_set_3dfx_mode " \ + "GLX_MESA_copy_sub_buffer " \ + "GLX_MESA_pixmap_colormap " \ + "GLX_MESA_release_buffers " \ + "GLX_ARB_get_proc_address " \ + "GLX_EXT_texture_from_pixmap " \ + "GLX_EXT_visual_info " \ + "GLX_EXT_visual_rating " \ + /*"GLX_SGI_video_sync "*/ \ + "GLX_SGIX_fbconfig " \ + "GLX_SGIX_pbuffer " + +/* + * Our fake GLX context will contain a "real" GLX context and an XMesa context. + * + * Note that a pointer to a __GLXcontext is a pointer to a fake_glx_context, + * and vice versa. + * + * We really just need this structure in order to make the libGL functions + * glXGetCurrentContext(), glXGetCurrentDrawable() and glXGetCurrentDisplay() + * work correctly. + */ +struct fake_glx_context { + __GLXcontext glxContext; /* this MUST be first! */ + XMesaContext xmesaContext; +}; + + + +/**********************************************************************/ +/*** GLX Visual Code ***/ +/**********************************************************************/ + +#define DONT_CARE -1 + + +static XMesaVisual *VisualTable = NULL; +static int NumVisuals = 0; + + +/* + * This struct and some code fragments borrowed + * from Mark Kilgard's GLUT library. + */ +typedef struct _OverlayInfo { + /* Avoid 64-bit portability problems by being careful to use + longs due to the way XGetWindowProperty is specified. Note + that these parameters are passed as CARD32s over X + protocol. */ + unsigned long overlay_visual; + long transparent_type; + long value; + long layer; +} OverlayInfo; + + + +/* Macro to handle c_class vs class field name in XVisualInfo struct */ +#if defined(__cplusplus) || defined(c_plusplus) +#define CLASS c_class +#else +#define CLASS class +#endif + + + +/* + * Test if the given XVisualInfo is usable for Mesa rendering. + */ +static GLboolean +is_usable_visual( XVisualInfo *vinfo ) +{ + switch (vinfo->CLASS) { + case StaticGray: + case GrayScale: + /* Any StaticGray/GrayScale visual works in RGB or CI mode */ + return GL_TRUE; + case StaticColor: + case PseudoColor: + /* Any StaticColor/PseudoColor visual of at least 4 bits */ + if (vinfo->depth>=4) { + return GL_TRUE; + } + else { + return GL_FALSE; + } + case TrueColor: + case DirectColor: + /* Any depth of TrueColor or DirectColor works in RGB mode */ + return GL_TRUE; + default: + /* This should never happen */ + return GL_FALSE; + } +} + + + +/** + * Get an array OverlayInfo records for specified screen. + * \param dpy the display + * \param screen screen number + * \param numOverlays returns numver of OverlayInfo records + * \return pointer to OverlayInfo array, free with XFree() + */ +static OverlayInfo * +GetOverlayInfo(Display *dpy, int screen, int *numOverlays) +{ + Atom overlayVisualsAtom; + Atom actualType; + Status status; + unsigned char *ovInfo; + unsigned long sizeData, bytesLeft; + int actualFormat; + + /* + * The SERVER_OVERLAY_VISUALS property on the root window contains + * a list of overlay visuals. Get that list now. + */ + overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True); + if (overlayVisualsAtom == None) { + return 0; + } + + status = XGetWindowProperty(dpy, RootWindow(dpy, screen), + overlayVisualsAtom, 0L, (long) 10000, False, + overlayVisualsAtom, &actualType, &actualFormat, + &sizeData, &bytesLeft, + &ovInfo); + + if (status != Success || actualType != overlayVisualsAtom || + actualFormat != 32 || sizeData < 4) { + /* something went wrong */ + XFree((void *) ovInfo); + *numOverlays = 0; + return NULL; + } + + *numOverlays = sizeData / 4; + return (OverlayInfo *) ovInfo; +} + + + +/** + * Return the level (overlay, normal, underlay) of a given XVisualInfo. + * Input: dpy - the X display + * vinfo - the XVisualInfo to test + * Return: level of the visual: + * 0 = normal planes + * >0 = overlay planes + * <0 = underlay planes + */ +static int +level_of_visual( Display *dpy, XVisualInfo *vinfo ) +{ + OverlayInfo *overlay_info; + int numOverlaysPerScreen, i; + + overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); + if (!overlay_info) { + return 0; + } + + /* search the overlay visual list for the visual ID of interest */ + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *ov = overlay_info + i; + if (ov->overlay_visual == vinfo->visualid) { + /* found the visual */ + if (/*ov->transparent_type==1 &&*/ ov->layer!=0) { + int level = ov->layer; + XFree((void *) overlay_info); + return level; + } + else { + XFree((void *) overlay_info); + return 0; + } + } + } + + /* The visual ID was not found in the overlay list. */ + XFree((void *) overlay_info); + return 0; +} + + + + +/* + * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the + * configuration in our list of GLX visuals. + */ +static XMesaVisual +save_glx_visual( Display *dpy, XVisualInfo *vinfo, + GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag, + GLboolean stereoFlag, + GLint depth_size, GLint stencil_size, + GLint accumRedSize, GLint accumGreenSize, + GLint accumBlueSize, GLint accumAlphaSize, + GLint level, GLint numAuxBuffers ) +{ + GLboolean ximageFlag = GL_TRUE; + XMesaVisual xmvis; + GLint i; + GLboolean comparePointers; + + if (dbFlag) { + /* Check if the MESA_BACK_BUFFER env var is set */ + char *backbuffer = _mesa_getenv("MESA_BACK_BUFFER"); + if (backbuffer) { + if (backbuffer[0]=='p' || backbuffer[0]=='P') { + ximageFlag = GL_FALSE; + } + else if (backbuffer[0]=='x' || backbuffer[0]=='X') { + ximageFlag = GL_TRUE; + } + else { + _mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage."); + } + } + } + + if (stereoFlag) { + /* stereo not supported */ + return NULL; + } + + /* Comparing IDs uses less memory but sometimes fails. */ + /* XXX revisit this after 3.0 is finished. */ + if (_mesa_getenv("MESA_GLX_VISUAL_HACK")) + comparePointers = GL_TRUE; + else + comparePointers = GL_FALSE; + + /* Force the visual to have an alpha channel */ + if (rgbFlag && _mesa_getenv("MESA_GLX_FORCE_ALPHA")) + alphaFlag = GL_TRUE; + + /* First check if a matching visual is already in the list */ + for (i=0; idisplay == dpy + && v->mesa_visual.level == level + && v->mesa_visual.numAuxBuffers == numAuxBuffers + && v->ximage_flag == ximageFlag + && v->mesa_visual.rgbMode == rgbFlag + && v->mesa_visual.doubleBufferMode == dbFlag + && v->mesa_visual.stereoMode == stereoFlag + && (v->mesa_visual.alphaBits > 0) == alphaFlag + && (v->mesa_visual.depthBits >= depth_size || depth_size == 0) + && (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0) + && (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0) + && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0) + && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0) + && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) { + /* now either compare XVisualInfo pointers or visual IDs */ + if ((!comparePointers && v->visinfo->visualid == vinfo->visualid) + || (comparePointers && v->vishandle == vinfo)) { + return v; + } + } + } + + /* Create a new visual and add it to the list. */ + + xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag, + stereoFlag, ximageFlag, + depth_size, stencil_size, + accumRedSize, accumBlueSize, + accumBlueSize, accumAlphaSize, 0, level, + GLX_NONE_EXT ); + if (xmvis) { + /* Save a copy of the pointer now so we can find this visual again + * if we need to search for it in find_glx_visual(). + */ + xmvis->vishandle = vinfo; + /* Allocate more space for additional visual */ + VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable, + sizeof(XMesaVisual) * NumVisuals, + sizeof(XMesaVisual) * (NumVisuals + 1)); + /* add xmvis to the list */ + VisualTable[NumVisuals] = xmvis; + NumVisuals++; + /* XXX minor hack, because XMesaCreateVisual doesn't support an + * aux buffers parameter. + */ + xmvis->mesa_visual.numAuxBuffers = numAuxBuffers; + } + return xmvis; +} + + +/** + * Return the default number of bits for the Z buffer. + * If defined, use the MESA_GLX_DEPTH_BITS env var value. + * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant. + * XXX probably do the same thing for stencil, accum, etc. + */ +static GLint +default_depth_bits(void) +{ + int zBits; + const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS"); + if (zEnv) + zBits = _mesa_atoi(zEnv); + else + zBits = DEFAULT_SOFTWARE_DEPTH_BITS; + return zBits; +} + +static GLint +default_alpha_bits(void) +{ + int aBits; + const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS"); + if (aEnv) + aBits = _mesa_atoi(aEnv); + else + aBits = 0; + return aBits; +} + +static GLint +default_accum_bits(void) +{ + return 16; +} + + + +/* + * Create a GLX visual from a regular XVisualInfo. + * This is called when Fake GLX is given an XVisualInfo which wasn't + * returned by glXChooseVisual. Since this is the first time we're + * considering this visual we'll take a guess at reasonable values + * for depth buffer size, stencil size, accum size, etc. + * This is the best we can do with a client-side emulation of GLX. + */ +static XMesaVisual +create_glx_visual( Display *dpy, XVisualInfo *visinfo ) +{ + int vislevel; + GLint zBits = 24; /*default_depth_bits();*/ + GLint accBits = default_accum_bits(); + GLboolean alphaFlag = default_alpha_bits() > 0; + + vislevel = level_of_visual( dpy, visinfo ); + if (vislevel) { + /* Configure this visual as a CI, single-buffered overlay */ + return save_glx_visual( dpy, visinfo, + GL_FALSE, /* rgb */ + GL_FALSE, /* alpha */ + GL_FALSE, /* double */ + GL_FALSE, /* stereo */ + 0, /* depth bits */ + 0, /* stencil bits */ + 0,0,0,0, /* accum bits */ + vislevel, /* level */ + 0 /* numAux */ + ); + } + else if (is_usable_visual( visinfo )) { + if (_mesa_getenv("MESA_GLX_FORCE_CI")) { + /* Configure this visual as a COLOR INDEX visual. */ + return save_glx_visual( dpy, visinfo, + GL_FALSE, /* rgb */ + GL_FALSE, /* alpha */ + GL_TRUE, /* double */ + GL_FALSE, /* stereo */ + zBits, + STENCIL_BITS, + 0, 0, 0, 0, /* accum bits */ + 0, /* level */ + 0 /* numAux */ + ); + } + else { + /* Configure this visual as RGB, double-buffered, depth-buffered. */ + /* This is surely wrong for some people's needs but what else */ + /* can be done? They should use glXChooseVisual(). */ + return save_glx_visual( dpy, visinfo, + GL_TRUE, /* rgb */ + alphaFlag, /* alpha */ + GL_TRUE, /* double */ + GL_FALSE, /* stereo */ + zBits, + STENCIL_BITS, + accBits, /* r */ + accBits, /* g */ + accBits, /* b */ + accBits, /* a */ + 0, /* level */ + 0 /* numAux */ + ); + } + } + else { + _mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n"); + return NULL; + } +} + + + +/* + * Find the GLX visual associated with an XVisualInfo. + */ +static XMesaVisual +find_glx_visual( Display *dpy, XVisualInfo *vinfo ) +{ + int i; + + /* try to match visual id */ + for (i=0;idisplay==dpy + && VisualTable[i]->visinfo->visualid == vinfo->visualid) { + return VisualTable[i]; + } + } + + /* if that fails, try to match pointers */ + for (i=0;idisplay==dpy && VisualTable[i]->vishandle==vinfo) { + return VisualTable[i]; + } + } + + return NULL; +} + + + +/** + * Return the transparent pixel value for a GLX visual. + * Input: glxvis - the glx_visual + * Return: a pixel value or -1 if no transparent pixel + */ +static int +transparent_pixel( XMesaVisual glxvis ) +{ + Display *dpy = glxvis->display; + XVisualInfo *vinfo = glxvis->visinfo; + OverlayInfo *overlay_info; + int numOverlaysPerScreen, i; + + overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); + if (!overlay_info) { + return -1; + } + + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *ov = overlay_info + i; + if (ov->overlay_visual == vinfo->visualid) { + /* found it! */ + if (ov->transparent_type == 0) { + /* type 0 indicates no transparency */ + XFree((void *) overlay_info); + return -1; + } + else { + /* ov->value is the transparent pixel */ + XFree((void *) overlay_info); + return ov->value; + } + } + } + + /* The visual ID was not found in the overlay list. */ + XFree((void *) overlay_info); + return -1; +} + + + +/** + * Try to get an X visual which matches the given arguments. + */ +static XVisualInfo * +get_visual( Display *dpy, int scr, unsigned int depth, int xclass ) +{ + XVisualInfo temp, *vis; + long mask; + int n; + unsigned int default_depth; + int default_class; + + mask = VisualScreenMask | VisualDepthMask | VisualClassMask; + temp.screen = scr; + temp.depth = depth; + temp.CLASS = xclass; + + default_depth = DefaultDepth(dpy,scr); + default_class = DefaultVisual(dpy,scr)->CLASS; + + if (depth==default_depth && xclass==default_class) { + /* try to get root window's visual */ + temp.visualid = DefaultVisual(dpy,scr)->visualid; + mask |= VisualIDMask; + } + + vis = XGetVisualInfo( dpy, mask, &temp, &n ); + + /* In case bits/pixel > 24, make sure color channels are still <=8 bits. + * An SGI Infinite Reality system, for example, can have 30bpp pixels: + * 10 bits per color channel. Mesa's limited to a max of 8 bits/channel. + */ + if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) { + if (_mesa_bitcount((GLuint) vis->red_mask ) <= 8 && + _mesa_bitcount((GLuint) vis->green_mask) <= 8 && + _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) { + return vis; + } + else { + XFree((void *) vis); + return NULL; + } + } + + return vis; +} + + + +/* + * Retrieve the value of the given environment variable and find + * the X visual which matches it. + * Input: dpy - the display + * screen - the screen number + * varname - the name of the environment variable + * Return: an XVisualInfo pointer to NULL if error. + */ +static XVisualInfo * +get_env_visual(Display *dpy, int scr, const char *varname) +{ + char value[100], type[100]; + int depth, xclass = -1; + XVisualInfo *vis; + + if (!_mesa_getenv( varname )) { + return NULL; + } + + _mesa_strncpy( value, _mesa_getenv(varname), 100 ); + value[99] = 0; + + sscanf( value, "%s %d", type, &depth ); + + if (_mesa_strcmp(type,"TrueColor")==0) xclass = TrueColor; + else if (_mesa_strcmp(type,"DirectColor")==0) xclass = DirectColor; + else if (_mesa_strcmp(type,"PseudoColor")==0) xclass = PseudoColor; + else if (_mesa_strcmp(type,"StaticColor")==0) xclass = StaticColor; + else if (_mesa_strcmp(type,"GrayScale")==0) xclass = GrayScale; + else if (_mesa_strcmp(type,"StaticGray")==0) xclass = StaticGray; + + if (xclass>-1 && depth>0) { + vis = get_visual( dpy, scr, depth, xclass ); + if (vis) { + return vis; + } + } + + _mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.", + type, depth); + + return NULL; +} + + + +/* + * Select an X visual which satisfies the RGBA/CI flag and minimum depth. + * Input: dpy, screen - X display and screen number + * rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode + * min_depth - minimum visual depth + * preferred_class - preferred GLX visual class or DONT_CARE + * Return: pointer to an XVisualInfo or NULL. + */ +static XVisualInfo * +choose_x_visual( Display *dpy, int screen, GLboolean rgba, int min_depth, + int preferred_class ) +{ + XVisualInfo *vis; + int xclass, visclass = 0; + int depth; + + if (rgba) { + Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True); + /* First see if the MESA_RGB_VISUAL env var is defined */ + vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" ); + if (vis) { + return vis; + } + /* Otherwise, search for a suitable visual */ + if (preferred_class==DONT_CARE) { + for (xclass=0;xclass<6;xclass++) { + switch (xclass) { + case 0: visclass = TrueColor; break; + case 1: visclass = DirectColor; break; + case 2: visclass = PseudoColor; break; + case 3: visclass = StaticColor; break; + case 4: visclass = GrayScale; break; + case 5: visclass = StaticGray; break; + } + if (min_depth==0) { + /* start with shallowest */ + for (depth=0;depth<=32;depth++) { + if (visclass==TrueColor && depth==8 && !hp_cr_maps) { + /* Special case: try to get 8-bit PseudoColor before */ + /* 8-bit TrueColor */ + vis = get_visual( dpy, screen, 8, PseudoColor ); + if (vis) { + return vis; + } + } + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + else { + /* start with deepest */ + for (depth=32;depth>=min_depth;depth--) { + if (visclass==TrueColor && depth==8 && !hp_cr_maps) { + /* Special case: try to get 8-bit PseudoColor before */ + /* 8-bit TrueColor */ + vis = get_visual( dpy, screen, 8, PseudoColor ); + if (vis) { + return vis; + } + } + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + } + } + else { + /* search for a specific visual class */ + switch (preferred_class) { + case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break; + case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break; + case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break; + case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break; + case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break; + case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break; + default: return NULL; + } + if (min_depth==0) { + /* start with shallowest */ + for (depth=0;depth<=32;depth++) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + else { + /* start with deepest */ + for (depth=32;depth>=min_depth;depth--) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + } + } + else { + /* First see if the MESA_CI_VISUAL env var is defined */ + vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" ); + if (vis) { + return vis; + } + /* Otherwise, search for a suitable visual, starting with shallowest */ + if (preferred_class==DONT_CARE) { + for (xclass=0;xclass<4;xclass++) { + switch (xclass) { + case 0: visclass = PseudoColor; break; + case 1: visclass = StaticColor; break; + case 2: visclass = GrayScale; break; + case 3: visclass = StaticGray; break; + } + /* try 8-bit up through 16-bit */ + for (depth=8;depth<=16;depth++) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + /* try min_depth up to 8-bit */ + for (depth=min_depth;depth<8;depth++) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + } + else { + /* search for a specific visual class */ + switch (preferred_class) { + case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break; + case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break; + case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break; + case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break; + case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break; + case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break; + default: return NULL; + } + /* try 8-bit up through 16-bit */ + for (depth=8;depth<=16;depth++) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + /* try min_depth up to 8-bit */ + for (depth=min_depth;depth<8;depth++) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + } + + /* didn't find a visual */ + return NULL; +} + + + +/* + * Find the deepest X over/underlay visual of at least min_depth. + * Input: dpy, screen - X display and screen number + * level - the over/underlay level + * trans_type - transparent pixel type: GLX_NONE_EXT, + * GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT, + * or DONT_CARE + * trans_value - transparent pixel value or DONT_CARE + * min_depth - minimum visual depth + * preferred_class - preferred GLX visual class or DONT_CARE + * Return: pointer to an XVisualInfo or NULL. + */ +static XVisualInfo * +choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag, + int level, int trans_type, int trans_value, + int min_depth, int preferred_class ) +{ + OverlayInfo *overlay_info; + int numOverlaysPerScreen; + int i; + XVisualInfo *deepvis; + int deepest; + + /*DEBUG int tt, tv; */ + + switch (preferred_class) { + case GLX_TRUE_COLOR_EXT: preferred_class = TrueColor; break; + case GLX_DIRECT_COLOR_EXT: preferred_class = DirectColor; break; + case GLX_PSEUDO_COLOR_EXT: preferred_class = PseudoColor; break; + case GLX_STATIC_COLOR_EXT: preferred_class = StaticColor; break; + case GLX_GRAY_SCALE_EXT: preferred_class = GrayScale; break; + case GLX_STATIC_GRAY_EXT: preferred_class = StaticGray; break; + default: preferred_class = DONT_CARE; + } + + overlay_info = GetOverlayInfo(dpy, scr, &numOverlaysPerScreen); + if (!overlay_info) { + return NULL; + } + + /* Search for the deepest overlay which satisifies all criteria. */ + deepest = min_depth; + deepvis = NULL; + + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *ov = overlay_info + i; + XVisualInfo *vislist, vistemplate; + int count; + + if (ov->layer!=level) { + /* failed overlay level criteria */ + continue; + } + if (!(trans_type==DONT_CARE + || (trans_type==GLX_TRANSPARENT_INDEX_EXT + && ov->transparent_type>0) + || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) { + /* failed transparent pixel type criteria */ + continue; + } + if (trans_value!=DONT_CARE && trans_value!=ov->value) { + /* failed transparent pixel value criteria */ + continue; + } + + /* get XVisualInfo and check the depth */ + vistemplate.visualid = ov->overlay_visual; + vistemplate.screen = scr; + vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask, + &vistemplate, &count ); + + if (count!=1) { + /* something went wrong */ + continue; + } + if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) { + /* wrong visual class */ + continue; + } + + /* if RGB was requested, make sure we have True/DirectColor */ + if (rgbFlag && vislist->CLASS != TrueColor + && vislist->CLASS != DirectColor) + continue; + + /* if CI was requested, make sure we have a color indexed visual */ + if (!rgbFlag + && (vislist->CLASS == TrueColor || vislist->CLASS == DirectColor)) + continue; + + if (deepvis==NULL || vislist->depth > deepest) { + /* YES! found a satisfactory visual */ + if (deepvis) { + XFree( deepvis ); + } + deepest = vislist->depth; + deepvis = vislist; + /* DEBUG tt = ov->transparent_type;*/ + /* DEBUG tv = ov->value; */ + } + } + +/*DEBUG + if (deepvis) { + printf("chose 0x%x: layer=%d depth=%d trans_type=%d trans_value=%d\n", + deepvis->visualid, level, deepvis->depth, tt, tv ); + } +*/ + return deepvis; +} + + +/**********************************************************************/ +/*** Display-related functions ***/ +/**********************************************************************/ + + +/** + * Free all XMesaVisuals which are associated with the given display. + */ +static void +destroy_visuals_on_display(Display *dpy) +{ + int i; + for (i = 0; i < NumVisuals; i++) { + if (VisualTable[i]->display == dpy) { + /* remove this visual */ + int j; + free(VisualTable[i]); + for (j = i; j < NumVisuals - 1; j++) + VisualTable[j] = VisualTable[j + 1]; + NumVisuals--; + } + } +} + + +/** + * Called from XCloseDisplay() to let us free our display-related data. + */ +static int +close_display_callback(Display *dpy, XExtCodes *codes) +{ + destroy_visuals_on_display(dpy); + xmesa_destroy_buffers_on_display(dpy); + return 0; +} + + +/** + * Look for the named extension on given display and return a pointer + * to the _XExtension data, or NULL if extension not found. + */ +static _XExtension * +lookup_extension(Display *dpy, const char *extName) +{ + _XExtension *ext; + for (ext = dpy->ext_procs; ext; ext = ext->next) { + if (ext->name && strcmp(ext->name, extName) == 0) { + return ext; + } + } + return NULL; +} + + +/** + * Whenever we're given a new Display pointer, call this function to + * register our close_display_callback function. + */ +static void +register_with_display(Display *dpy) +{ + const char *extName = "MesaGLX"; + _XExtension *ext; + + ext = lookup_extension(dpy, extName); + if (!ext) { + XExtCodes *c = XAddExtension(dpy); + ext = dpy->ext_procs; /* new extension is at head of list */ + assert(c->extension == ext->codes.extension); + ext->name = _mesa_strdup(extName); + ext->close_display = close_display_callback; + } +} + + +/**********************************************************************/ +/*** Begin Fake GLX API Functions ***/ +/**********************************************************************/ + + +/** + * Helper used by glXChooseVisual and glXChooseFBConfig. + * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for + * the later. + * In either case, the attribute list is terminated with the value 'None'. + */ +static XMesaVisual +choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) +{ + const GLboolean rgbModeDefault = fbConfig; + const int *parselist; + XVisualInfo *vis; + int min_ci = 0; + int min_red=0, min_green=0, min_blue=0; + GLboolean rgb_flag = rgbModeDefault; + GLboolean alpha_flag = GL_FALSE; + GLboolean double_flag = GL_FALSE; + GLboolean stereo_flag = GL_FALSE; + GLint depth_size = 0; + GLint stencil_size = 0; + GLint accumRedSize = 0; + GLint accumGreenSize = 0; + GLint accumBlueSize = 0; + GLint accumAlphaSize = 0; + int level = 0; + int visual_type = DONT_CARE; + int trans_type = DONT_CARE; + int trans_value = DONT_CARE; + GLint caveat = DONT_CARE; + XMesaVisual xmvis = NULL; + int desiredVisualID = -1; + int numAux = 0; + + parselist = list; + + while (*parselist) { + + switch (*parselist) { + case GLX_USE_GL: + if (fbConfig) { + /* invalid token */ + return NULL; + } + else { + /* skip */ + parselist++; + } + break; + case GLX_BUFFER_SIZE: + parselist++; + min_ci = *parselist++; + break; + case GLX_LEVEL: + parselist++; + level = *parselist++; + break; + case GLX_RGBA: + if (fbConfig) { + /* invalid token */ + return NULL; + } + else { + rgb_flag = GL_TRUE; + parselist++; + } + break; + case GLX_DOUBLEBUFFER: + parselist++; + if (fbConfig) { + double_flag = *parselist++; + } + else { + double_flag = GL_TRUE; + } + break; + case GLX_STEREO: + parselist++; + if (fbConfig) { + stereo_flag = *parselist++; + } + else { + stereo_flag = GL_TRUE; + } + break; + case GLX_AUX_BUFFERS: + parselist++; + numAux = *parselist++; + if (numAux > MAX_AUX_BUFFERS) + return NULL; + break; + case GLX_RED_SIZE: + parselist++; + min_red = *parselist++; + break; + case GLX_GREEN_SIZE: + parselist++; + min_green = *parselist++; + break; + case GLX_BLUE_SIZE: + parselist++; + min_blue = *parselist++; + break; + case GLX_ALPHA_SIZE: + parselist++; + { + GLint size = *parselist++; + alpha_flag = size ? GL_TRUE : GL_FALSE; + } + break; + case GLX_DEPTH_SIZE: + parselist++; + depth_size = *parselist++; + break; + case GLX_STENCIL_SIZE: + parselist++; + stencil_size = *parselist++; + break; + case GLX_ACCUM_RED_SIZE: + parselist++; + { + GLint size = *parselist++; + accumRedSize = MAX2( accumRedSize, size ); + } + break; + case GLX_ACCUM_GREEN_SIZE: + parselist++; + { + GLint size = *parselist++; + accumGreenSize = MAX2( accumGreenSize, size ); + } + break; + case GLX_ACCUM_BLUE_SIZE: + parselist++; + { + GLint size = *parselist++; + accumBlueSize = MAX2( accumBlueSize, size ); + } + break; + case GLX_ACCUM_ALPHA_SIZE: + parselist++; + { + GLint size = *parselist++; + accumAlphaSize = MAX2( accumAlphaSize, size ); + } + break; + + /* + * GLX_EXT_visual_info extension + */ + case GLX_X_VISUAL_TYPE_EXT: + parselist++; + visual_type = *parselist++; + break; + case GLX_TRANSPARENT_TYPE_EXT: + parselist++; + trans_type = *parselist++; + break; + case GLX_TRANSPARENT_INDEX_VALUE_EXT: + parselist++; + trans_value = *parselist++; + break; + case GLX_TRANSPARENT_RED_VALUE_EXT: + case GLX_TRANSPARENT_GREEN_VALUE_EXT: + case GLX_TRANSPARENT_BLUE_VALUE_EXT: + case GLX_TRANSPARENT_ALPHA_VALUE_EXT: + /* ignore */ + parselist++; + parselist++; + break; + + /* + * GLX_EXT_visual_info extension + */ + case GLX_VISUAL_CAVEAT_EXT: + parselist++; + caveat = *parselist++; /* ignored for now */ + break; + + /* + * GLX_ARB_multisample + */ + case GLX_SAMPLE_BUFFERS_ARB: + /* ms not supported */ + return NULL; + case GLX_SAMPLES_ARB: + /* ms not supported */ + return NULL; + + /* + * FBConfig attribs. + */ + case GLX_RENDER_TYPE: + if (!fbConfig) + return NULL; + parselist++; + if (*parselist == GLX_RGBA_BIT) { + rgb_flag = GL_TRUE; + } + else if (*parselist == GLX_COLOR_INDEX_BIT) { + rgb_flag = GL_FALSE; + } + else if (*parselist == 0) { + rgb_flag = GL_TRUE; + } + parselist++; + break; + case GLX_DRAWABLE_TYPE: + if (!fbConfig) + return NULL; + parselist++; + if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) { + return NULL; /* bad bit */ + } + parselist++; + break; + case GLX_FBCONFIG_ID: + if (!fbConfig) + return NULL; + parselist++; + desiredVisualID = *parselist++; + break; + case GLX_X_RENDERABLE: + if (!fbConfig) + return NULL; + parselist += 2; + /* ignore */ + break; + +#ifdef GLX_EXT_texture_from_pixmap + case GLX_BIND_TO_TEXTURE_RGB_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + parselist++; + if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT | + GLX_TEXTURE_2D_BIT_EXT | + GLX_TEXTURE_RECTANGLE_BIT_EXT)) { + /* invalid bit */ + return NULL; + } + break; + case GLX_Y_INVERTED_EXT: + parselist++; /*skip*/ + break; +#endif + + case None: + /* end of list */ + break; + + default: + /* undefined attribute */ + _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()", + *parselist); + return NULL; + } + } + + (void) caveat; + + /* + * Since we're only simulating the GLX extension this function will never + * find any real GL visuals. Instead, all we can do is try to find an RGB + * or CI visual of appropriate depth. Other requested attributes such as + * double buffering, depth buffer, etc. will be associated with the X + * visual and stored in the VisualTable[]. + */ + if (desiredVisualID != -1) { + /* try to get a specific visual, by visualID */ + XVisualInfo temp; + int n; + temp.visualid = desiredVisualID; + temp.screen = screen; + vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n); + if (vis) { + /* give the visual some useful GLX attributes */ + double_flag = GL_TRUE; + if (vis->depth > 8) + rgb_flag = GL_TRUE; + depth_size = 24; /*default_depth_bits();*/ + stencil_size = STENCIL_BITS; + /* XXX accum??? */ + } + } + else if (level==0) { + /* normal color planes */ + if (rgb_flag) { + /* Get an RGB visual */ + int min_rgb = min_red + min_green + min_blue; + if (min_rgb>1 && min_rgb<8) { + /* a special case to be sure we can get a monochrome visual */ + min_rgb = 1; + } + vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type ); + } + else { + /* Get a color index visual */ + vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type ); + accumRedSize = accumGreenSize = accumBlueSize = accumAlphaSize = 0; + } + } + else { + /* over/underlay planes */ + if (rgb_flag) { + /* rgba overlay */ + int min_rgb = min_red + min_green + min_blue; + if (min_rgb>1 && min_rgb<8) { + /* a special case to be sure we can get a monochrome visual */ + min_rgb = 1; + } + vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level, + trans_type, trans_value, min_rgb, visual_type ); + } + else { + /* color index overlay */ + vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level, + trans_type, trans_value, min_ci, visual_type ); + } + } + + if (vis) { + /* Note: we're not exactly obeying the glXChooseVisual rules here. + * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the + * largest depth buffer size, which is 32bits/value. Instead, we + * return 16 to maintain performance with earlier versions of Mesa. + */ + if (stencil_size > 0) + depth_size = 24; /* if Z and stencil, always use 24+8 format */ + else if (depth_size > 24) + depth_size = 32; + else if (depth_size > 16) + depth_size = 24; + else if (depth_size > 0) { + depth_size = default_depth_bits(); + } + + if (!alpha_flag) { + alpha_flag = default_alpha_bits() > 0; + } + + /* we only support one size of stencil and accum buffers. */ + if (stencil_size > 0) + stencil_size = STENCIL_BITS; + if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 || + accumAlphaSize > 0) { + accumRedSize = + accumGreenSize = + accumBlueSize = default_accum_bits(); + accumAlphaSize = alpha_flag ? accumRedSize : 0; + } + + xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag, + stereo_flag, depth_size, stencil_size, + accumRedSize, accumGreenSize, + accumBlueSize, accumAlphaSize, level, numAux ); + } + + return xmvis; +} + + +static XVisualInfo * +Fake_glXChooseVisual( Display *dpy, int screen, int *list ) +{ + XMesaVisual xmvis; + + /* register ourselves as an extension on this display */ + register_with_display(dpy); + + xmvis = choose_visual(dpy, screen, list, GL_FALSE); + if (xmvis) { +#if 0 + return xmvis->vishandle; +#else + /* create a new vishandle - the cached one may be stale */ + xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); + if (xmvis->vishandle) { + _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); + } + return xmvis->vishandle; +#endif + } + else + return NULL; +} + + +static GLXContext +Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, + GLXContext share_list, Bool direct ) +{ + XMesaVisual xmvis; + struct fake_glx_context *glxCtx; + struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list; + + if (!dpy || !visinfo) + return 0; + + glxCtx = CALLOC_STRUCT(fake_glx_context); + if (!glxCtx) + return 0; + + /* deallocate unused windows/buffers */ +#if 0 + XMesaGarbageCollect(); +#endif + + xmvis = find_glx_visual( dpy, visinfo ); + if (!xmvis) { + /* This visual wasn't found with glXChooseVisual() */ + xmvis = create_glx_visual( dpy, visinfo ); + if (!xmvis) { + /* unusable visual */ + _mesa_free(glxCtx); + return NULL; + } + } + + glxCtx->xmesaContext = XMesaCreateContext(xmvis, + shareCtx ? shareCtx->xmesaContext : NULL); + if (!glxCtx->xmesaContext) { + _mesa_free(glxCtx); + return NULL; + } + + glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.currentDpy = dpy; + glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ + + assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); + + return (GLXContext) glxCtx; +} + + +/* XXX these may have to be removed due to thread-safety issues. */ +static GLXContext MakeCurrent_PrevContext = 0; +static GLXDrawable MakeCurrent_PrevDrawable = 0; +static GLXDrawable MakeCurrent_PrevReadable = 0; +static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0; +static XMesaBuffer MakeCurrent_PrevReadBuffer = 0; + + +/* GLX 1.3 and later */ +static Bool +Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, + GLXDrawable read, GLXContext ctx ) +{ + struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + + if (ctx && draw && read) { + XMesaBuffer drawBuffer, readBuffer; + XMesaContext xmctx = glxCtx->xmesaContext; + + /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */ + if (ctx == MakeCurrent_PrevContext + && draw == MakeCurrent_PrevDrawable) { + drawBuffer = MakeCurrent_PrevDrawBuffer; + } + else { + drawBuffer = XMesaFindBuffer( dpy, draw ); + } + if (!drawBuffer) { + /* drawable must be a new window! */ + drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw ); + if (!drawBuffer) { + /* Out of memory, or context/drawable depth mismatch */ + return False; + } +#ifdef FX + FXcreateContext( xmctx->xm_visual, draw, xmctx, drawBuffer ); +#endif + } + + /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */ + if (ctx == MakeCurrent_PrevContext + && read == MakeCurrent_PrevReadable) { + readBuffer = MakeCurrent_PrevReadBuffer; + } + else { + readBuffer = XMesaFindBuffer( dpy, read ); + } + if (!readBuffer) { + /* drawable must be a new window! */ + readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read ); + if (!readBuffer) { + /* Out of memory, or context/drawable depth mismatch */ + return False; + } +#ifdef FX + FXcreateContext( xmctx->xm_visual, read, xmctx, readBuffer ); +#endif + } + + MakeCurrent_PrevContext = ctx; + MakeCurrent_PrevDrawable = draw; + MakeCurrent_PrevReadable = read; + MakeCurrent_PrevDrawBuffer = drawBuffer; + MakeCurrent_PrevReadBuffer = readBuffer; + + /* Now make current! */ + if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) { + ((__GLXcontext *) ctx)->currentDpy = dpy; + ((__GLXcontext *) ctx)->currentDrawable = draw; + ((__GLXcontext *) ctx)->currentReadable = read; + return True; + } + else { + return False; + } + } + else if (!ctx && !draw && !read) { + /* release current context w/out assigning new one. */ + XMesaMakeCurrent( NULL, NULL ); + MakeCurrent_PrevContext = 0; + MakeCurrent_PrevDrawable = 0; + MakeCurrent_PrevReadable = 0; + MakeCurrent_PrevDrawBuffer = 0; + MakeCurrent_PrevReadBuffer = 0; + return True; + } + else { + /* The args must either all be non-zero or all zero. + * This is an error. + */ + return False; + } +} + + +static Bool +Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) +{ + return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx ); +} + + +static GLXPixmap +Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) +{ + XMesaVisual v; + XMesaBuffer b; + + v = find_glx_visual( dpy, visinfo ); + if (!v) { + v = create_glx_visual( dpy, visinfo ); + if (!v) { + /* unusable visual */ + return 0; + } + } + + b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); + if (!b) { + return 0; + } + return b->drawable; +} + + +/*** GLX_MESA_pixmap_colormap ***/ + +static GLXPixmap +Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, + Pixmap pixmap, Colormap cmap ) +{ + XMesaVisual v; + XMesaBuffer b; + + v = find_glx_visual( dpy, visinfo ); + if (!v) { + v = create_glx_visual( dpy, visinfo ); + if (!v) { + /* unusable visual */ + return 0; + } + } + + b = XMesaCreatePixmapBuffer( v, pixmap, cmap ); + if (!b) { + return 0; + } + return b->drawable; +} + + +static void +Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, pixmap); + if (b) { + XMesaDestroyBuffer(b); + } + else if (_mesa_getenv("MESA_DEBUG")) { + _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n"); + } +} + + +static void +Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, + unsigned long mask ) +{ + struct fake_glx_context *fakeSrc = (struct fake_glx_context *) src; + struct fake_glx_context *fakeDst = (struct fake_glx_context *) dst; + XMesaContext xm_src = fakeSrc->xmesaContext; + XMesaContext xm_dst = fakeDst->xmesaContext; + (void) dpy; + if (MakeCurrent_PrevContext == src) { + _mesa_Flush(); + } + st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask ); +} + + +static Bool +Fake_glXQueryExtension( Display *dpy, int *errorb, int *event ) +{ + /* Mesa's GLX isn't really an X extension but we try to act like one. */ + (void) dpy; + (void) errorb; + (void) event; + return True; +} + + +extern void _kw_ungrab_all( Display *dpy ); +void _kw_ungrab_all( Display *dpy ) +{ + XUngrabPointer( dpy, CurrentTime ); + XUngrabKeyboard( dpy, CurrentTime ); +} + + +static void +Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) +{ + struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + (void) dpy; + MakeCurrent_PrevContext = 0; + MakeCurrent_PrevDrawable = 0; + MakeCurrent_PrevReadable = 0; + MakeCurrent_PrevDrawBuffer = 0; + MakeCurrent_PrevReadBuffer = 0; + XMesaDestroyContext( glxCtx->xmesaContext ); + XMesaGarbageCollect(); + _mesa_free(glxCtx); +} + + +static Bool +Fake_glXIsDirect( Display *dpy, GLXContext ctx ) +{ + (void) dpy; + (void) ctx; + return False; +} + + + +static void +Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) +{ + XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); + + if (buffer) { + XMesaSwapBuffers(buffer); + } + else if (_mesa_getenv("MESA_DEBUG")) { + _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n", + (int) drawable); + } +} + + + +/*** GLX_MESA_copy_sub_buffer ***/ + +static void +Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, + int x, int y, int width, int height ) +{ + XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); + if (buffer) { + XMesaCopySubBuffer(buffer, x, y, width, height); + } + else if (_mesa_getenv("MESA_DEBUG")) { + _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n"); + } +} + + +static Bool +Fake_glXQueryVersion( Display *dpy, int *maj, int *min ) +{ + (void) dpy; + /* Return GLX version, not Mesa version */ + assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION); + *maj = CLIENT_MAJOR_VERSION; + *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION ); + return True; +} + + +/* + * Query the GLX attributes of the given XVisualInfo. + */ +static int +get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) +{ + ASSERT(xmvis); + switch(attrib) { + case GLX_USE_GL: + if (fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = (int) True; + return 0; + case GLX_BUFFER_SIZE: + *value = xmvis->visinfo->depth; + return 0; + case GLX_LEVEL: + *value = xmvis->mesa_visual.level; + return 0; + case GLX_RGBA: + if (fbconfig) + return GLX_BAD_ATTRIBUTE; + if (xmvis->mesa_visual.rgbMode) { + *value = True; + } + else { + *value = False; + } + return 0; + case GLX_DOUBLEBUFFER: + *value = (int) xmvis->mesa_visual.doubleBufferMode; + return 0; + case GLX_STEREO: + *value = (int) xmvis->mesa_visual.stereoMode; + return 0; + case GLX_AUX_BUFFERS: + *value = xmvis->mesa_visual.numAuxBuffers; + return 0; + case GLX_RED_SIZE: + *value = xmvis->mesa_visual.redBits; + return 0; + case GLX_GREEN_SIZE: + *value = xmvis->mesa_visual.greenBits; + return 0; + case GLX_BLUE_SIZE: + *value = xmvis->mesa_visual.blueBits; + return 0; + case GLX_ALPHA_SIZE: + *value = xmvis->mesa_visual.alphaBits; + return 0; + case GLX_DEPTH_SIZE: + *value = xmvis->mesa_visual.depthBits; + return 0; + case GLX_STENCIL_SIZE: + *value = xmvis->mesa_visual.stencilBits; + return 0; + case GLX_ACCUM_RED_SIZE: + *value = xmvis->mesa_visual.accumRedBits; + return 0; + case GLX_ACCUM_GREEN_SIZE: + *value = xmvis->mesa_visual.accumGreenBits; + return 0; + case GLX_ACCUM_BLUE_SIZE: + *value = xmvis->mesa_visual.accumBlueBits; + return 0; + case GLX_ACCUM_ALPHA_SIZE: + *value = xmvis->mesa_visual.accumAlphaBits; + return 0; + + /* + * GLX_EXT_visual_info extension + */ + case GLX_X_VISUAL_TYPE_EXT: + switch (xmvis->visinfo->CLASS) { + case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0; + case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0; + case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0; + case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0; + case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0; + case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0; + } + return 0; + case GLX_TRANSPARENT_TYPE_EXT: + if (xmvis->mesa_visual.level==0) { + /* normal planes */ + *value = GLX_NONE_EXT; + } + else if (xmvis->mesa_visual.level>0) { + /* overlay */ + if (xmvis->mesa_visual.rgbMode) { + *value = GLX_TRANSPARENT_RGB_EXT; + } + else { + *value = GLX_TRANSPARENT_INDEX_EXT; + } + } + else if (xmvis->mesa_visual.level<0) { + /* underlay */ + *value = GLX_NONE_EXT; + } + return 0; + case GLX_TRANSPARENT_INDEX_VALUE_EXT: + { + int pixel = transparent_pixel( xmvis ); + if (pixel>=0) { + *value = pixel; + } + /* else undefined */ + } + return 0; + case GLX_TRANSPARENT_RED_VALUE_EXT: + /* undefined */ + return 0; + case GLX_TRANSPARENT_GREEN_VALUE_EXT: + /* undefined */ + return 0; + case GLX_TRANSPARENT_BLUE_VALUE_EXT: + /* undefined */ + return 0; + case GLX_TRANSPARENT_ALPHA_VALUE_EXT: + /* undefined */ + return 0; + + /* + * GLX_EXT_visual_info extension + */ + case GLX_VISUAL_CAVEAT_EXT: + /* test for zero, just in case */ + if (xmvis->mesa_visual.visualRating > 0) + *value = xmvis->mesa_visual.visualRating; + else + *value = GLX_NONE_EXT; + return 0; + + /* + * GLX_ARB_multisample + */ + case GLX_SAMPLE_BUFFERS_ARB: + *value = 0; + return 0; + case GLX_SAMPLES_ARB: + *value = 0; + return 0; + + /* + * For FBConfigs: + */ + case GLX_SCREEN_EXT: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = xmvis->visinfo->screen; + break; + case GLX_DRAWABLE_TYPE: /*SGIX too */ + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; + break; + case GLX_RENDER_TYPE_SGIX: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + if (xmvis->mesa_visual.rgbMode) + *value = GLX_RGBA_BIT; + else + *value = GLX_COLOR_INDEX_BIT; + break; + case GLX_X_RENDERABLE_SGIX: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = True; /* XXX really? */ + break; + case GLX_FBCONFIG_ID_SGIX: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = xmvis->visinfo->visualid; + break; + case GLX_MAX_PBUFFER_WIDTH: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + /* XXX or MAX_WIDTH? */ + *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen); + break; + case GLX_MAX_PBUFFER_HEIGHT: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen); + break; + case GLX_MAX_PBUFFER_PIXELS: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) * + DisplayHeight(xmvis->display, xmvis->visinfo->screen); + break; + case GLX_VISUAL_ID: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = xmvis->visinfo->visualid; + break; + +#ifdef GLX_EXT_texture_from_pixmap + case GLX_BIND_TO_TEXTURE_RGB_EXT: + *value = True; /*XXX*/ + break; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + /* XXX review */ + *value = xmvis->mesa_visual.alphaBits > 0 ? True : False; + break; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + *value = True; /*XXX*/ + break; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + *value = (GLX_TEXTURE_1D_BIT_EXT | + GLX_TEXTURE_2D_BIT_EXT | + GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/ + break; + case GLX_Y_INVERTED_EXT: + *value = True; /*XXX*/ + break; +#endif + + default: + return GLX_BAD_ATTRIBUTE; + } + return Success; +} + + +static int +Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, + int attrib, int *value ) +{ + XMesaVisual xmvis; + int k; + if (!dpy || !visinfo) + return GLX_BAD_ATTRIBUTE; + + xmvis = find_glx_visual( dpy, visinfo ); + if (!xmvis) { + /* this visual wasn't obtained with glXChooseVisual */ + xmvis = create_glx_visual( dpy, visinfo ); + if (!xmvis) { + /* this visual can't be used for GL rendering */ + if (attrib==GLX_USE_GL) { + *value = (int) False; + return 0; + } + else { + return GLX_BAD_VISUAL; + } + } + } + + k = get_config(xmvis, attrib, value, GL_FALSE); + return k; +} + + +static void +Fake_glXWaitGL( void ) +{ + XMesaContext xmesa = XMesaGetCurrentContext(); + XMesaFlush( xmesa ); +} + + + +static void +Fake_glXWaitX( void ) +{ + XMesaContext xmesa = XMesaGetCurrentContext(); + XMesaFlush( xmesa ); +} + + +static const char * +get_extensions( void ) +{ +#ifdef FX + const char *fx = _mesa_getenv("MESA_GLX_FX"); + if (fx && fx[0] != 'd') { + return EXTENSIONS; + } +#endif + return EXTENSIONS + 23; /* skip "GLX_MESA_set_3dfx_mode" */ +} + + + +/* GLX 1.1 and later */ +static const char * +Fake_glXQueryExtensionsString( Display *dpy, int screen ) +{ + (void) dpy; + (void) screen; + return get_extensions(); +} + + + +/* GLX 1.1 and later */ +static const char * +Fake_glXQueryServerString( Display *dpy, int screen, int name ) +{ + static char version[1000]; + _mesa_sprintf(version, "%d.%d %s", + SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION); + + (void) dpy; + (void) screen; + + switch (name) { + case GLX_EXTENSIONS: + return get_extensions(); + case GLX_VENDOR: + return VENDOR; + case GLX_VERSION: + return version; + default: + return NULL; + } +} + + + +/* GLX 1.1 and later */ +static const char * +Fake_glXGetClientString( Display *dpy, int name ) +{ + static char version[1000]; + _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, + CLIENT_MINOR_VERSION, MESA_GLX_VERSION); + + (void) dpy; + + switch (name) { + case GLX_EXTENSIONS: + return get_extensions(); + case GLX_VENDOR: + return VENDOR; + case GLX_VERSION: + return version; + default: + return NULL; + } +} + + + +/* + * GLX 1.3 and later + */ + + +static int +Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, + int attribute, int *value ) +{ + XMesaVisual v = (XMesaVisual) config; + (void) dpy; + (void) config; + + if (!dpy || !config || !value) + return -1; + + return get_config(v, attribute, value, GL_TRUE); +} + + +static GLXFBConfig * +Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) +{ + XVisualInfo *visuals, visTemplate; + const long visMask = VisualScreenMask; + int i; + + /* Get list of all X visuals */ + visTemplate.screen = screen; + visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements); + if (*nelements > 0) { + XMesaVisual *results; + results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual)); + if (!results) { + *nelements = 0; + return NULL; + } + for (i = 0; i < *nelements; i++) { + results[i] = create_glx_visual(dpy, visuals + i); + } + return (GLXFBConfig *) results; + } + return NULL; +} + + +static GLXFBConfig * +Fake_glXChooseFBConfig( Display *dpy, int screen, + const int *attribList, int *nitems ) +{ + XMesaVisual xmvis; + + if (!attribList || !attribList[0]) { + /* return list of all configs (per GLX_SGIX_fbconfig spec) */ + return Fake_glXGetFBConfigs(dpy, screen, nitems); + } + + xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); + if (xmvis) { + GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual)); + if (!config) { + *nitems = 0; + return NULL; + } + *nitems = 1; + config[0] = (GLXFBConfig) xmvis; + return (GLXFBConfig *) config; + } + else { + *nitems = 0; + return NULL; + } +} + + +static XVisualInfo * +Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) +{ + if (dpy && config) { + XMesaVisual xmvis = (XMesaVisual) config; +#if 0 + return xmvis->vishandle; +#else + /* create a new vishandle - the cached one may be stale */ + xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); + if (xmvis->vishandle) { + _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); + } + return xmvis->vishandle; +#endif + } + else { + return NULL; + } +} + + +static GLXWindow +Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, + const int *attribList ) +{ + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf; + if (!xmvis) + return 0; + + xmbuf = XMesaCreateWindowBuffer(xmvis, win); + if (!xmbuf) + return 0; + +#ifdef FX + /* XXX this will segfault if actually called */ + FXcreateContext(xmvis, win, NULL, xmbuf); +#endif + + (void) dpy; + (void) attribList; /* Ignored in GLX 1.3 */ + + return win; /* A hack for now */ +} + + +static void +Fake_glXDestroyWindow( Display *dpy, GLXWindow window ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable) window); + if (b) + XMesaDestroyBuffer(b); + /* don't destroy X window */ +} + + +/* XXX untested */ +static GLXPixmap +Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, + const int *attribList ) +{ + XMesaVisual v = (XMesaVisual) config; + XMesaBuffer b; + const int *attr; + int target = 0, format = 0, mipmap = 0; + int value; + + if (!dpy || !config || !pixmap) + return 0; + + for (attr = attribList; *attr; attr++) { + switch (*attr) { + case GLX_TEXTURE_FORMAT_EXT: + attr++; + switch (*attr) { + case GLX_TEXTURE_FORMAT_NONE_EXT: + case GLX_TEXTURE_FORMAT_RGB_EXT: + case GLX_TEXTURE_FORMAT_RGBA_EXT: + format = *attr; + break; + default: + /* error */ + return 0; + } + break; + case GLX_TEXTURE_TARGET_EXT: + attr++; + switch (*attr) { + case GLX_TEXTURE_1D_EXT: + case GLX_TEXTURE_2D_EXT: + case GLX_TEXTURE_RECTANGLE_EXT: + target = *attr; + break; + default: + /* error */ + return 0; + } + break; + case GLX_MIPMAP_TEXTURE_EXT: + attr++; + if (*attr) + mipmap = 1; + break; + default: + /* error */ + return 0; + } + } + + if (format == GLX_TEXTURE_FORMAT_RGB_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + if (mipmap) { + if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + if (target == GLX_TEXTURE_1D_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + else if (target == GLX_TEXTURE_2D_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + if (target == GLX_TEXTURE_RECTANGLE_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + + if (format || target || mipmap) { + /* texture from pixmap */ + b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap); + } + else { + b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); + } + if (!b) { + return 0; + } + + return pixmap; +} + + +static void +Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable)pixmap); + if (b) + XMesaDestroyBuffer(b); + /* don't destroy X pixmap */ +} + + +static GLXPbuffer +Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, + const int *attribList ) +{ + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf; + const int *attrib; + int width = 0, height = 0; + GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; + + (void) dpy; + + for (attrib = attribList; *attrib; attrib++) { + switch (*attrib) { + case GLX_PBUFFER_WIDTH: + attrib++; + width = *attrib; + break; + case GLX_PBUFFER_HEIGHT: + attrib++; + height = *attrib; + break; + case GLX_PRESERVED_CONTENTS: + attrib++; + preserveContents = *attrib; /* ignored */ + break; + case GLX_LARGEST_PBUFFER: + attrib++; + useLargest = *attrib; /* ignored */ + break; + default: + return 0; + } + } + + /* not used at this time */ + (void) useLargest; + (void) preserveContents; + + if (width == 0 || height == 0) + return 0; + + xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); + /* A GLXPbuffer handle must be an X Drawable because that's what + * glXMakeCurrent takes. + */ + if (xmbuf) + return (GLXPbuffer) xmbuf->drawable; + else + return 0; +} + + +static void +Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, pbuf); + if (b) { + XMesaDestroyBuffer(b); + } +} + + +static void +Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, + unsigned int *value ) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw); + if (!xmbuf) + return; + + switch (attribute) { + case GLX_WIDTH: + *value = xmesa_buffer_width(xmbuf); + break; + case GLX_HEIGHT: + *value = xmesa_buffer_width(xmbuf); + break; + case GLX_PRESERVED_CONTENTS: + *value = True; + break; + case GLX_LARGEST_PBUFFER: + *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf); + break; + case GLX_FBCONFIG_ID: + *value = xmbuf->xm_visual->visinfo->visualid; + return; +#ifdef GLX_EXT_texture_from_pixmap + case GLX_TEXTURE_FORMAT_EXT: + *value = xmbuf->TextureFormat; + break; + case GLX_TEXTURE_TARGET_EXT: + *value = xmbuf->TextureTarget; + break; + case GLX_MIPMAP_TEXTURE_EXT: + *value = xmbuf->TextureMipmap; + break; +#endif + + default: + return; /* raise BadValue error */ + } +} + + +static GLXContext +Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, + int renderType, GLXContext shareList, Bool direct ) +{ + struct fake_glx_context *glxCtx; + struct fake_glx_context *shareCtx = (struct fake_glx_context *) shareList; + XMesaVisual xmvis = (XMesaVisual) config; + + if (!dpy || !config || + (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE)) + return 0; + + glxCtx = CALLOC_STRUCT(fake_glx_context); + if (!glxCtx) + return 0; + + /* deallocate unused windows/buffers */ + XMesaGarbageCollect(); + + glxCtx->xmesaContext = XMesaCreateContext(xmvis, + shareCtx ? shareCtx->xmesaContext : NULL); + if (!glxCtx->xmesaContext) { + _mesa_free(glxCtx); + return NULL; + } + + glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.currentDpy = dpy; + glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ + + assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); + + return (GLXContext) glxCtx; +} + + +static int +Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) +{ + struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + XMesaContext xmctx = glxCtx->xmesaContext; + + (void) dpy; + (void) ctx; + + switch (attribute) { + case GLX_FBCONFIG_ID: + *value = xmctx->xm_visual->visinfo->visualid; + break; + case GLX_RENDER_TYPE: + if (xmctx->xm_visual->mesa_visual.rgbMode) + *value = GLX_RGBA_BIT; + else + *value = GLX_COLOR_INDEX_BIT; + break; + case GLX_SCREEN: + *value = 0; + return Success; + default: + return GLX_BAD_ATTRIBUTE; + } + return 0; +} + + +static void +Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); + if (xmbuf) + xmbuf->selectedEvents = mask; +} + + +static void +Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, + unsigned long *mask ) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); + if (xmbuf) + *mask = xmbuf->selectedEvents; + else + *mask = 0; +} + + + +/*** GLX_SGI_swap_control ***/ + +static int +Fake_glXSwapIntervalSGI(int interval) +{ + (void) interval; + return 0; +} + + + +/*** GLX_SGI_video_sync ***/ + +static unsigned int FrameCounter = 0; + +static int +Fake_glXGetVideoSyncSGI(unsigned int *count) +{ + /* this is a bogus implementation */ + *count = FrameCounter++; + return 0; +} + +static int +Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) +{ + if (divisor <= 0 || remainder < 0) + return GLX_BAD_VALUE; + /* this is a bogus implementation */ + FrameCounter++; + while (FrameCounter % divisor != remainder) + FrameCounter++; + *count = FrameCounter; + return 0; +} + + + +/*** GLX_SGI_make_current_read ***/ + +static Bool +Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) +{ + return Fake_glXMakeContextCurrent( dpy, draw, read, ctx ); +} + +/* not used +static GLXDrawable +Fake_glXGetCurrentReadDrawableSGI(void) +{ + return 0; +} +*/ + + +/*** GLX_SGIX_video_source ***/ +#if defined(_VL_H) + +static GLXVideoSourceSGIX +Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) +{ + (void) dpy; + (void) screen; + (void) server; + (void) path; + (void) nodeClass; + (void) drainNode; + return 0; +} + +static void +Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) +{ + (void) dpy; + (void) src; +} + +#endif + + +/*** GLX_EXT_import_context ***/ + +static void +Fake_glXFreeContextEXT(Display *dpy, GLXContext context) +{ + (void) dpy; + (void) context; +} + +static GLXContextID +Fake_glXGetContextIDEXT(const GLXContext context) +{ + (void) context; + return 0; +} + +static GLXContext +Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID) +{ + (void) dpy; + (void) contextID; + return 0; +} + +static int +Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value) +{ + (void) dpy; + (void) context; + (void) attribute; + (void) value; + return 0; +} + + + +/*** GLX_SGIX_fbconfig ***/ + +static int +Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) +{ + return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value); +} + +static GLXFBConfigSGIX * +Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) +{ + return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements); +} + + +static GLXPixmap +Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) +{ + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0); + return xmbuf->drawable; /* need to return an X ID */ +} + + +static GLXContext +Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) +{ + XMesaVisual xmvis = (XMesaVisual) config; + struct fake_glx_context *glxCtx; + struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list; + + glxCtx = CALLOC_STRUCT(fake_glx_context); + if (!glxCtx) + return 0; + + /* deallocate unused windows/buffers */ + XMesaGarbageCollect(); + + glxCtx->xmesaContext = XMesaCreateContext(xmvis, + shareCtx ? shareCtx->xmesaContext : NULL); + if (!glxCtx->xmesaContext) { + _mesa_free(glxCtx); + return NULL; + } + + glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.currentDpy = dpy; + glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ + + assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); + + return (GLXContext) glxCtx; +} + + +static XVisualInfo * +Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) +{ + return Fake_glXGetVisualFromFBConfig(dpy, config); +} + + +static GLXFBConfigSGIX +Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) +{ + XMesaVisual xmvis = find_glx_visual(dpy, vis); + if (!xmvis) { + /* This visual wasn't found with glXChooseVisual() */ + xmvis = create_glx_visual(dpy, vis); + } + + return (GLXFBConfigSGIX) xmvis; +} + + + +/*** GLX_SGIX_pbuffer ***/ + +static GLXPbufferSGIX +Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, + unsigned int width, unsigned int height, + int *attribList) +{ + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf; + const int *attrib; + GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; + + (void) dpy; + + for (attrib = attribList; attrib && *attrib; attrib++) { + switch (*attrib) { + case GLX_PRESERVED_CONTENTS_SGIX: + attrib++; + preserveContents = *attrib; /* ignored */ + break; + case GLX_LARGEST_PBUFFER_SGIX: + attrib++; + useLargest = *attrib; /* ignored */ + break; + default: + return 0; + } + } + + /* not used at this time */ + (void) useLargest; + (void) preserveContents; + + xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); + /* A GLXPbuffer handle must be an X Drawable because that's what + * glXMakeCurrent takes. + */ + return (GLXPbuffer) xmbuf->drawable; +} + + +static void +Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); + if (xmbuf) { + XMesaDestroyBuffer(xmbuf); + } +} + + +static int +Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) +{ + const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); + + if (!xmbuf) { + /* Generate GLXBadPbufferSGIX for bad pbuffer */ + return 0; + } + + switch (attribute) { + case GLX_PRESERVED_CONTENTS_SGIX: + *value = True; + break; + case GLX_LARGEST_PBUFFER_SGIX: + *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf); + break; + case GLX_WIDTH_SGIX: + *value = xmesa_buffer_width(xmbuf); + break; + case GLX_HEIGHT_SGIX: + *value = xmesa_buffer_height(xmbuf); + break; + case GLX_EVENT_MASK_SGIX: + *value = 0; /* XXX might be wrong */ + break; + default: + *value = 0; + } + return 0; +} + + +static void +Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); + if (xmbuf) { + /* Note: we'll never generate clobber events */ + xmbuf->selectedEvents = mask; + } +} + + +static void +Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); + if (xmbuf) { + *mask = xmbuf->selectedEvents; + } + else { + *mask = 0; + } +} + + + +/*** GLX_SGI_cushion ***/ + +static void +Fake_glXCushionSGI(Display *dpy, Window win, float cushion) +{ + (void) dpy; + (void) win; + (void) cushion; +} + + + +/*** GLX_SGIX_video_resize ***/ + +static int +Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) window; + return 0; +} + +static int +Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) x; + (void) y; + (void) w; + (void) h; + return 0; +} + +static int +Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) x; + (void) y; + (void) w; + (void) h; + return 0; +} + +static int +Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) dx; + (void) dy; + (void) dw; + (void) dh; + return 0; +} + +static int +Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) synctype; + return 0; +} + + + +/*** GLX_SGIX_dmbuffer **/ + +#if defined(_DM_BUFFER_H_) +static Bool +Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) +{ + (void) dpy; + (void) pbuffer; + (void) params; + (void) dmbuffer; + return False; +} +#endif + + +/*** GLX_SGIX_swap_group ***/ + +static void +Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) +{ + (void) dpy; + (void) drawable; + (void) member; +} + + + +/*** GLX_SGIX_swap_barrier ***/ + +static void +Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) +{ + (void) dpy; + (void) drawable; + (void) barrier; +} + +static Bool +Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) +{ + (void) dpy; + (void) screen; + (void) max; + return False; +} + + + +/*** GLX_SUN_get_transparent_index ***/ + +static Status +Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) +{ + (void) dpy; + (void) overlay; + (void) underlay; + (void) pTransparent; + return 0; +} + + + +/*** GLX_MESA_release_buffers ***/ + +/* + * Release the depth, stencil, accum buffers attached to a GLXDrawable + * (a window or pixmap) prior to destroying the GLXDrawable. + */ +static Bool +Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, d); + if (b) { + XMesaDestroyBuffer(b); + return True; + } + return False; +} + + + +/*** GLX_MESA_set_3dfx_mode ***/ + +static Bool +Fake_glXSet3DfxModeMESA( int mode ) +{ + return XMesaSetFXmode( mode ); +} + + + +/*** GLX_NV_vertex_array range ***/ +static void * +Fake_glXAllocateMemoryNV( GLsizei size, + GLfloat readFrequency, + GLfloat writeFrequency, + GLfloat priority ) +{ + (void) size; + (void) readFrequency; + (void) writeFrequency; + (void) priority; + return NULL; +} + + +static void +Fake_glXFreeMemoryNV( GLvoid *pointer ) +{ + (void) pointer; +} + + +/*** GLX_MESA_agp_offset ***/ + +static GLuint +Fake_glXGetAGPOffsetMESA( const GLvoid *pointer ) +{ + (void) pointer; + return ~0; +} + + +/*** GLX_EXT_texture_from_pixmap ***/ + +static void +Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, + const int *attrib_list) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, drawable); + if (b) + XMesaBindTexImage(dpy, b, buffer, attrib_list); +} + +static void +Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, drawable); + if (b) + XMesaReleaseTexImage(dpy, b, buffer); +} + + +/* silence warning */ +extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); + + +/** + * Create a new GLX API dispatch table with its function pointers + * initialized to point to Mesa's "fake" GLX API functions. + * Note: there's a similar function (_real_GetGLXDispatchTable) that + * returns a new dispatch table with all pointers initalized to point + * to "real" GLX functions (which understand GLX wire protocol, etc). + */ +struct _glxapi_table * +_mesa_GetGLXDispatchTable(void) +{ + static struct _glxapi_table glx; + + /* be sure our dispatch table size <= libGL's table */ + { + GLuint size = sizeof(struct _glxapi_table) / sizeof(void *); + (void) size; + assert(_glxapi_get_dispatch_table_size() >= size); + } + + /* initialize the whole table to no-ops */ + _glxapi_set_no_op_table(&glx); + + /* now initialize the table with the functions I implement */ + glx.ChooseVisual = Fake_glXChooseVisual; + glx.CopyContext = Fake_glXCopyContext; + glx.CreateContext = Fake_glXCreateContext; + glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap; + glx.DestroyContext = Fake_glXDestroyContext; + glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap; + glx.GetConfig = Fake_glXGetConfig; + /*glx.GetCurrentContext = Fake_glXGetCurrentContext;*/ + /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/ + glx.IsDirect = Fake_glXIsDirect; + glx.MakeCurrent = Fake_glXMakeCurrent; + glx.QueryExtension = Fake_glXQueryExtension; + glx.QueryVersion = Fake_glXQueryVersion; + glx.SwapBuffers = Fake_glXSwapBuffers; + glx.UseXFont = Fake_glXUseXFont; + glx.WaitGL = Fake_glXWaitGL; + glx.WaitX = Fake_glXWaitX; + + /*** GLX_VERSION_1_1 ***/ + glx.GetClientString = Fake_glXGetClientString; + glx.QueryExtensionsString = Fake_glXQueryExtensionsString; + glx.QueryServerString = Fake_glXQueryServerString; + + /*** GLX_VERSION_1_2 ***/ + /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/ + + /*** GLX_VERSION_1_3 ***/ + glx.ChooseFBConfig = Fake_glXChooseFBConfig; + glx.CreateNewContext = Fake_glXCreateNewContext; + glx.CreatePbuffer = Fake_glXCreatePbuffer; + glx.CreatePixmap = Fake_glXCreatePixmap; + glx.CreateWindow = Fake_glXCreateWindow; + glx.DestroyPbuffer = Fake_glXDestroyPbuffer; + glx.DestroyPixmap = Fake_glXDestroyPixmap; + glx.DestroyWindow = Fake_glXDestroyWindow; + /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/ + glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib; + glx.GetFBConfigs = Fake_glXGetFBConfigs; + glx.GetSelectedEvent = Fake_glXGetSelectedEvent; + glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig; + glx.MakeContextCurrent = Fake_glXMakeContextCurrent; + glx.QueryContext = Fake_glXQueryContext; + glx.QueryDrawable = Fake_glXQueryDrawable; + glx.SelectEvent = Fake_glXSelectEvent; + + /*** GLX_SGI_swap_control ***/ + glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI; + + /*** GLX_SGI_video_sync ***/ + glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI; + glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI; + + /*** GLX_SGI_make_current_read ***/ + glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI; + /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/ + +/*** GLX_SGIX_video_source ***/ +#if defined(_VL_H) + glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX; + glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX; +#endif + + /*** GLX_EXT_import_context ***/ + glx.FreeContextEXT = Fake_glXFreeContextEXT; + glx.GetContextIDEXT = Fake_glXGetContextIDEXT; + /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/ + glx.ImportContextEXT = Fake_glXImportContextEXT; + glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT; + + /*** GLX_SGIX_fbconfig ***/ + glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX; + glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX; + glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX; + glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX; + glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX; + glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX; + + /*** GLX_SGIX_pbuffer ***/ + glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX; + glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX; + glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX; + glx.SelectEventSGIX = Fake_glXSelectEventSGIX; + glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX; + + /*** GLX_SGI_cushion ***/ + glx.CushionSGI = Fake_glXCushionSGI; + + /*** GLX_SGIX_video_resize ***/ + glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX; + glx.ChannelRectSGIX = Fake_glXChannelRectSGIX; + glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX; + glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX; + glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX; + + /*** GLX_SGIX_dmbuffer **/ +#if defined(_DM_BUFFER_H_) + glx.AssociateDMPbufferSGIX = NULL; +#endif + + /*** GLX_SGIX_swap_group ***/ + glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX; + + /*** GLX_SGIX_swap_barrier ***/ + glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX; + glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX; + + /*** GLX_SUN_get_transparent_index ***/ + glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN; + + /*** GLX_MESA_copy_sub_buffer ***/ + glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA; + + /*** GLX_MESA_release_buffers ***/ + glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA; + + /*** GLX_MESA_pixmap_colormap ***/ + glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA; + + /*** GLX_MESA_set_3dfx_mode ***/ + glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA; + + /*** GLX_NV_vertex_array_range ***/ + glx.AllocateMemoryNV = Fake_glXAllocateMemoryNV; + glx.FreeMemoryNV = Fake_glXFreeMemoryNV; + + /*** GLX_MESA_agp_offset ***/ + glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA; + + /*** GLX_EXT_texture_from_pixmap ***/ + glx.BindTexImageEXT = Fake_glXBindTexImageEXT; + glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT; + + return &glx; +} diff --git a/src/gallium/winsys/xlib/glxapi.c b/src/gallium/winsys/xlib/glxapi.c new file mode 100644 index 0000000000..c2ccce6f52 --- /dev/null +++ b/src/gallium/winsys/xlib/glxapi.c @@ -0,0 +1,1408 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + + +/* + * This is the GLX API dispatcher. Calls to the glX* functions are + * either routed to the real GLX encoders or to Mesa's pseudo-GLX functions. + * See the glxapi.h file for more details. + */ + + +#include +#include +#include +#include +#include "main/glheader.h" +#include "glapi/glapi.h" +#include "glxapi.h" + + +extern struct _glxapi_table *_real_GetGLXDispatchTable(void); +extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); + + +struct display_dispatch { + Display *Dpy; + struct _glxapi_table *Table; + struct display_dispatch *Next; +}; + +static struct display_dispatch *DispatchList = NULL; + + +/* Display -> Dispatch caching */ +static Display *prevDisplay = NULL; +static struct _glxapi_table *prevTable = NULL; + + +static struct _glxapi_table * +get_dispatch(Display *dpy) +{ + if (!dpy) + return NULL; + + /* search list of display/dispatch pairs for this display */ + { + const struct display_dispatch *d = DispatchList; + while (d) { + if (d->Dpy == dpy) { + prevDisplay = dpy; + prevTable = d->Table; + return d->Table; /* done! */ + } + d = d->Next; + } + } + + /* A new display, determine if we should use real GLX + * or Mesa's pseudo-GLX. + */ + { + struct _glxapi_table *t = _mesa_GetGLXDispatchTable(); + + if (t) { + struct display_dispatch *d; + d = (struct display_dispatch *) malloc(sizeof(struct display_dispatch)); + if (d) { + d->Dpy = dpy; + d->Table = t; + /* insert at head of list */ + d->Next = DispatchList; + DispatchList = d; + /* update cache */ + prevDisplay = dpy; + prevTable = t; + return t; + } + } + } + + /* If we get here that means we can't use real GLX on this display + * and the Mesa pseudo-GLX software renderer wasn't compiled in. + * Or, we ran out of memory! + */ + return NULL; +} + + +/* Don't use the GET_DISPATCH defined in glthread.h */ +#undef GET_DISPATCH + +#define GET_DISPATCH(DPY, TABLE) \ + if (DPY == prevDisplay) { \ + TABLE = prevTable; \ + } \ + else if (!DPY) { \ + TABLE = NULL; \ + } \ + else { \ + TABLE = get_dispatch(DPY); \ + } + + + + +/** + * GLX API current context. + */ +#if defined(GLX_USE_TLS) +PUBLIC __thread void * CurrentContext + __attribute__((tls_model("initial-exec"))); +#elif defined(THREADS) +static _glthread_TSD ContextTSD; /**< Per-thread context pointer */ +#else +static GLXContext CurrentContext = 0; +#endif + + +static void +SetCurrentContext(GLXContext c) +{ +#if defined(GLX_USE_TLS) + CurrentContext = c; +#elif defined(THREADS) + _glthread_SetTSD(&ContextTSD, c); +#else + CurrentContext = c; +#endif +} + + +/* + * GLX API entrypoints + */ + +/*** GLX_VERSION_1_0 ***/ + +XVisualInfo PUBLIC * +glXChooseVisual(Display *dpy, int screen, int *list) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->ChooseVisual)(dpy, screen, list); +} + + +void PUBLIC +glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->CopyContext)(dpy, src, dst, mask); +} + + +GLXContext PUBLIC +glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateContext)(dpy, visinfo, shareList, direct); +} + + +GLXPixmap PUBLIC +glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXPixmap)(dpy, visinfo, pixmap); +} + + +void PUBLIC +glXDestroyContext(Display *dpy, GLXContext ctx) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + if (glXGetCurrentContext() == ctx) + SetCurrentContext(NULL); + (t->DestroyContext)(dpy, ctx); +} + + +void PUBLIC +glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyGLXPixmap)(dpy, pixmap); +} + + +int PUBLIC +glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return GLX_NO_EXTENSION; + return (t->GetConfig)(dpy, visinfo, attrib, value); +} + + +GLXContext PUBLIC +glXGetCurrentContext(void) +{ +#if defined(GLX_USE_TLS) + return CurrentContext; +#elif defined(THREADS) + return (GLXContext) _glthread_GetTSD(&ContextTSD); +#else + return CurrentContext; +#endif +} + + +GLXDrawable PUBLIC +glXGetCurrentDrawable(void) +{ + __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); + return gc ? gc->currentDrawable : 0; +} + + +Bool PUBLIC +glXIsDirect(Display *dpy, GLXContext ctx) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->IsDirect)(dpy, ctx); +} + + +Bool PUBLIC +glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) +{ + Bool b; + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) { + return False; + } + b = (*t->MakeCurrent)(dpy, drawable, ctx); + if (b) { + SetCurrentContext(ctx); + } + return b; +} + + +Bool PUBLIC +glXQueryExtension(Display *dpy, int *errorb, int *event) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->QueryExtension)(dpy, errorb, event); +} + + +Bool PUBLIC +glXQueryVersion(Display *dpy, int *maj, int *min) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->QueryVersion)(dpy, maj, min); +} + + +void PUBLIC +glXSwapBuffers(Display *dpy, GLXDrawable drawable) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->SwapBuffers)(dpy, drawable); +} + + +void PUBLIC +glXUseXFont(Font font, int first, int count, int listBase) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->UseXFont)(font, first, count, listBase); +} + + +void PUBLIC +glXWaitGL(void) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->WaitGL)(); +} + + +void PUBLIC +glXWaitX(void) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->WaitX)(); +} + + + +/*** GLX_VERSION_1_1 ***/ + +const char PUBLIC * +glXGetClientString(Display *dpy, int name) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->GetClientString)(dpy, name); +} + + +const char PUBLIC * +glXQueryExtensionsString(Display *dpy, int screen) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->QueryExtensionsString)(dpy, screen); +} + + +const char PUBLIC * +glXQueryServerString(Display *dpy, int screen, int name) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->QueryServerString)(dpy, screen, name); +} + + +/*** GLX_VERSION_1_2 ***/ + +Display PUBLIC * +glXGetCurrentDisplay(void) +{ + /* Same code as in libGL's glxext.c */ + __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); + if (NULL == gc) return NULL; + return gc->currentDpy; +} + + + +/*** GLX_VERSION_1_3 ***/ + +GLXFBConfig PUBLIC * +glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ChooseFBConfig)(dpy, screen, attribList, nitems); +} + + +GLXContext PUBLIC +glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateNewContext)(dpy, config, renderType, shareList, direct); +} + + +GLXPbuffer PUBLIC +glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreatePbuffer)(dpy, config, attribList); +} + + +GLXPixmap PUBLIC +glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreatePixmap)(dpy, config, pixmap, attribList); +} + + +GLXWindow PUBLIC +glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateWindow)(dpy, config, win, attribList); +} + + +void PUBLIC +glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyPbuffer)(dpy, pbuf); +} + + +void PUBLIC +glXDestroyPixmap(Display *dpy, GLXPixmap pixmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyPixmap)(dpy, pixmap); +} + + +void PUBLIC +glXDestroyWindow(Display *dpy, GLXWindow window) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyWindow)(dpy, window); +} + + +GLXDrawable PUBLIC +glXGetCurrentReadDrawable(void) +{ + __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); + return gc ? gc->currentReadable : 0; +} + + +int PUBLIC +glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return GLX_NO_EXTENSION; + return (t->GetFBConfigAttrib)(dpy, config, attribute, value); +} + + +GLXFBConfig PUBLIC * +glXGetFBConfigs(Display *dpy, int screen, int *nelements) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetFBConfigs)(dpy, screen, nelements); +} + +void PUBLIC +glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->GetSelectedEvent)(dpy, drawable, mask); +} + + +XVisualInfo PUBLIC * +glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->GetVisualFromFBConfig)(dpy, config); +} + + +Bool PUBLIC +glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) +{ + Bool b; + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + b = (t->MakeContextCurrent)(dpy, draw, read, ctx); + if (b) { + SetCurrentContext(ctx); + } + return b; +} + + +int PUBLIC +glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + assert(t); + if (!t) + return 0; /* XXX correct? */ + return (t->QueryContext)(dpy, ctx, attribute, value); +} + + +void PUBLIC +glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->QueryDrawable)(dpy, draw, attribute, value); +} + + +void PUBLIC +glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->SelectEvent)(dpy, drawable, mask); +} + + + +/*** GLX_SGI_swap_control ***/ + +int PUBLIC +glXSwapIntervalSGI(int interval) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->SwapIntervalSGI)(interval); +} + + + +/*** GLX_SGI_video_sync ***/ + +int PUBLIC +glXGetVideoSyncSGI(unsigned int *count) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t || !glXGetCurrentContext()) + return GLX_BAD_CONTEXT; + return (t->GetVideoSyncSGI)(count); +} + +int PUBLIC +glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t || !glXGetCurrentContext()) + return GLX_BAD_CONTEXT; + return (t->WaitVideoSyncSGI)(divisor, remainder, count); +} + + + +/*** GLX_SGI_make_current_read ***/ + +Bool PUBLIC +glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->MakeCurrentReadSGI)(dpy, draw, read, ctx); +} + +GLXDrawable PUBLIC +glXGetCurrentReadDrawableSGI(void) +{ + return glXGetCurrentReadDrawable(); +} + + +#if defined(_VL_H) + +GLXVideoSourceSGIX PUBLIC +glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXVideoSourceSGIX)(dpy, screen, server, path, nodeClass, drainNode); +} + +void PUBLIC +glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->DestroyGLXVideoSourceSGIX)(dpy, src); +} + +#endif + + +/*** GLX_EXT_import_context ***/ + +void PUBLIC +glXFreeContextEXT(Display *dpy, GLXContext context) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->FreeContextEXT)(dpy, context); +} + +GLXContextID PUBLIC +glXGetContextIDEXT(const GLXContext context) +{ + return ((__GLXcontext *) context)->xid; +} + +Display PUBLIC * +glXGetCurrentDisplayEXT(void) +{ + return glXGetCurrentDisplay(); +} + +GLXContext PUBLIC +glXImportContextEXT(Display *dpy, GLXContextID contextID) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ImportContextEXT)(dpy, contextID); +} + +int PUBLIC +glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; /* XXX ok? */ + return (t->QueryContextInfoEXT)(dpy, context, attribute, value); +} + + + +/*** GLX_SGIX_fbconfig ***/ + +int PUBLIC +glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetFBConfigAttribSGIX)(dpy, config, attribute, value); +} + +GLXFBConfigSGIX PUBLIC * +glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ChooseFBConfigSGIX)(dpy, screen, attrib_list, nelements); +} + +GLXPixmap PUBLIC +glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXPixmapWithConfigSGIX)(dpy, config, pixmap); +} + +GLXContext PUBLIC +glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateContextWithConfigSGIX)(dpy, config, render_type, share_list, direct); +} + +XVisualInfo PUBLIC * +glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetVisualFromFBConfigSGIX)(dpy, config); +} + +GLXFBConfigSGIX PUBLIC +glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetFBConfigFromVisualSGIX)(dpy, vis); +} + + + +/*** GLX_SGIX_pbuffer ***/ + +GLXPbufferSGIX PUBLIC +glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXPbufferSGIX)(dpy, config, width, height, attrib_list); +} + +void PUBLIC +glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyGLXPbufferSGIX)(dpy, pbuf); +} + +int PUBLIC +glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->QueryGLXPbufferSGIX)(dpy, pbuf, attribute, value); +} + +void PUBLIC +glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->SelectEventSGIX)(dpy, drawable, mask); +} + +void PUBLIC +glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->GetSelectedEventSGIX)(dpy, drawable, mask); +} + + + +/*** GLX_SGI_cushion ***/ + +void PUBLIC +glXCushionSGI(Display *dpy, Window win, float cushion) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->CushionSGI)(dpy, win, cushion); +} + + + +/*** GLX_SGIX_video_resize ***/ + +int PUBLIC +glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->BindChannelToWindowSGIX)(dpy, screen, channel, window); +} + +int PUBLIC +glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ChannelRectSGIX)(dpy, screen, channel, x, y, w, h); +} + +int PUBLIC +glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->QueryChannelRectSGIX)(dpy, screen, channel, x, y, w, h); +} + +int PUBLIC +glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->QueryChannelDeltasSGIX)(dpy, screen, channel, dx, dy, dw, dh); +} + +int PUBLIC +glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ChannelRectSyncSGIX)(dpy, screen, channel, synctype); +} + + + +#if defined(_DM_BUFFER_H_) + +Bool PUBLIC +glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->AssociateDMPbufferSGIX)(dpy, pbuffer, params, dmbuffer); +} + +#endif + + +/*** GLX_SGIX_swap_group ***/ + +void PUBLIC +glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (*t->JoinSwapGroupSGIX)(dpy, drawable, member); +} + + +/*** GLX_SGIX_swap_barrier ***/ + +void PUBLIC +glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (*t->BindSwapBarrierSGIX)(dpy, drawable, barrier); +} + +Bool PUBLIC +glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (*t->QueryMaxSwapBarriersSGIX)(dpy, screen, max); +} + + + +/*** GLX_SUN_get_transparent_index ***/ + +Status PUBLIC +glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (*t->GetTransparentIndexSUN)(dpy, overlay, underlay, pTransparent); +} + + + +/*** GLX_MESA_copy_sub_buffer ***/ + +void PUBLIC +glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height); +} + + + +/*** GLX_MESA_release_buffers ***/ + +Bool PUBLIC +glXReleaseBuffersMESA(Display *dpy, Window w) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->ReleaseBuffersMESA)(dpy, w); +} + + + +/*** GLX_MESA_pixmap_colormap ***/ + +GLXPixmap PUBLIC +glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap); +} + + + +/*** GLX_MESA_set_3dfx_mode ***/ + +Bool PUBLIC +glXSet3DfxModeMESA(int mode) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->Set3DfxModeMESA)(mode); +} + + + +/*** GLX_NV_vertex_array_range ***/ + +void PUBLIC * +glXAllocateMemoryNV( GLsizei size, + GLfloat readFrequency, + GLfloat writeFrequency, + GLfloat priority ) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->AllocateMemoryNV)(size, readFrequency, writeFrequency, priority); +} + + +void PUBLIC +glXFreeMemoryNV( GLvoid *pointer ) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->FreeMemoryNV)(pointer); +} + + + + +/*** GLX_MESA_agp_offset */ + +GLuint PUBLIC +glXGetAGPOffsetMESA( const GLvoid *pointer ) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return ~0; + return (t->GetAGPOffsetMESA)(pointer); +} + + +/*** GLX_MESA_allocate_memory */ + +void * +glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size, + float readfreq, float writefreq, float priority) +{ + /* dummy */ + return NULL; +} + +void +glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) +{ + /* dummy */ +} + + +GLuint +glXGetMemoryOffsetMESA(Display *dpy, int scrn, const void *pointer) +{ + /* dummy */ + return 0; +} + + +/*** GLX_EXT_texture_from_pixmap */ + +void +glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, + const int *attrib_list) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (t) + t->BindTexImageEXT(dpy, drawable, buffer, attrib_list); +} + +void +glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (t) + t->ReleaseTexImageEXT(dpy, drawable, buffer); +} + + +/**********************************************************************/ +/* GLX API management functions */ +/**********************************************************************/ + + +const char * +_glxapi_get_version(void) +{ + return "1.3"; +} + + +/* + * Return array of extension strings. + */ +const char ** +_glxapi_get_extensions(void) +{ + static const char *extensions[] = { +#ifdef GLX_EXT_import_context + "GLX_EXT_import_context", +#endif +#ifdef GLX_SGI_video_sync + "GLX_SGI_video_sync", +#endif +#ifdef GLX_MESA_copy_sub_buffer + "GLX_MESA_copy_sub_buffer", +#endif +#ifdef GLX_MESA_release_buffers + "GLX_MESA_release_buffers", +#endif +#ifdef GLX_MESA_pixmap_colormap + "GLX_MESA_pixmap_colormap", +#endif +#ifdef GLX_MESA_set_3dfx_mode + "GLX_MESA_set_3dfx_mode", +#endif +#ifdef GLX_SGIX_fbconfig + "GLX_SGIX_fbconfig", +#endif +#ifdef GLX_SGIX_pbuffer + "GLX_SGIX_pbuffer", +#endif +#ifdef GLX_EXT_texture_from_pixmap + "GLX_EXT_texture_from_pixmap", +#endif + NULL + }; + return extensions; +} + + +/* + * Return size of the GLX dispatch table, in entries, not bytes. + */ +GLuint +_glxapi_get_dispatch_table_size(void) +{ + return sizeof(struct _glxapi_table) / sizeof(void *); +} + + +static int +generic_no_op_func(void) +{ + return 0; +} + + +/* + * Initialize all functions in given dispatch table to be no-ops + */ +void +_glxapi_set_no_op_table(struct _glxapi_table *t) +{ + typedef int (*nop_func)(void); + nop_func *dispatch = (nop_func *) t; + GLuint n = _glxapi_get_dispatch_table_size(); + GLuint i; + for (i = 0; i < n; i++) { + dispatch[i] = generic_no_op_func; + } +} + + +struct name_address_pair { + const char *Name; + __GLXextFuncPtr Address; +}; + +static struct name_address_pair GLX_functions[] = { + /*** GLX_VERSION_1_0 ***/ + { "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual }, + { "glXCopyContext", (__GLXextFuncPtr) glXCopyContext }, + { "glXCreateContext", (__GLXextFuncPtr) glXCreateContext }, + { "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap }, + { "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext }, + { "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap }, + { "glXGetConfig", (__GLXextFuncPtr) glXGetConfig }, + { "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext }, + { "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable }, + { "glXIsDirect", (__GLXextFuncPtr) glXIsDirect }, + { "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent }, + { "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension }, + { "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion }, + { "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers }, + { "glXUseXFont", (__GLXextFuncPtr) glXUseXFont }, + { "glXWaitGL", (__GLXextFuncPtr) glXWaitGL }, + { "glXWaitX", (__GLXextFuncPtr) glXWaitX }, + + /*** GLX_VERSION_1_1 ***/ + { "glXGetClientString", (__GLXextFuncPtr) glXGetClientString }, + { "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString }, + { "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString }, + + /*** GLX_VERSION_1_2 ***/ + { "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay }, + + /*** GLX_VERSION_1_3 ***/ + { "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig }, + { "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext }, + { "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer }, + { "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap }, + { "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow }, + { "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer }, + { "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap }, + { "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow }, + { "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable }, + { "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib }, + { "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs }, + { "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent }, + { "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig }, + { "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent }, + { "glXQueryContext", (__GLXextFuncPtr) glXQueryContext }, + { "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable }, + { "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent }, + + /*** GLX_VERSION_1_4 ***/ + { "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress }, + + /*** GLX_SGI_swap_control ***/ + { "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI }, + + /*** GLX_SGI_video_sync ***/ + { "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI }, + { "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI }, + + /*** GLX_SGI_make_current_read ***/ + { "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI }, + { "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI }, + + /*** GLX_SGIX_video_source ***/ +#if defined(_VL_H) + { "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX }, + { "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX }, +#endif + + /*** GLX_EXT_import_context ***/ + { "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT }, + { "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT }, + { "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT }, + { "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT }, + { "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT }, + + /*** GLX_SGIX_fbconfig ***/ + { "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX }, + { "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX }, + { "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX }, + { "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX }, + { "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX }, + { "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX }, + + /*** GLX_SGIX_pbuffer ***/ + { "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX }, + { "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX }, + { "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX }, + { "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX }, + { "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX }, + + /*** GLX_SGI_cushion ***/ + { "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI }, + + /*** GLX_SGIX_video_resize ***/ + { "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX }, + { "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX }, + { "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX }, + { "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX }, + { "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX }, + + /*** GLX_SGIX_dmbuffer **/ +#if defined(_DM_BUFFER_H_) + { "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX }, +#endif + + /*** GLX_SGIX_swap_group ***/ + { "glXJoinSwapGroupSGIX", (__GLXextFuncPtr) glXJoinSwapGroupSGIX }, + + /*** GLX_SGIX_swap_barrier ***/ + { "glXBindSwapBarrierSGIX", (__GLXextFuncPtr) glXBindSwapBarrierSGIX }, + { "glXQueryMaxSwapBarriersSGIX", (__GLXextFuncPtr) glXQueryMaxSwapBarriersSGIX }, + + /*** GLX_SUN_get_transparent_index ***/ + { "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN }, + + /*** GLX_MESA_copy_sub_buffer ***/ + { "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA }, + + /*** GLX_MESA_pixmap_colormap ***/ + { "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA }, + + /*** GLX_MESA_release_buffers ***/ + { "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA }, + + /*** GLX_MESA_set_3dfx_mode ***/ + { "glXSet3DfxModeMESA", (__GLXextFuncPtr) glXSet3DfxModeMESA }, + + /*** GLX_ARB_get_proc_address ***/ + { "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB }, + + /*** GLX_NV_vertex_array_range ***/ + { "glXAllocateMemoryNV", (__GLXextFuncPtr) glXAllocateMemoryNV }, + { "glXFreeMemoryNV", (__GLXextFuncPtr) glXFreeMemoryNV }, + + /*** GLX_MESA_agp_offset ***/ + { "glXGetAGPOffsetMESA", (__GLXextFuncPtr) glXGetAGPOffsetMESA }, + + /*** GLX_MESA_allocate_memory ***/ + { "glXAllocateMemoryMESA", (__GLXextFuncPtr) glXAllocateMemoryMESA }, + { "glXFreeMemoryMESA", (__GLXextFuncPtr) glXFreeMemoryMESA }, + { "glXGetMemoryOffsetMESA", (__GLXextFuncPtr) glXGetMemoryOffsetMESA }, + + /*** GLX_EXT_texture_from_pixmap ***/ + { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT }, + { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT }, + + { NULL, NULL } /* end of list */ +}; + + + +/* + * Return address of named glX function, or NULL if not found. + */ +__GLXextFuncPtr +_glxapi_get_proc_address(const char *funcName) +{ + GLuint i; + for (i = 0; GLX_functions[i].Name; i++) { + if (strcmp(GLX_functions[i].Name, funcName) == 0) + return GLX_functions[i].Address; + } + return NULL; +} + + + +/* + * This function does not get dispatched through the dispatch table + * since it's really a "meta" function. + */ +__GLXextFuncPtr +glXGetProcAddressARB(const GLubyte *procName) +{ + __GLXextFuncPtr f; + + f = _glxapi_get_proc_address((const char *) procName); + if (f) { + return f; + } + + f = (__GLXextFuncPtr) _glapi_get_proc_address((const char *) procName); + return f; +} + + +/* GLX 1.4 */ +void (*glXGetProcAddress(const GLubyte *procName))() +{ + return glXGetProcAddressARB(procName); +} diff --git a/src/gallium/winsys/xlib/glxapi.h b/src/gallium/winsys/xlib/glxapi.h new file mode 100644 index 0000000000..37de81e55a --- /dev/null +++ b/src/gallium/winsys/xlib/glxapi.h @@ -0,0 +1,228 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2004 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + + +#ifndef _glxapi_h_ +#define _glxapi_h_ + + +#define GLX_GLXEXT_PROTOTYPES +#include "GL/glx.h" + + +/* The GLX API dispatcher (i.e. this code) is being built into stand-alone + * Mesa. We don't know anything about XFree86 or real GLX so we define a + * minimal __GLXContextRec here so some of the functions in this file can + * work properly. + */ +typedef struct __GLXcontextRec { + Display *currentDpy; + GLboolean isDirect; + GLXDrawable currentDrawable; + GLXDrawable currentReadable; + XID xid; +} __GLXcontext; + + +/* + * Almost all the GLX API functions get routed through this dispatch table. + * The exceptions are the glXGetCurrentXXX() functions. + * + * This dispatch table allows multiple GLX client-side modules to coexist. + * Specifically, a real GLX library (like SGI's or the Utah GLX) and Mesa's + * pseudo-GLX can be present at the same time. The former being used on + * GLX-enabled X servers and the later on non-GLX X servers. + * + * Red Hat has been using this since Red Hat Linux 7.0 (I think). + * This'll be a standard feature in XFree86 4.3. It basically allows one + * libGL to do both DRI-rendering and "fake GLX" rendering to X displays + * that lack the GLX extension. + */ +struct _glxapi_table { + /*** GLX_VERSION_1_0 ***/ + XVisualInfo *(*ChooseVisual)(Display *dpy, int screen, int *list); + void (*CopyContext)(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask); + GLXContext (*CreateContext)(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct); + GLXPixmap (*CreateGLXPixmap)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap); + void (*DestroyContext)(Display *dpy, GLXContext ctx); + void (*DestroyGLXPixmap)(Display *dpy, GLXPixmap pixmap); + int (*GetConfig)(Display *dpy, XVisualInfo *visinfo, int attrib, int *value); + /*GLXContext (*GetCurrentContext)(void);*/ + /*GLXDrawable (*GetCurrentDrawable)(void);*/ + Bool (*IsDirect)(Display *dpy, GLXContext ctx); + Bool (*MakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx); + Bool (*QueryExtension)(Display *dpy, int *errorb, int *event); + Bool (*QueryVersion)(Display *dpy, int *maj, int *min); + void (*SwapBuffers)(Display *dpy, GLXDrawable drawable); + void (*UseXFont)(Font font, int first, int count, int listBase); + void (*WaitGL)(void); + void (*WaitX)(void); + + /*** GLX_VERSION_1_1 ***/ + const char *(*GetClientString)(Display *dpy, int name); + const char *(*QueryExtensionsString)(Display *dpy, int screen); + const char *(*QueryServerString)(Display *dpy, int screen, int name); + + /*** GLX_VERSION_1_2 ***/ + /*Display *(*GetCurrentDisplay)(void);*/ + + /*** GLX_VERSION_1_3 ***/ + GLXFBConfig *(*ChooseFBConfig)(Display *dpy, int screen, const int *attribList, int *nitems); + GLXContext (*CreateNewContext)(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct); + GLXPbuffer (*CreatePbuffer)(Display *dpy, GLXFBConfig config, const int *attribList); + GLXPixmap (*CreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList); + GLXWindow (*CreateWindow)(Display *dpy, GLXFBConfig config, Window win, const int *attribList); + void (*DestroyPbuffer)(Display *dpy, GLXPbuffer pbuf); + void (*DestroyPixmap)(Display *dpy, GLXPixmap pixmap); + void (*DestroyWindow)(Display *dpy, GLXWindow window); + /*GLXDrawable (*GetCurrentReadDrawable)(void);*/ + int (*GetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value); + GLXFBConfig *(*GetFBConfigs)(Display *dpy, int screen, int *nelements); + void (*GetSelectedEvent)(Display *dpy, GLXDrawable drawable, unsigned long *mask); + XVisualInfo *(*GetVisualFromFBConfig)(Display *dpy, GLXFBConfig config); + Bool (*MakeContextCurrent)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + int (*QueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value); + void (*QueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); + void (*SelectEvent)(Display *dpy, GLXDrawable drawable, unsigned long mask); + + /*** GLX_SGI_swap_control ***/ + int (*SwapIntervalSGI)(int); + + /*** GLX_SGI_video_sync ***/ + int (*GetVideoSyncSGI)(unsigned int *count); + int (*WaitVideoSyncSGI)(int divisor, int remainder, unsigned int *count); + + /*** GLX_SGI_make_current_read ***/ + Bool (*MakeCurrentReadSGI)(Display *, GLXDrawable, GLXDrawable, GLXContext); + /*GLXDrawable (*GetCurrentReadDrawableSGI)(void);*/ + + /*** GLX_SGIX_video_source (needs video library) ***/ +#if defined(_VL_H_) + GLXVideoSourceSGIX (*CreateGLXVideoSourceSGIX)(Display *, int, VLServer, VLPath, int, VLNode); + void (*DestroyGLXVideoSourceSGIX)(Display *, GLXVideoSourceSGIX); +#else + void *CreateGLXVideoSourceSGIX; + void *DestroyGLXVideoSourceSGIX; +#endif + + /*** GLX_EXT_import_context ***/ + void (*FreeContextEXT)(Display *dpy, GLXContext context); + GLXContextID (*GetContextIDEXT)(const GLXContext context); + /*Display *(*GetCurrentDisplayEXT)(void);*/ + GLXContext (*ImportContextEXT)(Display *dpy, GLXContextID contextID); + int (*QueryContextInfoEXT)(Display *dpy, GLXContext context, int attribute,int *value); + + /*** GLX_SGIX_fbconfig ***/ + int (*GetFBConfigAttribSGIX)(Display *, GLXFBConfigSGIX, int, int *); + GLXFBConfigSGIX * (*ChooseFBConfigSGIX)(Display *, int, int *, int *); + GLXPixmap (*CreateGLXPixmapWithConfigSGIX)(Display *, GLXFBConfigSGIX, Pixmap); + GLXContext (*CreateContextWithConfigSGIX)(Display *, GLXFBConfigSGIX, int, GLXContext, Bool); + XVisualInfo * (*GetVisualFromFBConfigSGIX)(Display *, GLXFBConfigSGIX); + GLXFBConfigSGIX (*GetFBConfigFromVisualSGIX)(Display *, XVisualInfo *); + + /*** GLX_SGIX_pbuffer ***/ + GLXPbufferSGIX (*CreateGLXPbufferSGIX)(Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *); + void (*DestroyGLXPbufferSGIX)(Display *, GLXPbufferSGIX); + int (*QueryGLXPbufferSGIX)(Display *, GLXPbufferSGIX, int, unsigned int *); + void (*SelectEventSGIX)(Display *, GLXDrawable, unsigned long); + void (*GetSelectedEventSGIX)(Display *, GLXDrawable, unsigned long *); + + /*** GLX_SGI_cushion ***/ + void (*CushionSGI)(Display *, Window, float); + + /*** GLX_SGIX_video_resize ***/ + int (*BindChannelToWindowSGIX)(Display *, int, int, Window); + int (*ChannelRectSGIX)(Display *, int, int, int, int, int, int); + int (*QueryChannelRectSGIX)(Display *, int, int, int *, int *, int *, int *); + int (*QueryChannelDeltasSGIX)(Display *, int, int, int *, int *, int *, int *); + int (*ChannelRectSyncSGIX)(Display *, int, int, GLenum); + + /*** GLX_SGIX_dmbuffer (needs dmedia library) ***/ +#if defined (_DM_BUFFER_H_) + Bool (*AssociateDMPbufferSGIX)(Display *, GLXPbufferSGIX, DMparams *, DMbuffer); +#else + void *AssociciateDMPbufferSGIX; +#endif + + /*** GLX_SGIX_swap_group ***/ + void (*JoinSwapGroupSGIX)(Display *, GLXDrawable, GLXDrawable); + + /*** GLX_SGIX_swap_barrier ***/ + void (*BindSwapBarrierSGIX)(Display *, GLXDrawable, int); + Bool (*QueryMaxSwapBarriersSGIX)(Display *, int, int *); + + /*** GLX_SUN_get_transparent_index ***/ + Status (*GetTransparentIndexSUN)(Display *, Window, Window, long *); + + /*** GLX_MESA_copy_sub_buffer ***/ + void (*CopySubBufferMESA)(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); + + /*** GLX_MESA_release_buffers ***/ + Bool (*ReleaseBuffersMESA)(Display *dpy, Window w); + + /*** GLX_MESA_pixmap_colormap ***/ + GLXPixmap (*CreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap); + + /*** GLX_MESA_set_3dfx_mode ***/ + Bool (*Set3DfxModeMESA)(int mode); + + /*** GLX_NV_vertex_array_range ***/ + void * (*AllocateMemoryNV)( GLsizei size, + GLfloat readFrequency, + GLfloat writeFrequency, + GLfloat priority ); + void (*FreeMemoryNV)( GLvoid *pointer ); + + /*** GLX_MESA_agp_offset ***/ + GLuint (*GetAGPOffsetMESA)( const GLvoid *pointer ); + + /*** GLX_EXT_texture_from_pixmap ***/ + void (*BindTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer, + const int *attrib_list); + void (*ReleaseTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer); +}; + + + +extern const char * +_glxapi_get_version(void); + + +extern const char ** +_glxapi_get_extensions(void); + + +extern GLuint +_glxapi_get_dispatch_table_size(void); + + +extern void +_glxapi_set_no_op_table(struct _glxapi_table *t); + + +extern __GLXextFuncPtr +_glxapi_get_proc_address(const char *funcName); + + +#endif diff --git a/src/gallium/winsys/xlib/glxheader.h b/src/gallium/winsys/xlib/glxheader.h new file mode 100644 index 0000000000..a402191f13 --- /dev/null +++ b/src/gallium/winsys/xlib/glxheader.h @@ -0,0 +1,62 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.1 + * + * Copyright (C) 1999-2006 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + + +#ifndef GLX_HEADER_H +#define GLX_HEADER_H + +#ifdef __VMS +#include +#endif + +#include "glheader.h" + +#ifdef XFree86Server + +# include "resource.h" +# include "windowstr.h" + +#else + +# include +# include +# include +# ifdef USE_XSHM /* was SHM */ +# include +# include +# include +# endif +# include +# include + +#endif + + + +/* this silences a compiler warning on several systems */ +struct timespec; +struct itimerspec; + + +#endif /*GLX_HEADER*/ diff --git a/src/gallium/winsys/xlib/realglx.c b/src/gallium/winsys/xlib/realglx.c new file mode 100644 index 0000000000..30adb7465b --- /dev/null +++ b/src/gallium/winsys/xlib/realglx.c @@ -0,0 +1,180 @@ + +/* + * Mesa 3-D graphics library + * Version: 5.1 + * + * Copyright (C) 1999-2002 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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 +#include +#include "realglx.h" +#include "glxapi.h" + + +struct _glxapi_table * +_real_GetGLXDispatchTable(void) +{ + static struct _glxapi_table glx; + + /* be sure our dispatch table size <= libGL's table */ + { + GLuint size = sizeof(struct _glxapi_table) / sizeof(void *); + (void) size; + assert(_glxapi_get_dispatch_table_size() >= size); + } + + /* initialize the whole table to no-ops */ + _glxapi_set_no_op_table(&glx); + + /* now initialize the table with the functions I implement */ + + /*** GLX_VERSION_1_0 ***/ + glx.ChooseVisual = _real_glXChooseVisual; + glx.CopyContext = _real_glXCopyContext; + glx.CreateContext = _real_glXCreateContext; + glx.CreateGLXPixmap = _real_glXCreateGLXPixmap; + glx.DestroyContext = _real_glXDestroyContext; + glx.DestroyGLXPixmap = _real_glXDestroyGLXPixmap; + glx.GetConfig = _real_glXGetConfig; + /*glx.GetCurrentContext = _real_glXGetCurrentContext;*/ + /*glx.GetCurrentDrawable = _real_glXGetCurrentDrawable;*/ + glx.IsDirect = _real_glXIsDirect; + glx.MakeCurrent = _real_glXMakeCurrent; + glx.QueryExtension = _real_glXQueryExtension; + glx.QueryVersion = _real_glXQueryVersion; + glx.SwapBuffers = _real_glXSwapBuffers; + glx.UseXFont = _real_glXUseXFont; + glx.WaitGL = _real_glXWaitGL; + glx.WaitX = _real_glXWaitX; + + /*** GLX_VERSION_1_1 ***/ + glx.GetClientString = _real_glXGetClientString; + glx.QueryExtensionsString = _real_glXQueryExtensionsString; + glx.QueryServerString = _real_glXQueryServerString; + + /*** GLX_VERSION_1_2 ***/ + /*glx.GetCurrentDisplay = _real_glXGetCurrentDisplay;*/ + + /*** GLX_VERSION_1_3 ***/ + glx.ChooseFBConfig = _real_glXChooseFBConfig; + glx.CreateNewContext = _real_glXCreateNewContext; + glx.CreatePbuffer = _real_glXCreatePbuffer; + glx.CreatePixmap = _real_glXCreatePixmap; + glx.CreateWindow = _real_glXCreateWindow; + glx.DestroyPbuffer = _real_glXDestroyPbuffer; + glx.DestroyPixmap = _real_glXDestroyPixmap; + glx.DestroyWindow = _real_glXDestroyWindow; + /*glx.GetCurrentReadDrawable = _real_glXGetCurrentReadDrawable;*/ + glx.GetFBConfigAttrib = _real_glXGetFBConfigAttrib; + glx.GetFBConfigs = _real_glXGetFBConfigs; + glx.GetSelectedEvent = _real_glXGetSelectedEvent; + glx.GetVisualFromFBConfig = _real_glXGetVisualFromFBConfig; + glx.MakeContextCurrent = _real_glXMakeContextCurrent; + glx.QueryContext = _real_glXQueryContext; + glx.QueryDrawable = _real_glXQueryDrawable; + glx.SelectEvent = _real_glXSelectEvent; + + /*** GLX_SGI_swap_control ***/ + glx.SwapIntervalSGI = _real_glXSwapIntervalSGI; + + /*** GLX_SGI_video_sync ***/ + glx.GetVideoSyncSGI = _real_glXGetVideoSyncSGI; + glx.WaitVideoSyncSGI = _real_glXWaitVideoSyncSGI; + + /*** GLX_SGI_make_current_read ***/ + glx.MakeCurrentReadSGI = _real_glXMakeCurrentReadSGI; + /*glx.GetCurrentReadDrawableSGI = _real_glXGetCurrentReadDrawableSGI;*/ + +#if defined(_VL_H) + /*** GLX_SGIX_video_source ***/ + glx.CreateGLXVideoSourceSGIX = _real_glXCreateGLXVideoSourceSGIX; + glx.DestroyGLXVideoSourceSGIX = _real_glXDestroyGLXVideoSourceSGIX; +#endif + + /*** GLX_EXT_import_context ***/ + glx.FreeContextEXT = _real_glXFreeContextEXT; + /*glx.GetContextIDEXT = _real_glXGetContextIDEXT;*/ + /*glx.GetCurrentDisplayEXT = _real_glXGetCurrentDisplayEXT;*/ + glx.ImportContextEXT = _real_glXImportContextEXT; + glx.QueryContextInfoEXT = _real_glXQueryContextInfoEXT; + + /*** GLX_SGIX_fbconfig ***/ + glx.GetFBConfigAttribSGIX = _real_glXGetFBConfigAttribSGIX; + glx.ChooseFBConfigSGIX = _real_glXChooseFBConfigSGIX; + glx.CreateGLXPixmapWithConfigSGIX = _real_glXCreateGLXPixmapWithConfigSGIX; + glx.CreateContextWithConfigSGIX = _real_glXCreateContextWithConfigSGIX; + glx.GetVisualFromFBConfigSGIX = _real_glXGetVisualFromFBConfigSGIX; + glx.GetFBConfigFromVisualSGIX = _real_glXGetFBConfigFromVisualSGIX; + + /*** GLX_SGIX_pbuffer ***/ + glx.CreateGLXPbufferSGIX = _real_glXCreateGLXPbufferSGIX; + glx.DestroyGLXPbufferSGIX = _real_glXDestroyGLXPbufferSGIX; + glx.QueryGLXPbufferSGIX = _real_glXQueryGLXPbufferSGIX; + glx.SelectEventSGIX = _real_glXSelectEventSGIX; + glx.GetSelectedEventSGIX = _real_glXGetSelectedEventSGIX; + + /*** GLX_SGI_cushion ***/ + glx.CushionSGI = _real_glXCushionSGI; + + /*** GLX_SGIX_video_resize ***/ + glx.BindChannelToWindowSGIX = _real_glXBindChannelToWindowSGIX; + glx.ChannelRectSGIX = _real_glXChannelRectSGIX; + glx.QueryChannelRectSGIX = _real_glXQueryChannelRectSGIX; + glx.QueryChannelDeltasSGIX = _real_glXQueryChannelDeltasSGIX; + glx.ChannelRectSyncSGIX = _real_glXChannelRectSyncSGIX; + +#if defined(_DM_BUFFER_H_) + /*** (GLX_SGIX_dmbuffer ***/ + glx.AssociateDMPbufferSGIX = NULL; +#endif + + /*** GLX_SGIX_swap_group ***/ + glx.JoinSwapGroupSGIX = _real_glXJoinSwapGroupSGIX; + + /*** GLX_SGIX_swap_barrier ***/ + glx.BindSwapBarrierSGIX = _real_glXBindSwapBarrierSGIX; + glx.QueryMaxSwapBarriersSGIX = _real_glXQueryMaxSwapBarriersSGIX; + + /*** GLX_SUN_get_transparent_index ***/ + glx.GetTransparentIndexSUN = _real_glXGetTransparentIndexSUN; + + /*** GLX_MESA_copy_sub_buffer ***/ + glx.CopySubBufferMESA = _real_glXCopySubBufferMESA; + + /*** GLX_MESA_release_buffers ***/ + glx.ReleaseBuffersMESA = _real_glXReleaseBuffersMESA; + + /*** GLX_MESA_pixmap_colormap ***/ + glx.CreateGLXPixmapMESA = _real_glXCreateGLXPixmapMESA; + + /*** GLX_MESA_set_3dfx_mode ***/ + glx.Set3DfxModeMESA = _real_glXSet3DfxModeMESA; + + /*** GLX_NV_vertex_array_range ***/ + glx.AllocateMemoryNV = _real_glXAllocateMemoryNV; + glx.FreeMemoryNV = _real_glXFreeMemoryNV; + + /*** GLX_MESA_agp_offset ***/ + glx.GetAGPOffsetMESA = _real_glXGetAGPOffsetMESA; + + return &glx; +} diff --git a/src/gallium/winsys/xlib/realglx.h b/src/gallium/winsys/xlib/realglx.h new file mode 100644 index 0000000000..150129db68 --- /dev/null +++ b/src/gallium/winsys/xlib/realglx.h @@ -0,0 +1,326 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + + +#ifndef REALGLX_H +#define REALGLX_H + + +extern struct _glxapi_table * +_real_GetGLXDispatchTable(void); + + +/* + * Basically just need these to prevent compiler warnings. + */ + + +extern XVisualInfo * +_real_glXChooseVisual( Display *dpy, int screen, int *list ); + +extern GLXContext +_real_glXCreateContext( Display *dpy, XVisualInfo *visinfo, + GLXContext share_list, Bool direct ); + +extern GLXPixmap +_real_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ); + +extern GLXPixmap +_real_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, + Pixmap pixmap, Colormap cmap ); + +extern void +_real_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ); + +extern void +_real_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, + unsigned long mask ); + +extern Bool +_real_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ); + +extern Bool +_real_glXQueryExtension( Display *dpy, int *errorb, int *event ); + +extern void +_real_glXDestroyContext( Display *dpy, GLXContext ctx ); + +extern Bool +_real_glXIsDirect( Display *dpy, GLXContext ctx ); + +extern void +_real_glXSwapBuffers( Display *dpy, GLXDrawable drawable ); + +extern void +_real_glXUseXFont( Font font, int first, int count, int listbase ); + +extern Bool +_real_glXQueryVersion( Display *dpy, int *maj, int *min ); + +extern int +_real_glXGetConfig( Display *dpy, XVisualInfo *visinfo, + int attrib, int *value ); + +extern void +_real_glXWaitGL( void ); + + +extern void +_real_glXWaitX( void ); + +/* GLX 1.1 and later */ +extern const char * +_real_glXQueryExtensionsString( Display *dpy, int screen ); + +/* GLX 1.1 and later */ +extern const char * +_real_glXQueryServerString( Display *dpy, int screen, int name ); + +/* GLX 1.1 and later */ +extern const char * +_real_glXGetClientString( Display *dpy, int name ); + + +/* + * GLX 1.3 and later + */ + +extern GLXFBConfig * +_real_glXChooseFBConfig( Display *dpy, int screen, + const int *attribList, int *nitems ); + +extern int +_real_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, + int attribute, int *value ); + +extern GLXFBConfig * +_real_glXGetFBConfigs( Display *dpy, int screen, int *nelements ); + +extern XVisualInfo * +_real_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ); + +extern GLXWindow +_real_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, + const int *attribList ); + +extern void +_real_glXDestroyWindow( Display *dpy, GLXWindow window ); + +extern GLXPixmap +_real_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, + const int *attribList ); + +extern void +_real_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ); + +extern GLXPbuffer +_real_glXCreatePbuffer( Display *dpy, GLXFBConfig config, + const int *attribList ); + +extern void +_real_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ); + +extern void +_real_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, + unsigned int *value ); + +extern GLXContext +_real_glXCreateNewContext( Display *dpy, GLXFBConfig config, + int renderType, GLXContext shareList, Bool direct ); + + +extern Bool +_real_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, + GLXDrawable read, GLXContext ctx ); + +extern int +_real_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ); + +extern void +_real_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ); + +extern void +_real_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, + unsigned long *mask ); + +#ifdef GLX_SGI_swap_control +extern int +_real_glXSwapIntervalSGI(int interval); +#endif + + +#ifdef GLX_SGI_video_sync +extern int +_real_glXGetVideoSyncSGI(unsigned int *count); + +extern int +_real_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count); +#endif + + +#ifdef GLX_SGI_make_current_read +extern Bool +_real_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + +extern GLXDrawable +_real_glXGetCurrentReadDrawableSGI(void); +#endif + +#if defined(_VL_H) && defined(GLX_SGIX_video_source) +extern GLXVideoSourceSGIX +_real_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode); + +extern void +_real_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src); +#endif + +#ifdef GLX_EXT_import_context +extern void +_real_glXFreeContextEXT(Display *dpy, GLXContext context); + +extern GLXContextID +_real_glXGetContextIDEXT(const GLXContext context); + +extern Display * +_real_glXGetCurrentDisplayEXT(void); + +extern GLXContext +_real_glXImportContextEXT(Display *dpy, GLXContextID contextID); + +extern int +_real_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value); +#endif + +#ifdef GLX_SGIX_fbconfig +extern int +_real_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); + +extern GLXFBConfigSGIX * +_real_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements); + +extern GLXPixmap +_real_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); + +extern GLXContext +_real_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); + +extern XVisualInfo * +_real_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config); + +extern GLXFBConfigSGIX +_real_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis); +#endif + +#ifdef GLX_SGIX_pbuffer +extern GLXPbufferSGIX +_real_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); + +extern void +_real_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf); + +extern int +_real_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); + +extern void +_real_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask); + +extern void +_real_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask); +#endif + +#ifdef GLX_SGI_cushion +extern void +_real_glXCushionSGI(Display *dpy, Window win, float cushion); +#endif + +#ifdef GLX_SGIX_video_resize +extern int +_real_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window); + +extern int +_real_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h); + +extern int +_real_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h); + +extern int +_real_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh); + +extern int +_real_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype); +#endif + +#if defined(_DM_BUFFER_H_) && defined(GLX_SGIX_dmbuffer) +extern Bool +_real_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer); +#endif + +#ifdef GLX_SGIX_swap_group +extern void +_real_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member); +#endif + +#ifdef GLX_SGIX_swap_barrier +extern void +_real_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier); + +extern Bool +_real_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max); +#endif + +#ifdef GLX_SUN_get_transparent_index +extern Status +_real_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent); +#endif + +#ifdef GLX_MESA_release_buffers +extern Bool +_real_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ); +#endif + +#ifdef GLX_MESA_set_3dfx_mode +extern Bool +_real_glXSet3DfxModeMESA( int mode ); +#endif + +#ifdef GLX_NV_vertex_array_range +extern void * +_real_glXAllocateMemoryNV(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +extern void +_real_glXFreeMemoryNV(GLvoid *pointer); +#endif + +#ifdef GLX_MESA_agp_offset +extern GLuint +_real_glXGetAGPOffsetMESA(const GLvoid *pointer); +#endif + +#ifdef GLX_MESA_copy_sub_buffer +extern void +_real_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, + int x, int y, int width, int height ); +#endif + +#endif /* REALGLX_H */ diff --git a/src/gallium/winsys/xlib/xfonts.c b/src/gallium/winsys/xlib/xfonts.c new file mode 100644 index 0000000000..d72c600bd1 --- /dev/null +++ b/src/gallium/winsys/xlib/xfonts.c @@ -0,0 +1,377 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + + +/* xfonts.c -- glXUseXFont() for Mesa written by + * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de + */ + +#ifdef __VMS +#include +#endif + +#include "glxheader.h" +#include "context.h" +#include "imports.h" +#include "xfonts.h" + + +/* Some debugging info. */ + +#ifdef DEBUG +#undef _R +#undef _G +#undef _B +#include + +int debug_xfonts = 0; + +static void +dump_char_struct(XCharStruct * ch, char *prefix) +{ + printf("%slbearing = %d, rbearing = %d, width = %d\n", + prefix, ch->lbearing, ch->rbearing, ch->width); + printf("%sascent = %d, descent = %d, attributes = %u\n", + prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes); +} + +static void +dump_font_struct(XFontStruct * font) +{ + printf("ascent = %d, descent = %d\n", font->ascent, font->descent); + printf("char_or_byte2 = (%u,%u)\n", + font->min_char_or_byte2, font->max_char_or_byte2); + printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1); + printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False"); + printf("default_char = %c (\\%03o)\n", + (char) (isprint(font->default_char) ? font->default_char : ' '), + font->default_char); + dump_char_struct(&font->min_bounds, "min> "); + dump_char_struct(&font->max_bounds, "max> "); +#if 0 + for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) { + char prefix[8]; + sprintf(prefix, "%d> ", c); + dump_char_struct(&font->per_char[c], prefix); + } +#endif +} + +static void +dump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap) +{ + unsigned int x, y; + + printf(" "); + for (x = 0; x < 8 * width; x++) + printf("%o", 7 - (x % 8)); + putchar('\n'); + for (y = 0; y < height; y++) { + printf("%3o:", y); + for (x = 0; x < 8 * width; x++) + putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x % + 8)))) + ? '*' : '.'); + printf(" "); + for (x = 0; x < width; x++) + printf("0x%02x, ", bitmap[width * (height - y - 1) + x]); + putchar('\n'); + } +} +#endif /* DEBUG */ + + +/* Implementation. */ + +/* Fill a BITMAP with a character C from thew current font + in the graphics context GC. WIDTH is the width in bytes + and HEIGHT is the height in bits. + + Note that the generated bitmaps must be used with + + glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE); + glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); + glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei (GL_UNPACK_ALIGNMENT, 1); + + Possible optimizations: + + * use only one reusable pixmap with the maximum dimensions. + * draw the entire font into a single pixmap (careful with + proportional fonts!). +*/ + + +/* + * Generate OpenGL-compatible bitmap. + */ +static void +fill_bitmap(Display * dpy, Window win, GC gc, + unsigned int width, unsigned int height, + int x0, int y0, unsigned int c, GLubyte * bitmap) +{ + XImage *image; + unsigned int x, y; + Pixmap pixmap; + XChar2b char2b; + + pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1); + XSetForeground(dpy, gc, 0); + XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height); + XSetForeground(dpy, gc, 1); + + char2b.byte1 = (c >> 8) & 0xff; + char2b.byte2 = (c & 0xff); + + XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1); + + image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap); + if (image) { + /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */ + for (y = 0; y < height; y++) + for (x = 0; x < 8 * width; x++) + if (XGetPixel(image, x, y)) + bitmap[width * (height - y - 1) + x / 8] |= + (1 << (7 - (x % 8))); + XDestroyImage(image); + } + + XFreePixmap(dpy, pixmap); +} + +/* + * determine if a given glyph is valid and return the + * corresponding XCharStruct. + */ +static XCharStruct * +isvalid(XFontStruct * fs, unsigned int which) +{ + unsigned int rows, pages; + unsigned int byte1 = 0, byte2 = 0; + int i, valid = 1; + + rows = fs->max_byte1 - fs->min_byte1 + 1; + pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; + + if (rows == 1) { + /* "linear" fonts */ + if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which)) + valid = 0; + } + else { + /* "matrix" fonts */ + byte2 = which & 0xff; + byte1 = which >> 8; + if ((fs->min_char_or_byte2 > byte2) || + (fs->max_char_or_byte2 < byte2) || + (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1)) + valid = 0; + } + + if (valid) { + if (fs->per_char) { + if (rows == 1) { + /* "linear" fonts */ + return (fs->per_char + (which - fs->min_char_or_byte2)); + } + else { + /* "matrix" fonts */ + i = ((byte1 - fs->min_byte1) * pages) + + (byte2 - fs->min_char_or_byte2); + return (fs->per_char + i); + } + } + else { + return (&fs->min_bounds); + } + } + return (NULL); +} + + +void +Fake_glXUseXFont(Font font, int first, int count, int listbase) +{ + Display *dpy; + Window win; + Pixmap pixmap; + GC gc; + XGCValues values; + unsigned long valuemask; + XFontStruct *fs; + GLint swapbytes, lsbfirst, rowlength; + GLint skiprows, skippixels, alignment; + unsigned int max_width, max_height, max_bm_width, max_bm_height; + GLubyte *bm; + int i; + + dpy = glXGetCurrentDisplay(); + if (!dpy) + return; /* I guess glXMakeCurrent wasn't called */ + win = RootWindow(dpy, DefaultScreen(dpy)); + + fs = XQueryFont(dpy, font); + if (!fs) { + _mesa_error(NULL, GL_INVALID_VALUE, + "Couldn't get font structure information"); + return; + } + + /* Allocate a bitmap that can fit all characters. */ + max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing; + max_height = fs->max_bounds.ascent + fs->max_bounds.descent; + max_bm_width = (max_width + 7) / 8; + max_bm_height = max_height; + + bm = (GLubyte *) MALLOC((max_bm_width * max_bm_height) * sizeof(GLubyte)); + if (!bm) { + XFreeFontInfo(NULL, fs, 1); + _mesa_error(NULL, GL_OUT_OF_MEMORY, + "Couldn't allocate bitmap in glXUseXFont()"); + return; + } + +#if 0 + /* get the page info */ + pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; + firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2; + lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2; + rows = fs->max_byte1 - fs->min_byte1 + 1; + unsigned int first_char, last_char, pages, rows; +#endif + + /* Save the current packing mode for bitmaps. */ + glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes); + glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst); + glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength); + glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows); + glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels); + glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); + + /* Enforce a standard packing mode which is compatible with + fill_bitmap() from above. This is actually the default mode, + except for the (non)alignment. */ + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + pixmap = XCreatePixmap(dpy, win, 10, 10, 1); + values.foreground = BlackPixel(dpy, DefaultScreen(dpy)); + values.background = WhitePixel(dpy, DefaultScreen(dpy)); + values.font = fs->fid; + valuemask = GCForeground | GCBackground | GCFont; + gc = XCreateGC(dpy, pixmap, valuemask, &values); + XFreePixmap(dpy, pixmap); + +#ifdef DEBUG + if (debug_xfonts) + dump_font_struct(fs); +#endif + + for (i = 0; i < count; i++) { + unsigned int width, height, bm_width, bm_height; + GLfloat x0, y0, dx, dy; + XCharStruct *ch; + int x, y; + unsigned int c = first + i; + int list = listbase + i; + int valid; + + /* check on index validity and get the bounds */ + ch = isvalid(fs, c); + if (!ch) { + ch = &fs->max_bounds; + valid = 0; + } + else { + valid = 1; + } + +#ifdef DEBUG + if (debug_xfonts) { + char s[7]; + sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c); + dump_char_struct(ch, s); + } +#endif + + /* glBitmap()' parameters: + straight from the glXUseXFont(3) manpage. */ + width = ch->rbearing - ch->lbearing; + height = ch->ascent + ch->descent; + x0 = -ch->lbearing; + y0 = ch->descent - 0; /* XXX used to subtract 1 here */ + /* but that caused a conformace failure */ + dx = ch->width; + dy = 0; + + /* X11's starting point. */ + x = -ch->lbearing; + y = ch->ascent; + + /* Round the width to a multiple of eight. We will use this also + for the pixmap for capturing the X11 font. This is slightly + inefficient, but it makes the OpenGL part real easy. */ + bm_width = (width + 7) / 8; + bm_height = height; + + glNewList(list, GL_COMPILE); + if (valid && (bm_width > 0) && (bm_height > 0)) { + + MEMSET(bm, '\0', bm_width * bm_height); + fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm); + + glBitmap(width, height, x0, y0, dx, dy, bm); +#ifdef DEBUG + if (debug_xfonts) { + printf("width/height = %u/%u\n", width, height); + printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height); + dump_bitmap(bm_width, bm_height, bm); + } +#endif + } + else { + glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL); + } + glEndList(); + } + + FREE(bm); + XFreeFontInfo(NULL, fs, 1); + XFreeGC(dpy, gc); + + /* Restore saved packing modes. */ + glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); + glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst); + glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength); + glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); + glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); +} diff --git a/src/gallium/winsys/xlib/xfonts.h b/src/gallium/winsys/xlib/xfonts.h new file mode 100644 index 0000000000..e36f42f817 --- /dev/null +++ b/src/gallium/winsys/xlib/xfonts.h @@ -0,0 +1,41 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + + +#ifndef XFONTS_H +#define XFONTS_H + +#ifdef __VMS +#include +#endif + +#include + + +extern void Fake_glXUseXFont( Font font, int first, int count, int listbase ); + + +#endif + diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c new file mode 100644 index 0000000000..e5fef1d7a8 --- /dev/null +++ b/src/gallium/winsys/xlib/xm_api.c @@ -0,0 +1,1380 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + +/** + * \file xm_api.c + * + * All the XMesa* API functions. + * + * + * NOTES: + * + * The window coordinate system origin (0,0) is in the lower-left corner + * of the window. X11's window coordinate origin is in the upper-left + * corner of the window. Therefore, most drawing functions in this + * file have to flip Y coordinates. + * + * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile + * in support for the MIT Shared Memory extension. If enabled, when you + * use an Ximage for the back buffer in double buffered mode, the "swap" + * operation will be faster. You must also link with -lXext. + * + * Byte swapping: If the Mesa host and the X display use a different + * byte order then there's some trickiness to be aware of when using + * XImages. The byte ordering used for the XImage is that of the X + * display, not the Mesa host. + * The color-to-pixel encoding for True/DirectColor must be done + * according to the display's visual red_mask, green_mask, and blue_mask. + * If XPutPixel is used to put a pixel into an XImage then XPutPixel will + * do byte swapping if needed. If one wants to directly "poke" the pixel + * into the XImage's buffer then the pixel must be byte swapped first. + * + */ + +#ifdef __CYGWIN__ +#undef WIN32 +#undef __WIN32__ +#endif + +#include "glxheader.h" +#include "GL/xmesa.h" +#include "xmesaP.h" +#include "main/context.h" +#include "main/framebuffer.h" +#include "glapi/glthread.h" + +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" + +#include "xm_winsys_aub.h" + +/** + * Global X driver lock + */ +_glthread_Mutex _xmesa_lock; + + +int xmesa_mode; + + +/**********************************************************************/ +/***** X Utility Functions *****/ +/**********************************************************************/ + + +/** + * Return the host's byte order as LSBFirst or MSBFirst ala X. + */ +#ifndef XFree86Server +static int host_byte_order( void ) +{ + int i = 1; + char *cptr = (char *) &i; + return (*cptr==1) ? LSBFirst : MSBFirst; +} +#endif + + +/** + * Check if the X Shared Memory extension is available. + * Return: 0 = not available + * 1 = shared XImage support available + * 2 = shared Pixmap support available also + */ +static int check_for_xshm( XMesaDisplay *display ) +{ +#if defined(USE_XSHM) && !defined(XFree86Server) + int major, minor, ignore; + Bool pixmaps; + + if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { + if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { + return (pixmaps==True) ? 2 : 1; + } + else { + return 0; + } + } + else { + return 0; + } +#else + /* No XSHM support */ + return 0; +#endif +} + + +/** + * Return the true number of bits per pixel for XImages. + * For example, if we request a 24-bit deep visual we may actually need/get + * 32bpp XImages. This function returns the appropriate bpp. + * Input: dpy - the X display + * visinfo - desribes the visual to be used for XImages + * Return: true number of bits per pixel for XImages + */ +static int +bits_per_pixel( XMesaVisual xmv ) +{ +#ifdef XFree86Server + const int depth = xmv->nplanes; + int i; + assert(depth > 0); + for (i = 0; i < screenInfo.numPixmapFormats; i++) { + if (screenInfo.formats[i].depth == depth) + return screenInfo.formats[i].bitsPerPixel; + } + return depth; /* should never get here, but this should be safe */ +#else + XMesaDisplay *dpy = xmv->display; + XMesaVisualInfo visinfo = xmv->visinfo; + XMesaImage *img; + int bitsPerPixel; + /* Create a temporary XImage */ + img = XCreateImage( dpy, visinfo->visual, visinfo->depth, + ZPixmap, 0, /*format, offset*/ + (char*) MALLOC(8), /*data*/ + 1, 1, /*width, height*/ + 32, /*bitmap_pad*/ + 0 /*bytes_per_line*/ + ); + assert(img); + /* grab the bits/pixel value */ + bitsPerPixel = img->bits_per_pixel; + /* free the XImage */ + _mesa_free( img->data ); + img->data = NULL; + XMesaDestroyImage( img ); + return bitsPerPixel; +#endif +} + + + +/* + * Determine if a given X window ID is valid (window exists). + * Do this by calling XGetWindowAttributes() for the window and + * checking if we catch an X error. + * Input: dpy - the display + * win - the window to check for existance + * Return: GL_TRUE - window exists + * GL_FALSE - window doesn't exist + */ +#ifndef XFree86Server +static GLboolean WindowExistsFlag; + +static int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr ) +{ + (void) dpy; + if (xerr->error_code == BadWindow) { + WindowExistsFlag = GL_FALSE; + } + return 0; +} + +static GLboolean window_exists( XMesaDisplay *dpy, Window win ) +{ + XWindowAttributes wa; + int (*old_handler)( XMesaDisplay*, XErrorEvent* ); + WindowExistsFlag = GL_TRUE; + old_handler = XSetErrorHandler(window_exists_err_handler); + XGetWindowAttributes( dpy, win, &wa ); /* dummy request */ + XSetErrorHandler(old_handler); + return WindowExistsFlag; +} + +static Status +get_drawable_size( XMesaDisplay *dpy, Drawable d, uint *width, uint *height ) +{ + Window root; + Status stat; + int xpos, ypos; + unsigned int w, h, bw, depth; + stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); + *width = w; + *height = h; + return stat; +} +#endif + + +/** + * Return the size of the window (or pixmap) that corresponds to the + * given XMesaBuffer. + * \param width returns width in pixels + * \param height returns height in pixels + */ +static void +xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b, + GLuint *width, GLuint *height) +{ +#ifdef XFree86Server + *width = MIN2(b->drawable->width, MAX_WIDTH); + *height = MIN2(b->drawable->height, MAX_HEIGHT); +#else + Status stat; + + _glthread_LOCK_MUTEX(_xmesa_lock); + XSync(b->xm_visual->display, 0); /* added for Chromium */ + stat = get_drawable_size(dpy, b->drawable, width, height); + _glthread_UNLOCK_MUTEX(_xmesa_lock); + + if (!stat) { + /* probably querying a window that's recently been destroyed */ + _mesa_warning(NULL, "XGetGeometry failed!\n"); + *width = *height = 1; + } +#endif +} + + +/** + * Choose the pixel format for the given visual. + * This will tell the gallium driver how to pack pixel data into + * drawing surfaces. + */ +static GLuint +choose_pixel_format(XMesaVisual v) +{ + if ( GET_REDMASK(v) == 0x0000ff + && GET_GREENMASK(v) == 0x00ff00 + && GET_BLUEMASK(v) == 0xff0000 + && v->BitsPerPixel == 32) { + if (CHECK_BYTE_ORDER(v)) { + /* no byteswapping needed */ + return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */; + } + else { + return PIPE_FORMAT_R8G8B8A8_UNORM; + } + } + else if ( GET_REDMASK(v) == 0xff0000 + && GET_GREENMASK(v) == 0x00ff00 + && GET_BLUEMASK(v) == 0x0000ff + && v->BitsPerPixel == 32) { + if (CHECK_BYTE_ORDER(v)) { + /* no byteswapping needed */ + return PIPE_FORMAT_A8R8G8B8_UNORM; + } + else { + return PIPE_FORMAT_B8G8R8A8_UNORM; + } + } + else if ( GET_REDMASK(v) == 0xf800 + && GET_GREENMASK(v) == 0x07e0 + && GET_BLUEMASK(v) == 0x001f + && CHECK_BYTE_ORDER(v) + && v->BitsPerPixel == 16) { + /* 5-6-5 RGB */ + return PIPE_FORMAT_R5G6B5_UNORM; + } + + assert(0); + return 0; +} + + + +/**********************************************************************/ +/***** Linked list of XMesaBuffers *****/ +/**********************************************************************/ + +XMesaBuffer XMesaBufferList = NULL; + + +/** + * Allocate a new XMesaBuffer object which corresponds to the given drawable. + * Note that XMesaBuffer is derived from GLframebuffer. + * The new XMesaBuffer will not have any size (Width=Height=0). + * + * \param d the corresponding X drawable (window or pixmap) + * \param type either WINDOW, PIXMAP or PBUFFER, describing d + * \param vis the buffer's visual + * \param cmap the window's colormap, if known. + * \return new XMesaBuffer or NULL if any problem + */ +static XMesaBuffer +create_xmesa_buffer(XMesaDrawable d, BufferType type, + XMesaVisual vis, XMesaColormap cmap) +{ + XMesaBuffer b; + GLframebuffer *fb; + enum pipe_format colorFormat, depthFormat, stencilFormat; + uint width, height; + + ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER); + + b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer); + if (!b) + return NULL; + + b->drawable = d; + + b->xm_visual = vis; + b->type = type; + b->cmap = cmap; + + /* determine PIPE_FORMATs for buffers */ + colorFormat = choose_pixel_format(vis); + + if (vis->mesa_visual.depthBits == 0) + depthFormat = PIPE_FORMAT_NONE; + else if (vis->mesa_visual.depthBits <= 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (vis->mesa_visual.depthBits <= 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_Z32_UNORM; + + if (vis->mesa_visual.stencilBits == 8) { + if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) + stencilFormat = depthFormat; + else + stencilFormat = PIPE_FORMAT_S8_UNORM; + } + else { + stencilFormat = PIPE_FORMAT_NONE; + } + + + get_drawable_size(vis->display, d, &width, &height); + + /* + * Create framebuffer, but we'll plug in our own renderbuffers below. + */ + b->stfb = st_create_framebuffer(&vis->mesa_visual, + colorFormat, depthFormat, stencilFormat, + width, height, + (void *) b); + fb = &b->stfb->Base; + + /* + * Create scratch XImage for xmesa_display_surface() + */ + b->tempImage = XCreateImage(vis->display, + vis->visinfo->visual, + vis->visinfo->depth, + ZPixmap, 0, /* format, offset */ + NULL, /* data */ + 0, 0, /* size */ + 32, /* bitmap_pad */ + 0); /* bytes_per_line */ + + /* GLX_EXT_texture_from_pixmap */ + b->TextureTarget = 0; + b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT; + b->TextureMipmap = 0; + + /* insert buffer into linked list */ + b->Next = XMesaBufferList; + XMesaBufferList = b; + + return b; +} + + +/** + * Find an XMesaBuffer by matching X display and colormap but NOT matching + * the notThis buffer. + */ +XMesaBuffer +xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis) +{ + XMesaBuffer b; + for (b = XMesaBufferList; b; b = b->Next) { + if (b->xm_visual->display == dpy && + b->cmap == cmap && + b != notThis) { + return b; + } + } + return NULL; +} + + +/** + * Remove buffer from linked list, delete if no longer referenced. + */ +static void +xmesa_free_buffer(XMesaBuffer buffer) +{ + XMesaBuffer prev = NULL, b; + + for (b = XMesaBufferList; b; b = b->Next) { + if (b == buffer) { + struct gl_framebuffer *fb = &buffer->stfb->Base; + + /* unlink buffer from list */ + if (prev) + prev->Next = buffer->Next; + else + XMesaBufferList = buffer->Next; + + /* mark as delete pending */ + fb->DeletePending = GL_TRUE; + + /* Since the X window for the XMesaBuffer is going away, we don't + * want to dereference this pointer in the future. + */ + b->drawable = 0; + + buffer->tempImage->data = NULL; + XDestroyImage(buffer->tempImage); + + /* Unreference. If count = zero we'll really delete the buffer */ + _mesa_unreference_framebuffer(&fb); + + XFreeGC(b->xm_visual->display, b->gc); + + free(buffer); + + return; + } + /* continue search */ + prev = b; + } + /* buffer not found in XMesaBufferList */ + _mesa_problem(NULL,"xmesa_free_buffer() - buffer not found\n"); +} + + + +/**********************************************************************/ +/***** Misc Private Functions *****/ +/**********************************************************************/ + + +/** + * When a context is bound for the first time, we can finally finish + * initializing the context's visual and buffer information. + * \param v the XMesaVisual to initialize + * \param b the XMesaBuffer to initialize (may be NULL) + * \param rgb_flag TRUE = RGBA mode, FALSE = color index mode + * \param window the window/pixmap we're rendering into + * \param cmap the colormap associated with the window/pixmap + * \return GL_TRUE=success, GL_FALSE=failure + */ +static GLboolean +initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, + GLboolean rgb_flag, XMesaDrawable window, + XMesaColormap cmap) +{ +#ifdef XFree86Server + int client = (window) ? CLIENT_ID(window->id) : 0; +#endif + + ASSERT(!b || b->xm_visual == v); + + /* Save true bits/pixel */ + v->BitsPerPixel = bits_per_pixel(v); + assert(v->BitsPerPixel > 0); + + if (rgb_flag == GL_FALSE) { + /* COLOR-INDEXED WINDOW: not supported*/ + return GL_FALSE; + } + else { + /* RGB WINDOW: + * We support RGB rendering into almost any kind of visual. + */ + const int xclass = v->mesa_visual.visualType; + if (xclass != GLX_TRUE_COLOR && xclass == !GLX_DIRECT_COLOR) { + _mesa_warning(NULL, + "XMesa: RGB mode rendering not supported in given visual.\n"); + return GL_FALSE; + } + v->mesa_visual.indexBits = 0; + } + + /* + * If MESA_INFO env var is set print out some debugging info + * which can help Brian figure out what's going on when a user + * reports bugs. + */ + if (_mesa_getenv("MESA_INFO")) { + _mesa_printf("X/Mesa visual = %p\n", (void *) v); + _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level); + _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v)); + _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); + } + + if (b && window) { + /* these should have been set in create_xmesa_buffer */ + ASSERT(b->drawable == window); + + /* Setup for single/double buffering */ + if (v->mesa_visual.doubleBufferMode) { + /* Double buffered */ + b->shm = check_for_xshm( v->display ); + } + + /* X11 graphics context */ +#ifdef XFree86Server + b->gc = CreateScratchGC(v->display, window->depth); +#else + b->gc = XCreateGC( v->display, window, 0, NULL ); +#endif + XMesaSetFunction( v->display, b->gc, GXcopy ); + } + + return GL_TRUE; +} + + + +#define NUM_VISUAL_TYPES 6 + +/** + * Convert an X visual type to a GLX visual type. + * + * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) + * to be converted. + * \return If \c visualType is a valid X visual type, a GLX visual type will + * be returned. Otherwise \c GLX_NONE will be returned. + * + * \note + * This code was lifted directly from lib/GL/glx/glcontextmodes.c in the + * DRI CVS tree. + */ +static GLint +xmesa_convert_from_x_visual_type( int visualType ) +{ + static const int glx_visual_types[ NUM_VISUAL_TYPES ] = { + GLX_STATIC_GRAY, GLX_GRAY_SCALE, + GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, + GLX_TRUE_COLOR, GLX_DIRECT_COLOR + }; + + return ( (unsigned) visualType < NUM_VISUAL_TYPES ) + ? glx_visual_types[ visualType ] : GLX_NONE; +} + + +/**********************************************************************/ +/***** Public Functions *****/ +/**********************************************************************/ + + +/* + * Create a new X/Mesa visual. + * Input: display - X11 display + * visinfo - an XVisualInfo pointer + * rgb_flag - GL_TRUE = RGB mode, + * GL_FALSE = color index mode + * alpha_flag - alpha buffer requested? + * db_flag - GL_TRUE = double-buffered, + * GL_FALSE = single buffered + * stereo_flag - stereo visual? + * ximage_flag - GL_TRUE = use an XImage for back buffer, + * GL_FALSE = use an off-screen pixmap for back buffer + * depth_size - requested bits/depth values, or zero + * stencil_size - requested bits/stencil values, or zero + * accum_red_size - requested bits/red accum values, or zero + * accum_green_size - requested bits/green accum values, or zero + * accum_blue_size - requested bits/blue accum values, or zero + * accum_alpha_size - requested bits/alpha accum values, or zero + * num_samples - number of samples/pixel if multisampling, or zero + * level - visual level, usually 0 + * visualCaveat - ala the GLX extension, usually GLX_NONE + * Return; a new XMesaVisual or 0 if error. + */ +PUBLIC +XMesaVisual XMesaCreateVisual( XMesaDisplay *display, + XMesaVisualInfo visinfo, + GLboolean rgb_flag, + GLboolean alpha_flag, + GLboolean db_flag, + GLboolean stereo_flag, + GLboolean ximage_flag, + GLint depth_size, + GLint stencil_size, + GLint accum_red_size, + GLint accum_green_size, + GLint accum_blue_size, + GLint accum_alpha_size, + GLint num_samples, + GLint level, + GLint visualCaveat ) +{ + XMesaVisual v; + GLint red_bits, green_bits, blue_bits, alpha_bits; + +#ifndef XFree86Server + /* For debugging only */ + if (_mesa_getenv("MESA_XSYNC")) { + /* This makes debugging X easier. + * In your debugger, set a breakpoint on _XError to stop when an + * X protocol error is generated. + */ + XSynchronize( display, 1 ); + } +#endif + + v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual); + if (!v) { + return NULL; + } + + v->display = display; + + /* Save a copy of the XVisualInfo struct because the user may X_mesa_free() + * the struct but we may need some of the information contained in it + * at a later time. + */ +#ifndef XFree86Server + v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo)); + if(!v->visinfo) { + _mesa_free(v); + return NULL; + } + MEMCPY(v->visinfo, visinfo, sizeof(*visinfo)); +#endif + + v->ximage_flag = ximage_flag; + +#ifdef XFree86Server + /* We could calculate these values by ourselves. nplanes is either the sum + * of the red, green, and blue bits or the number index bits. + * ColormapEntries is either (1U << index_bits) or + * (1U << max(redBits, greenBits, blueBits)). + */ + assert(visinfo->nplanes > 0); + v->nplanes = visinfo->nplanes; + v->ColormapEntries = visinfo->ColormapEntries; + + v->mesa_visual.redMask = visinfo->redMask; + v->mesa_visual.greenMask = visinfo->greenMask; + v->mesa_visual.blueMask = visinfo->blueMask; + v->mesa_visual.visualID = visinfo->vid; + v->mesa_visual.screen = 0; /* FIXME: What should be done here? */ +#else + v->mesa_visual.redMask = visinfo->red_mask; + v->mesa_visual.greenMask = visinfo->green_mask; + v->mesa_visual.blueMask = visinfo->blue_mask; + v->mesa_visual.visualID = visinfo->visualid; + v->mesa_visual.screen = visinfo->screen; +#endif + +#if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus)) + v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class); +#else + v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class); +#endif + + v->mesa_visual.visualRating = visualCaveat; + + if (alpha_flag) + v->mesa_visual.alphaBits = 8; + + (void) initialize_visual_and_buffer( v, NULL, rgb_flag, 0, 0 ); + + { + const int xclass = v->mesa_visual.visualType; + if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { + red_bits = _mesa_bitcount(GET_REDMASK(v)); + green_bits = _mesa_bitcount(GET_GREENMASK(v)); + blue_bits = _mesa_bitcount(GET_BLUEMASK(v)); + } + else { + /* this is an approximation */ + int depth; + depth = GET_VISUAL_DEPTH(v); + red_bits = depth / 3; + depth -= red_bits; + green_bits = depth / 2; + depth -= green_bits; + blue_bits = depth; + alpha_bits = 0; + assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) ); + } + alpha_bits = v->mesa_visual.alphaBits; + } + + _mesa_initialize_visual( &v->mesa_visual, + rgb_flag, db_flag, stereo_flag, + red_bits, green_bits, + blue_bits, alpha_bits, + v->mesa_visual.indexBits, + depth_size, + stencil_size, + accum_red_size, accum_green_size, + accum_blue_size, accum_alpha_size, + 0 ); + + /* XXX minor hack */ + v->mesa_visual.level = level; + return v; +} + + +PUBLIC +void XMesaDestroyVisual( XMesaVisual v ) +{ +#ifndef XFree86Server + _mesa_free(v->visinfo); +#endif + _mesa_free(v); +} + + + +/** + * Create a new XMesaContext. + * \param v the XMesaVisual + * \param share_list another XMesaContext with which to share display + * lists or NULL if no sharing is wanted. + * \return an XMesaContext or NULL if error. + */ +PUBLIC +XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) +{ + static GLboolean firstTime = GL_TRUE; + struct pipe_context *pipe; + XMesaContext c; + GLcontext *mesaCtx; + uint pf; + + if (firstTime) { + _glthread_INIT_MUTEX(_xmesa_lock); + firstTime = GL_FALSE; + } + + /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */ + c = (XMesaContext) CALLOC_STRUCT(xmesa_context); + if (!c) + return NULL; + + pf = choose_pixel_format(v); + assert(pf); + + if (!getenv("XM_AUB")) { + xmesa_mode = XMESA_SOFTPIPE; + pipe = xmesa_create_pipe_context( c, pf ); + } + else { + xmesa_mode = XMESA_AUB; + pipe = xmesa_create_i965simple( xmesa_get_pipe_winsys_aub() ); + } + + c->st = st_create_context(pipe, &v->mesa_visual, + share_list ? share_list->st : NULL); + mesaCtx = c->st->ctx; + c->st->ctx->DriverCtx = c; + +#if 00 + _mesa_enable_sw_extensions(mesaCtx); + _mesa_enable_1_3_extensions(mesaCtx); + _mesa_enable_1_4_extensions(mesaCtx); + _mesa_enable_1_5_extensions(mesaCtx); + _mesa_enable_2_0_extensions(mesaCtx); +#endif + +#ifdef XFree86Server + /* If we're running in the X server, do bounds checking to prevent + * segfaults and server crashes! + */ + mesaCtx->Const.CheckArrayBounds = GL_TRUE; +#endif + + /* finish up xmesa context initializations */ + c->xm_visual = v; + c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ + + c->st->haveFramebufferSurfaces = GL_TRUE; + + return c; +} + + + +PUBLIC +void XMesaDestroyContext( XMesaContext c ) +{ + st_destroy_context(c->st); + _mesa_free(c); +} + + + +/** + * Private function for creating an XMesaBuffer which corresponds to an + * X window or pixmap. + * \param v the window's XMesaVisual + * \param w the window we're wrapping + * \return new XMesaBuffer or NULL if error + */ +PUBLIC XMesaBuffer +XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w) +{ +#ifndef XFree86Server + XWindowAttributes attr; +#endif + XMesaBuffer b; + XMesaColormap cmap; + int depth; + + assert(v); + assert(w); + + /* Check that window depth matches visual depth */ +#ifdef XFree86Server + depth = ((XMesaDrawable)w)->depth; +#else + XGetWindowAttributes( v->display, w, &attr ); + depth = attr.depth; +#endif + if (GET_VISUAL_DEPTH(v) != depth) { + _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n", + GET_VISUAL_DEPTH(v), depth); + return NULL; + } + + /* Find colormap */ +#ifdef XFree86Server + cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP); +#else + if (attr.colormap) { + cmap = attr.colormap; + } + else { + _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w); + /* this is weird, a window w/out a colormap!? */ + /* OK, let's just allocate a new one and hope for the best */ + cmap = XCreateColormap(v->display, w, attr.visual, AllocNone); + } +#endif + + b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap); + if (!b) + return NULL; + + if (!initialize_visual_and_buffer( v, b, v->mesa_visual.rgbMode, + (XMesaDrawable) w, cmap )) { + xmesa_free_buffer(b); + return NULL; + } + + return b; +} + + + +/** + * Create a new XMesaBuffer from an X pixmap. + * + * \param v the XMesaVisual + * \param p the pixmap + * \param cmap the colormap, may be 0 if using a \c GLX_TRUE_COLOR or + * \c GLX_DIRECT_COLOR visual for the pixmap + * \returns new XMesaBuffer or NULL if error + */ +PUBLIC XMesaBuffer +XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap) +{ + XMesaBuffer b; + + assert(v); + + b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap); + if (!b) + return NULL; + + if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, + (XMesaDrawable) p, cmap)) { + xmesa_free_buffer(b); + return NULL; + } + + return b; +} + + +/** + * For GLX_EXT_texture_from_pixmap + */ +XMesaBuffer +XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p, + XMesaColormap cmap, + int format, int target, int mipmap) +{ + GET_CURRENT_CONTEXT(ctx); + XMesaBuffer b; + GLuint width, height; + + assert(v); + + b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap); + if (!b) + return NULL; + + /* get pixmap size, update framebuffer/renderbuffer dims */ + xmesa_get_window_size(v->display, b, &width, &height); + _mesa_resize_framebuffer(NULL, &(b->stfb->Base), width, height); + + if (target == 0) { + /* examine dims */ + if (ctx->Extensions.ARB_texture_non_power_of_two) { + target = GLX_TEXTURE_2D_EXT; + } + else if ( _mesa_bitcount(width) == 1 + && _mesa_bitcount(height) == 1) { + /* power of two size */ + if (height == 1) { + target = GLX_TEXTURE_1D_EXT; + } + else { + target = GLX_TEXTURE_2D_EXT; + } + } + else if (ctx->Extensions.NV_texture_rectangle) { + target = GLX_TEXTURE_RECTANGLE_EXT; + } + else { + /* non power of two textures not supported */ + XMesaDestroyBuffer(b); + return 0; + } + } + + b->TextureTarget = target; + b->TextureFormat = format; + b->TextureMipmap = mipmap; + + if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, + (XMesaDrawable) p, cmap)) { + xmesa_free_buffer(b); + return NULL; + } + + return b; +} + + + +XMesaBuffer +XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, + unsigned int width, unsigned int height) +{ +#ifndef XFree86Server + XMesaWindow root; + XMesaDrawable drawable; /* X Pixmap Drawable */ + XMesaBuffer b; + + /* allocate pixmap for front buffer */ + root = RootWindow( v->display, v->visinfo->screen ); + drawable = XCreatePixmap(v->display, root, width, height, + v->visinfo->depth); + if (!drawable) + return NULL; + + b = create_xmesa_buffer(drawable, PBUFFER, v, cmap); + if (!b) + return NULL; + + if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, + drawable, cmap)) { + xmesa_free_buffer(b); + return NULL; + } + + return b; +#else + return 0; +#endif +} + + + +/* + * Deallocate an XMesaBuffer structure and all related info. + */ +PUBLIC void +XMesaDestroyBuffer(XMesaBuffer b) +{ + xmesa_free_buffer(b); +} + + +/** + * Query the current window size and update the corresponding GLframebuffer + * and all attached renderbuffers. + * Called when: + * 1. the first time a buffer is bound to a context. + * 2. from the XMesaResizeBuffers() API function. + * 3. SwapBuffers. XXX probabaly from xm_flush_frontbuffer() too... + * Note: it's possible (and legal) for xmctx to be NULL. That can happen + * when resizing a buffer when no rendering context is bound. + */ +void +xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer) +{ + GLuint width, height; + xmesa_get_window_size(drawBuffer->xm_visual->display, drawBuffer, &width, &height); + st_resize_framebuffer(drawBuffer->stfb, width, height); +} + + +/* + * Bind buffer b to context c and make c the current rendering context. + */ +GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b ) +{ + return XMesaMakeCurrent2( c, b, b ); +} + + +/* + * Bind buffer b to context c and make c the current rendering context. + */ +PUBLIC +GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, + XMesaBuffer readBuffer ) +{ + if (c) { + if (!drawBuffer || !readBuffer) + return GL_FALSE; /* must specify buffers! */ + +#if 0 + /* XXX restore this optimization */ + if (&(c->mesa) == _mesa_get_current_context() + && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer + && c->mesa.ReadBuffer == &readBuffer->mesa_buffer + && xmesa_buffer(c->mesa.DrawBuffer)->wasCurrent) { + /* same context and buffer, do nothing */ + return GL_TRUE; + } +#endif + + c->xm_buffer = drawBuffer; + + /* Call this periodically to detect when the user has begun using + * GL rendering from multiple threads. + */ + _glapi_check_multithread(); + + st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb); + + xmesa_check_and_update_buffer_size(c, drawBuffer); + if (readBuffer != drawBuffer) + xmesa_check_and_update_buffer_size(c, readBuffer); + + /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */ + drawBuffer->wasCurrent = GL_TRUE; + } + else { + /* Detach */ + st_make_current( NULL, NULL, NULL ); + } + return GL_TRUE; +} + + +/* + * Unbind the context c from its buffer. + */ +GLboolean XMesaUnbindContext( XMesaContext c ) +{ + /* A no-op for XFree86 integration purposes */ + return GL_TRUE; +} + + +XMesaContext XMesaGetCurrentContext( void ) +{ + GET_CURRENT_CONTEXT(ctx); + if (ctx) { + XMesaContext xmesa = xmesa_context(ctx); + return xmesa; + } + else { + return 0; + } +} + + +XMesaBuffer XMesaGetCurrentBuffer( void ) +{ + GET_CURRENT_CONTEXT(ctx); + if (ctx) { + XMesaBuffer xmbuf = xmesa_buffer(ctx->DrawBuffer); + return xmbuf; + } + else { + return 0; + } +} + + +/* New in Mesa 3.1 */ +XMesaBuffer XMesaGetCurrentReadBuffer( void ) +{ + GET_CURRENT_CONTEXT(ctx); + if (ctx) { + return xmesa_buffer(ctx->ReadBuffer); + } + else { + return 0; + } +} + + +#ifdef XFree86Server +PUBLIC +GLboolean XMesaForceCurrent(XMesaContext c) +{ + if (c) { + _glapi_set_dispatch(c->mesa.CurrentDispatch); + + if (&(c->mesa) != _mesa_get_current_context()) { + _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer); + } + } + else { + _mesa_make_current(NULL, NULL, NULL); + } + return GL_TRUE; +} + + +PUBLIC +GLboolean XMesaLoseCurrent(XMesaContext c) +{ + (void) c; + _mesa_make_current(NULL, NULL, NULL); + return GL_TRUE; +} + + +PUBLIC +GLboolean XMesaCopyContext( XMesaContext xm_src, XMesaContext xm_dst, GLuint mask ) +{ + _mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask); + return GL_TRUE; +} +#endif /* XFree86Server */ + + +#ifndef FX +GLboolean XMesaSetFXmode( GLint mode ) +{ + (void) mode; + return GL_FALSE; +} +#endif + + + +/* + * Copy the back buffer to the front buffer. If there's no back buffer + * this is a no-op. + */ +PUBLIC +void XMesaSwapBuffers( XMesaBuffer b ) +{ + struct pipe_surface *surf; + + /* If we're swapping the buffer associated with the current context + * we have to flush any pending rendering commands first. + */ + st_notify_swapbuffers(b->stfb); + + surf = st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT); + if (surf) { + if (xmesa_mode == XMESA_AUB) + xmesa_display_aub( surf ); + else + xmesa_display_surface(b, surf); + } + + xmesa_check_and_update_buffer_size(NULL, b); +} + + + +/* + * Copy sub-region of back buffer to front buffer + */ +void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height ) +{ + struct pipe_surface *surf_front + = st_get_framebuffer_surface(b->stfb, ST_SURFACE_FRONT_LEFT); + struct pipe_surface *surf_back + = st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT); + struct pipe_context *pipe = NULL; /* XXX fix */ + + if (!surf_front || !surf_back) + return; + + pipe->surface_copy(pipe, + FALSE, + surf_front, x, y, /* dest */ + surf_back, x, y, /* src */ + width, height); +} + + + +/* + * Return the depth buffer associated with an XMesaBuffer. + * Input: b - the XMesa buffer handle + * Output: width, height - size of buffer in pixels + * bytesPerValue - bytes per depth value (2 or 4) + * buffer - pointer to depth buffer values + * Return: GL_TRUE or GL_FALSE to indicate success or failure. + */ +GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height, + GLint *bytesPerValue, void **buffer ) +{ + *width = 0; + *height = 0; + *bytesPerValue = 0; + *buffer = 0; + return GL_FALSE; +} + + +void XMesaFlush( XMesaContext c ) +{ + if (c && c->xm_visual->display) { +#ifdef XFree86Server + /* NOT_NEEDED */ +#else + XSync( c->xm_visual->display, False ); +#endif + } +} + + + +const char *XMesaGetString( XMesaContext c, int name ) +{ + (void) c; + if (name==XMESA_VERSION) { + return "5.0"; + } + else if (name==XMESA_EXTENSIONS) { + return ""; + } + else { + return NULL; + } +} + + + +XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d ) +{ + XMesaBuffer b; + for (b=XMesaBufferList; b; b=b->Next) { + if (b->drawable == d && b->xm_visual->display == dpy) { + return b; + } + } + return NULL; +} + + +/** + * Free/destroy all XMesaBuffers associated with given display. + */ +void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy) +{ + XMesaBuffer b, next; + for (b = XMesaBufferList; b; b = next) { + next = b->Next; + if (b->xm_visual->display == dpy) { + xmesa_free_buffer(b); + } + } +} + + +/* + * Look for XMesaBuffers whose X window has been destroyed. + * Deallocate any such XMesaBuffers. + */ +void XMesaGarbageCollect( void ) +{ + XMesaBuffer b, next; + for (b=XMesaBufferList; b; b=next) { + next = b->Next; + if (b->xm_visual && + b->xm_visual->display && + b->drawable && + b->type == WINDOW) { +#ifdef XFree86Server + /* NOT_NEEDED */ +#else + XSync(b->xm_visual->display, False); + if (!window_exists( b->xm_visual->display, b->drawable )) { + /* found a dead window, free the ancillary info */ + XMesaDestroyBuffer( b ); + } +#endif + } + } +} + + +unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y, + GLfloat red, GLfloat green, + GLfloat blue, GLfloat alpha ) +{ + /* no longer supported */ + return 0; +} + + +/* + * This is typically called when the window size changes and we need + * to reallocate the buffer's back/depth/stencil/accum buffers. + */ +PUBLIC void +XMesaResizeBuffers( XMesaBuffer b ) +{ + GET_CURRENT_CONTEXT(ctx); + XMesaContext xmctx = xmesa_context(ctx); + if (!xmctx) + return; + xmesa_check_and_update_buffer_size(xmctx, b); +} + + + + +PUBLIC void +XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer, + const int *attrib_list) +{ +} + + + +PUBLIC void +XMesaReleaseTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer) +{ +} + diff --git a/src/gallium/winsys/xlib/xm_image.c b/src/gallium/winsys/xlib/xm_image.c new file mode 100644 index 0000000000..087b4e4c3a --- /dev/null +++ b/src/gallium/winsys/xlib/xm_image.c @@ -0,0 +1,133 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Brian Paul + */ + +#include +#include + +#include "glxheader.h" +#include "xmesaP.h" + +#ifdef XFree86Server + +#ifdef ROUNDUP +#undef ROUNDUP +#endif + +#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3)) + +XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height, char *data) +{ + XMesaImage *image; + + image = (XMesaImage *)xalloc(sizeof(XMesaImage)); + + if (image) { + image->width = width; + image->height = height; + image->data = data; + /* Always pad to 32 bits */ + image->bytes_per_line = ROUNDUP((bitsPerPixel * width), 32); + image->bits_per_pixel = bitsPerPixel; + } + + return image; +} + +void XMesaDestroyImage(XMesaImage *image) +{ + if (image->data) + free(image->data); + xfree(image); +} + +unsigned long XMesaGetPixel(XMesaImage *image, int x, int y) +{ + CARD8 *row = (CARD8 *)(image->data + y*image->bytes_per_line); + CARD8 *i8; + CARD16 *i16; + CARD32 *i32; + switch (image->bits_per_pixel) { + case 8: + i8 = (CARD8 *)row; + return i8[x]; + break; + case 15: + case 16: + i16 = (CARD16 *)row; + return i16[x]; + break; + case 24: /* WARNING: architecture specific code */ + i8 = (CARD8 *)row; + return (((CARD32)i8[x*3]) | + (((CARD32)i8[x*3+1])<<8) | + (((CARD32)i8[x*3+2])<<16)); + break; + case 32: + i32 = (CARD32 *)row; + return i32[x]; + break; + } + return 0; +} + +#ifndef XMESA_USE_PUTPIXEL_MACRO +void XMesaPutPixel(XMesaImage *image, int x, int y, unsigned long pixel) +{ + CARD8 *row = (CARD8 *)(image->data + y*image->bytes_per_line); + CARD8 *i8; + CARD16 *i16; + CARD32 *i32; + switch (image->bits_per_pixel) { + case 8: + i8 = (CARD8 *)row; + i8[x] = (CARD8)pixel; + break; + case 15: + case 16: + i16 = (CARD16 *)row; + i16[x] = (CARD16)pixel; + break; + case 24: /* WARNING: architecture specific code */ + i8 = (CARD8 *)__row; + i8[x*3] = (CARD8)(p); + i8[x*3+1] = (CARD8)(p>>8); + i8[x*3+2] = (CARD8)(p>>16); + case 32: + i32 = (CARD32 *)row; + i32[x] = (CARD32)pixel; + break; + } +} +#endif + +#endif /* XFree86Server */ diff --git a/src/gallium/winsys/xlib/xm_image.h b/src/gallium/winsys/xlib/xm_image.h new file mode 100644 index 0000000000..2a5e0f3777 --- /dev/null +++ b/src/gallium/winsys/xlib/xm_image.h @@ -0,0 +1,77 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Brian Paul + */ + +#ifndef _XM_IMAGE_H_ +#define _XM_IMAGE_H_ + +#define XMESA_USE_PUTPIXEL_MACRO + +extern XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height, + char *data); +extern void XMesaDestroyImage(XMesaImage *image); +extern unsigned long XMesaGetPixel(XMesaImage *image, int x, int y); +#ifdef XMESA_USE_PUTPIXEL_MACRO +#define XMesaPutPixel(__i,__x,__y,__p) \ +{ \ + CARD8 *__row = (CARD8 *)(__i->data + __y*__i->bytes_per_line); \ + CARD8 *__i8; \ + CARD16 *__i16; \ + CARD32 *__i32; \ + switch (__i->bits_per_pixel) { \ + case 8: \ + __i8 = (CARD8 *)__row; \ + __i8[__x] = (CARD8)__p; \ + break; \ + case 15: \ + case 16: \ + __i16 = (CARD16 *)__row; \ + __i16[__x] = (CARD16)__p; \ + break; \ + case 24: /* WARNING: architecture specific code */ \ + __i8 = (CARD8 *)__row; \ + __i8[__x*3] = (CARD8)(__p); \ + __i8[__x*3+1] = (CARD8)(__p>>8); \ + __i8[__x*3+2] = (CARD8)(__p>>16); \ + break; \ + case 32: \ + __i32 = (CARD32 *)__row; \ + __i32[__x] = (CARD32)__p; \ + break; \ + } \ +} +#else +extern void XMesaPutPixel(XMesaImage *image, int x, int y, + unsigned long pixel); +#endif + +#endif /* _XM_IMAGE_H_ */ diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c new file mode 100644 index 0000000000..c3cd22eea3 --- /dev/null +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -0,0 +1,466 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * Brian Paul + */ + + +#include "glxheader.h" +#include "xmesaP.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/softpipe/sp_winsys.h" + +#ifdef GALLIUM_CELL +#include "pipe/cell/ppu/cell_context.h" +#include "pipe/cell/ppu/cell_winsys.h" +#else +#define TILE_SIZE 32 /* avoid compilation errors */ +#endif + +#include "xm_winsys_aub.h" + + +/** + * Low-level OS/window system memory buffer + */ +struct xm_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; +}; + + +struct xmesa_surface +{ + struct pipe_surface surface; + + int tileSize; +}; + + +/** + * Derived from softpipe_winsys. + * We just need one extra field which indicates the pixel format to use for + * drawing surfaces so that we're compatible with the XVisual/window format. + */ +struct xmesa_softpipe_winsys +{ + struct softpipe_winsys spws; + enum pipe_format pixelformat; +}; + + + +/** Cast wrapper */ +static INLINE struct xmesa_surface * +xmesa_surface(struct pipe_surface *ps) +{ +// assert(0); + return (struct xmesa_surface *) ps; +} + +/** cast wrapper */ +static INLINE struct xmesa_softpipe_winsys * +xmesa_softpipe_winsys(struct softpipe_winsys *spws) +{ + return (struct xmesa_softpipe_winsys *) spws; +} + +/** + * Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque + * buffer pointer... + */ +static INLINE struct xm_buffer * +xm_buffer( struct pipe_buffer *buf ) +{ + return (struct xm_buffer *)buf; +} + + + +/* Most callbacks map direcly onto dri_bufmgr operations: + */ +static void * +xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, + unsigned flags) +{ + struct xm_buffer *xm_buf = xm_buffer(buf); + xm_buf->mapped = xm_buf->data; + return xm_buf->mapped; +} + +static void +xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct xm_buffer *xm_buf = xm_buffer(buf); + xm_buf->mapped = NULL; +} + +static void +xm_buffer_destroy(struct pipe_winsys *pws, + struct pipe_buffer *buf) +{ + struct xm_buffer *oldBuf = xm_buffer(buf); + + if (oldBuf->data) { + if (!oldBuf->userBuffer) + align_free(oldBuf->data); + oldBuf->data = NULL; + } + + free(oldBuf); +} + + +/** + * Display a surface that's in a tiled configuration. That is, all the + * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory. + */ +static void +xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) +{ + XImage *ximage = b->tempImage; + struct xm_buffer *xm_buf = xm_buffer(surf->buffer); + const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE; + uint x, y; + + /* check that the XImage has been previously initialized */ + assert(ximage->format); + assert(ximage->bitmap_unit); + + /* update XImage's fields */ + ximage->width = TILE_SIZE; + ximage->height = TILE_SIZE; + ximage->bytes_per_line = TILE_SIZE * 4; + + for (y = 0; y < surf->height; y += TILE_SIZE) { + for (x = 0; x < surf->width; x += TILE_SIZE) { + int dx = x; + int dy = y; + int tx = x / TILE_SIZE; + int ty = y / TILE_SIZE; + int offset = ty * tilesPerRow + tx; + + offset *= 4 * TILE_SIZE * TILE_SIZE; + + ximage->data = (char *) xm_buf->data + offset; + + XPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, dx, dy, TILE_SIZE, TILE_SIZE); + } + } +} + + +/** + * Display/copy the image in the surface into the X window specified + * by the XMesaBuffer. + */ +void +xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) +{ + XImage *ximage = b->tempImage; + struct xm_buffer *xm_buf = xm_buffer(surf->buffer); + const struct xmesa_surface *xm_surf + = xmesa_surface((struct pipe_surface *) surf); + + if (xm_surf->tileSize) { + xmesa_display_surface_tiled(b, surf); + return; + } + + /* check that the XImage has been previously initialized */ + assert(ximage->format); + assert(ximage->bitmap_unit); + + /* update XImage's fields */ + ximage->width = surf->width; + ximage->height = surf->height; + ximage->bytes_per_line = surf->pitch * (ximage->bits_per_pixel / 8); + ximage->data = xm_buf->data; + + /* display image in Window */ + XPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, 0, 0, surf->width, surf->height); +} + + +static void +xm_flush_frontbuffer(struct pipe_winsys *pws, + struct pipe_surface *surf, + void *context_private) +{ + /* The Xlib driver's front color surfaces are actually X Windows so + * this flush is a no-op. + * If we instead did front buffer rendering to a temporary XImage, + * this would be the place to copy the Ximage to the on-screen Window. + */ + XMesaContext xmctx = (XMesaContext) context_private; + xmesa_display_surface(xmctx->xm_buffer, surf); +} + + + +static void +xm_printf(struct pipe_winsys *pws, const char *fmtString, ...) +{ + va_list args; + va_start( args, fmtString ); + vfprintf(stderr, fmtString, args); + va_end( args ); +} + + +static const char * +xm_get_name(struct pipe_winsys *pws) +{ + return "Xlib"; +} + + +static struct pipe_buffer * +xm_buffer_create(struct pipe_winsys *pws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + /* align to 16-byte multiple for Cell */ + buffer->data = align_malloc(size, max(alignment, 16)); + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) +{ + struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); + buffer->base.refcount = 1; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +xm_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + +#ifdef GALLIUM_CELL /* XXX a bit of a hack */ + height = round_up(height, TILE_SIZE); +#endif + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if(!surf->buffer) + return -1; + + return 0; +} + + +/** + * Called via pipe->surface_alloc() to create new surfaces (textures, + * renderbuffers, etc. + */ +static struct pipe_surface * +xm_surface_alloc(struct pipe_winsys *ws) +{ + struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface); + + assert(ws); + + xms->surface.refcount = 1; + xms->surface.winsys = ws; + +#ifdef GALLIUM_CELL + if (!getenv("GALLIUM_NOCELL")) { + xms->tileSize = 32; /** probably temporary */ + } +#endif + + return &xms->surface; +} + + + +static void +xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + + +/** + * Return pointer to a pipe_winsys object. + * For Xlib, this is a singleton object. + * Nothing special for the Xlib driver so no subclassing or anything. + */ +struct pipe_winsys * +xmesa_get_pipe_winsys_aub(void) +{ + static struct pipe_winsys *ws = NULL; + + if (!ws && getenv("XM_AUB")) { + ws = xmesa_create_pipe_winsys_aub(); + } + else if (!ws) { + ws = CALLOC_STRUCT(pipe_winsys); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + */ + ws->buffer_create = xm_buffer_create; + ws->user_buffer_create = xm_user_buffer_create; + ws->buffer_map = xm_buffer_map; + ws->buffer_unmap = xm_buffer_unmap; + ws->buffer_destroy = xm_buffer_destroy; + + ws->surface_alloc = xm_surface_alloc; + ws->surface_alloc_storage = xm_surface_alloc_storage; + ws->surface_release = xm_surface_release; + + ws->flush_frontbuffer = xm_flush_frontbuffer; + ws->printf = xm_printf; + ws->get_name = xm_get_name; + } + + return ws; +} + + +/** + * Called via softpipe_winsys->is_format_supported(). + * This function is only called to test formats for front/back color surfaces. + * The winsys being queried will have been created at glXCreateContext + * time, with a pixel format corresponding to the context's visual. + */ +static boolean +xmesa_is_format_supported(struct softpipe_winsys *sws, + enum pipe_format format) +{ + struct xmesa_softpipe_winsys *xmws = xmesa_softpipe_winsys(sws); + return (format == xmws->pixelformat); +} + + +/** + * Return pointer to a softpipe_winsys object. + */ +static struct softpipe_winsys * +xmesa_get_softpipe_winsys(uint pixelformat) +{ + struct xmesa_softpipe_winsys *xmws + = CALLOC_STRUCT(xmesa_softpipe_winsys); + if (!xmws) + return NULL; + + xmws->spws.is_format_supported = xmesa_is_format_supported; + xmws->pixelformat = pixelformat; + + return &xmws->spws; +} + + +struct pipe_context * +xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) +{ + struct pipe_winsys *pws = xmesa_get_pipe_winsys_aub(); + struct pipe_context *pipe; + +#ifdef GALLIUM_CELL + if (!getenv("GALLIUM_NOCELL")) { + struct cell_winsys *cws = cell_get_winsys(pixelformat); + pipe = cell_create_context(pws, cws); + if (pipe) + pipe->priv = xmesa; + return pipe; + } + else +#endif + { + struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(pixelformat); + pipe = softpipe_create( pws, spws ); + if (pipe) + pipe->priv = xmesa; + + return pipe; + } +} diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c new file mode 100644 index 0000000000..bf41570257 --- /dev/null +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -0,0 +1,589 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * Brian Paul + */ + + +#include "glxheader.h" +#include "xmesaP.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/i965simple/brw_winsys.h" +#include "brw_aub.h" +#include "xm_winsys_aub.h" + + + +struct aub_buffer { + char *data; + unsigned offset; + unsigned size; + unsigned refcount; + unsigned map_count; + boolean dump_on_unmap; +}; + + + +struct aub_pipe_winsys { + struct pipe_winsys winsys; + + struct brw_aubfile *aubfile; + + /* This is simple, isn't it: + */ + char *pool; + unsigned size; + unsigned used; +}; + + +/* Turn a pipe winsys into an aub/pipe winsys: + */ +static inline struct aub_pipe_winsys * +aub_pipe_winsys( struct pipe_winsys *winsys ) +{ + return (struct aub_pipe_winsys *)winsys; +} + + + +static INLINE struct aub_buffer * +aub_bo( struct pipe_buffer *bo ) +{ + return (struct aub_buffer *)bo; +} + +static INLINE struct pipe_buffer * +pipe_bo( struct aub_buffer *bo ) +{ + return (struct pipe_buffer *)bo; +} + + + + +static void *aub_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags ) +{ + struct aub_buffer *sbo = aub_bo(buf); + + assert(sbo->data); + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + sbo->dump_on_unmap = 1; + + sbo->map_count++; + return sbo->data; +} + +static void aub_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + struct aub_buffer *sbo = aub_bo(buf); + + sbo->map_count--; + + if (sbo->map_count == 0 && + sbo->dump_on_unmap) { + + sbo->dump_on_unmap = 0; + + brw_aub_gtt_data( iws->aubfile, + sbo->offset, + sbo->data, + sbo->size, + 0, + 0); + } +} + + +static void +aub_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + free(buf); +} + + +void xmesa_buffer_subdata_aub(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned long offset, + unsigned long size, + const void *data, + unsigned aub_type, + unsigned aub_sub_type) +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + struct aub_buffer *sbo = aub_bo(buf); + + assert(sbo->size > offset + size); + memcpy(sbo->data + offset, data, size); + + brw_aub_gtt_data( iws->aubfile, + sbo->offset + offset, + sbo->data + offset, + size, + aub_type, + aub_sub_type ); +} + +void xmesa_commands_aub(struct pipe_winsys *winsys, + unsigned *cmds, + unsigned nr_dwords) +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + unsigned size = nr_dwords * 4; + + assert(iws->used + size < iws->size); + + brw_aub_gtt_cmds( iws->aubfile, + AUB_BUF_START + iws->used, + cmds, + nr_dwords * sizeof(int) ); + + iws->used += align(size, 4096); +} + + +static struct aub_pipe_winsys *global_winsys = NULL; + +void xmesa_display_aub( /* struct pipe_winsys *winsys, */ + struct pipe_surface *surface ) +{ +// struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + brw_aub_dump_bmp( global_winsys->aubfile, + surface, + aub_bo(surface->buffer)->offset ); +} + + + +/* Pipe has no concept of pools. We choose the tex/region pool + * for all buffers. + */ +static struct pipe_buffer * +aub_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + struct aub_buffer *sbo = CALLOC_STRUCT(aub_buffer); + + sbo->refcount = 1; + + /* Could reuse buffers that are not referenced in current + * batchbuffer. Can't do that atm, so always reallocate: + */ + assert(iws->used + size < iws->size); + sbo->data = iws->pool + iws->used; + sbo->offset = AUB_BUF_START + iws->used; + iws->used += align(size, 4096); + + sbo->size = size; + + return pipe_bo(sbo); +} + + +static struct pipe_buffer * +aub_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) +{ + struct aub_buffer *sbo; + + /* Lets hope this is meant for upload, not as a result! + */ + sbo = aub_bo(aub_buffer_create( winsys, 0, 0, 0 )); + + sbo->data = ptr; + sbo->size = bytes; + + return pipe_bo(sbo); +} + + +/* The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +aub_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ + xmesa_display_aub( surf ); +} + +static struct pipe_surface * +aub_i915_surface_alloc(struct pipe_winsys *winsys) +{ + struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); + if (surf) { + surf->refcount = 1; + surf->winsys = winsys; + } + return surf; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +aub_i915_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if(!surf->buffer) + return -1; + + return 0; +} + +static void +aub_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + + +static void +aub_printf( struct pipe_winsys *winsys, const char *fmtString, ... ) +{ + va_list args; + va_start( args, fmtString ); + vfprintf(stderr, fmtString, args); + va_end( args ); +} + +static const char * +aub_get_name( struct pipe_winsys *winsys ) +{ + return "Aub/xlib"; +} + +struct pipe_winsys * +xmesa_create_pipe_winsys_aub( void ) +{ + struct aub_pipe_winsys *iws = CALLOC_STRUCT( aub_pipe_winsys ); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + * + * Pipe would be happy with a malloc based memory manager, but + * the SwapBuffers implementation in this winsys driver requires + * that rendering be done to an appropriate _DriBufferObject. + */ + iws->winsys.buffer_create = aub_buffer_create; + iws->winsys.user_buffer_create = aub_user_buffer_create; + iws->winsys.buffer_map = aub_buffer_map; + iws->winsys.buffer_unmap = aub_buffer_unmap; + iws->winsys.buffer_destroy = aub_buffer_destroy; + iws->winsys.flush_frontbuffer = aub_flush_frontbuffer; + iws->winsys.printf = aub_printf; + iws->winsys.get_name = aub_get_name; + + iws->winsys.surface_alloc = aub_i915_surface_alloc; + iws->winsys.surface_alloc_storage = aub_i915_surface_alloc_storage; + iws->winsys.surface_release = aub_i915_surface_release; + + iws->aubfile = brw_aubfile_create(); + iws->size = AUB_BUF_SIZE; + iws->pool = malloc(AUB_BUF_SIZE); + + /* HACK: static copy of this pointer: + */ + assert(global_winsys == NULL); + global_winsys = iws; + + return &iws->winsys; +} + + +void +xmesa_destroy_pipe_winsys_aub( struct pipe_winsys *winsys ) + +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + brw_aub_destroy(iws->aubfile); + free(iws->pool); + free(iws); +} + + + + + + + +#define IWS_BATCHBUFFER_SIZE 1024 + +struct aub_brw_winsys { + struct brw_winsys winsys; /**< batch buffer funcs */ + struct aub_context *aub; + + struct pipe_winsys *pipe_winsys; + + unsigned batch_data[IWS_BATCHBUFFER_SIZE]; + unsigned batch_nr; + unsigned batch_size; + unsigned batch_alloc; +}; + + +/* Turn a i965simple winsys into an aub/i965simple winsys: + */ +static inline struct aub_brw_winsys * +aub_brw_winsys( struct brw_winsys *sws ) +{ + return (struct aub_brw_winsys *)sws; +} + + +/* Simple batchbuffer interface: + */ + +static unsigned *aub_i965_batch_start( struct brw_winsys *sws, + unsigned dwords, + unsigned relocs ) +{ + struct aub_brw_winsys *iws = aub_brw_winsys(sws); + + if (iws->batch_size < iws->batch_nr + dwords) + return NULL; + + iws->batch_alloc = iws->batch_nr + dwords; + return (void *)1; /* not a valid pointer! */ +} + +static void aub_i965_batch_dword( struct brw_winsys *sws, + unsigned dword ) +{ + struct aub_brw_winsys *iws = aub_brw_winsys(sws); + + assert(iws->batch_nr < iws->batch_alloc); + iws->batch_data[iws->batch_nr++] = dword; +} + +static void aub_i965_batch_reloc( struct brw_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta ) +{ + struct aub_brw_winsys *iws = aub_brw_winsys(sws); + + assert(iws->batch_nr < iws->batch_alloc); + iws->batch_data[iws->batch_nr++] = aub_bo(buf)->offset + delta; +} + +static unsigned aub_i965_get_buffer_offset( struct brw_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags ) +{ + return aub_bo(buf)->offset; +} + +static void aub_i965_batch_end( struct brw_winsys *sws ) +{ + struct aub_brw_winsys *iws = aub_brw_winsys(sws); + + assert(iws->batch_nr <= iws->batch_alloc); + iws->batch_alloc = 0; +} + +static void aub_i965_batch_flush( struct brw_winsys *sws, + struct pipe_fence_handle **fence ) +{ + struct aub_brw_winsys *iws = aub_brw_winsys(sws); + assert(iws->batch_nr <= iws->batch_size); + + if (iws->batch_nr) { + xmesa_commands_aub( iws->pipe_winsys, + iws->batch_data, + iws->batch_nr ); + } + + iws->batch_nr = 0; +} + + + +static void aub_i965_buffer_subdata_typed(struct brw_winsys *winsys, + struct pipe_buffer *buf, + unsigned long offset, + unsigned long size, + const void *data, + unsigned data_type) +{ + struct aub_brw_winsys *iws = aub_brw_winsys(winsys); + unsigned aub_type = DW_GENERAL_STATE; + unsigned aub_sub_type; + + switch (data_type) { + case BRW_CC_VP: + aub_sub_type = DWGS_COLOR_CALC_VIEWPORT_STATE; + break; + case BRW_CC_UNIT: + aub_sub_type = DWGS_COLOR_CALC_STATE; + break; + case BRW_WM_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_SAMPLER_DEFAULT_COLOR: + aub_sub_type = DWGS_SAMPLER_DEFAULT_COLOR; + break; + case BRW_SAMPLER: + aub_sub_type = DWGS_SAMPLER_STATE; + break; + case BRW_WM_UNIT: + aub_sub_type = DWGS_WINDOWER_IZ_STATE; + break; + case BRW_SF_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_SF_VP: + aub_sub_type = DWGS_STRIPS_FANS_VIEWPORT_STATE; + break; + case BRW_SF_UNIT: + aub_sub_type = DWGS_STRIPS_FANS_STATE; + break; + case BRW_VS_UNIT: + aub_sub_type = DWGS_VERTEX_SHADER_STATE; + break; + case BRW_VS_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_GS_UNIT: + aub_sub_type = DWGS_GEOMETRY_SHADER_STATE; + break; + case BRW_GS_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_CLIP_VP: + aub_sub_type = DWGS_CLIPPER_VIEWPORT_STATE; + break; + case BRW_CLIP_UNIT: + aub_sub_type = DWGS_CLIPPER_STATE; + break; + case BRW_CLIP_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_SS_SURFACE: + aub_type = DW_SURFACE_STATE; + aub_sub_type = DWSS_SURFACE_STATE; + break; + case BRW_SS_SURF_BIND: + aub_type = DW_SURFACE_STATE; + aub_sub_type = DWSS_BINDING_TABLE_STATE; + break; + case BRW_CONSTANT_BUFFER: + aub_type = DW_CONSTANT_URB_ENTRY; + aub_sub_type = 0; + break; + + default: + assert(0); + break; + } + + xmesa_buffer_subdata_aub( iws->pipe_winsys, + buf, + offset, + size, + data, + aub_type, + aub_sub_type ); +} + +/** + * Create i965 hardware rendering context. + */ +struct pipe_context * +xmesa_create_i965simple( struct pipe_winsys *winsys ) +{ + struct aub_brw_winsys *iws = CALLOC_STRUCT( aub_brw_winsys ); + + /* Fill in this struct with callbacks that i965simple will need to + * communicate with the window system, buffer manager, etc. + */ + iws->winsys.batch_start = aub_i965_batch_start; + iws->winsys.batch_dword = aub_i965_batch_dword; + iws->winsys.batch_reloc = aub_i965_batch_reloc; + iws->winsys.batch_end = aub_i965_batch_end; + iws->winsys.batch_flush = aub_i965_batch_flush; + iws->winsys.buffer_subdata_typed = aub_i965_buffer_subdata_typed; + iws->winsys.get_buffer_offset = aub_i965_get_buffer_offset; + + iws->pipe_winsys = winsys; + + iws->batch_size = IWS_BATCHBUFFER_SIZE; + + /* Create the i965simple context: + */ + return brw_create( winsys, + &iws->winsys, + 0 ); +} diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.h b/src/gallium/winsys/xlib/xm_winsys_aub.h new file mode 100644 index 0000000000..7bee199116 --- /dev/null +++ b/src/gallium/winsys/xlib/xm_winsys_aub.h @@ -0,0 +1,67 @@ +/************************************************************************** + * + * Copyright 2006 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. + * + **************************************************************************/ + +#ifndef AUB_WINSYS_H +#define AUB_WINSYS_H + +struct pipe_context; +struct pipe_winsys; +struct pipe_buffer; +struct pipe_surface; + +struct pipe_winsys * +xmesa_create_pipe_winsys_aub( void ); + +void +xmesa_destroy_pipe_winsys_aub( struct pipe_winsys *winsys ); + + + +struct pipe_context * +xmesa_create_i965simple( struct pipe_winsys *winsys ); + + + +void xmesa_buffer_subdata_aub(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned long offset, + unsigned long size, + const void *data, + unsigned aub_type, + unsigned aub_sub_type); + +void xmesa_commands_aub(struct pipe_winsys *winsys, + unsigned *cmds, + unsigned nr_dwords); + + +void xmesa_display_aub( /* struct pipe_winsys *winsys, */ + struct pipe_surface *surface ); + +struct pipe_winsys *xmesa_get_pipe_winsys_aub(void); + +#endif diff --git a/src/gallium/winsys/xlib/xmesaP.h b/src/gallium/winsys/xlib/xmesaP.h new file mode 100644 index 0000000000..fa8d1f14b9 --- /dev/null +++ b/src/gallium/winsys/xlib/xmesaP.h @@ -0,0 +1,176 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + + +#ifndef XMESAP_H +#define XMESAP_H + + +#include "GL/xmesa.h" +#include "mtypes.h" +#ifdef XFree86Server +#include "xm_image.h" +#endif + +#include "state_tracker/st_context.h" +#include "state_tracker/st_public.h" + + +extern _glthread_Mutex _xmesa_lock; + +extern XMesaBuffer XMesaBufferList; + +/* + */ +#define XMESA_SOFTPIPE 1 +#define XMESA_AUB 2 +extern int xmesa_mode; + + +/** + * Visual inforation, derived from GLvisual. + * Basically corresponds to an XVisualInfo. + */ +struct xmesa_visual { + GLvisual mesa_visual; /* Device independent visual parameters */ + XMesaDisplay *display; /* The X11 display */ +#ifdef XFree86Server + GLint ColormapEntries; + GLint nplanes; +#else + XMesaVisualInfo visinfo; /* X's visual info (pointer to private copy) */ + XVisualInfo *vishandle; /* Only used in fakeglx.c */ +#endif + GLint BitsPerPixel; /* True bits per pixel for XImages */ + + GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */ +}; + + +/** + * Context info, derived from st_context. + * Basically corresponds to a GLXContext. + */ +struct xmesa_context { + struct st_context *st; + XMesaVisual xm_visual; /** pixel format info */ + XMesaBuffer xm_buffer; /** current drawbuffer */ +}; + + +/** + * Types of X/GLX drawables we might render into. + */ +typedef enum { + WINDOW, /* An X window */ + GLXWINDOW, /* GLX window */ + PIXMAP, /* GLX pixmap */ + PBUFFER /* GLX Pbuffer */ +} BufferType; + + +/** + * Framebuffer information, derived from. + * Basically corresponds to a GLXDrawable. + */ +struct xmesa_buffer { + struct st_framebuffer *stfb; + + GLboolean wasCurrent; /* was ever the current buffer? */ + XMesaVisual xm_visual; /* the X/Mesa visual */ + XMesaDrawable drawable; /* Usually the X window ID */ + XMesaColormap cmap; /* the X colormap */ + BufferType type; /* window, pixmap, pbuffer or glxwindow */ + + XMesaImage *tempImage; + unsigned long selectedEvents;/* for pbuffers only */ + + GLuint shm; /* X Shared Memory extension status: */ + /* 0 = not available */ + /* 1 = XImage support available */ + /* 2 = Pixmap support available too */ +#if defined(USE_XSHM) && !defined(XFree86Server) + XShmSegmentInfo shminfo; +#endif + + XMesaGC gc; /* scratch GC for span, line, tri drawing */ + + /* GLX_EXT_texture_from_pixmap */ + GLint TextureTarget; /** GLX_TEXTURE_1D_EXT, for example */ + GLint TextureFormat; /** GLX_TEXTURE_FORMAT_RGB_EXT, for example */ + GLint TextureMipmap; /** 0 or 1 */ + + struct xmesa_buffer *Next; /* Linked list pointer: */ +}; + + + +/** cast wrapper */ +static INLINE XMesaContext +xmesa_context(GLcontext *ctx) +{ + return (XMesaContext) ctx->DriverCtx; +} + + +/** cast wrapper */ +static INLINE XMesaBuffer +xmesa_buffer(GLframebuffer *fb) +{ + struct st_framebuffer *stfb = (struct st_framebuffer *) fb; + return (XMesaBuffer) st_framebuffer_private(stfb); +} + + +extern void +xmesa_delete_framebuffer(struct gl_framebuffer *fb); + +extern XMesaBuffer +xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis); + +extern void +xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer); + +extern void +xmesa_destroy_buffers_on_display(XMesaDisplay *dpy); + +extern struct pipe_context * +xmesa_create_pipe_context(XMesaContext xm, uint pixelformat); + +static INLINE GLuint +xmesa_buffer_width(XMesaBuffer b) +{ + return b->stfb->Base.Width; +} + +static INLINE GLuint +xmesa_buffer_height(XMesaBuffer b) +{ + return b->stfb->Base.Height; +} + +extern void +xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf); + +#endif -- cgit v1.2.3 From 6acd63a4980951727939c0dd545a0324965b3834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Feb 2008 17:50:12 +0900 Subject: Code reorganization: update build. Update the Makefiles and includes for the new paths. Note that there hasn't been no separation of the Makefiles yet, and make is jumping all over the place. That will be taken care shortly. But for now, make should work. It was tested with linux and linux-dri. Linux-cell and linux-llvm might require some minor tweaks. --- src/gallium/winsys/dri/Makefile | 38 +++++++ src/gallium/winsys/dri/Makefile.template | 113 +++++++++++++++++++++ src/gallium/winsys/dri/intel/Makefile | 8 +- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 2 +- .../winsys/dri/intel/intel_winsys_softpipe.c | 2 +- src/gallium/winsys/xlib/xm_winsys.c | 6 +- src/gallium/winsys/xlib/xm_winsys_aub.c | 2 +- 7 files changed, 161 insertions(+), 10 deletions(-) create mode 100644 src/gallium/winsys/dri/Makefile create mode 100644 src/gallium/winsys/dri/Makefile.template (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/Makefile b/src/gallium/winsys/dri/Makefile new file mode 100644 index 0000000000..f466ce6c3c --- /dev/null +++ b/src/gallium/winsys/dri/Makefile @@ -0,0 +1,38 @@ +# src/mesa/drivers/dri/Makefile + +TOP = ../../../.. + +include $(TOP)/configs/current + + + +default: $(TOP)/$(LIB_DIR) subdirs + + +$(TOP)/$(LIB_DIR): + -mkdir $(TOP)/$(LIB_DIR) + + +subdirs: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +install: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) install) || exit 1 ; \ + fi \ + done + + +clean: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) clean) ; \ + fi \ + done + -rm -f common/*.o diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template new file mode 100644 index 0000000000..b96305c094 --- /dev/null +++ b/src/gallium/winsys/dri/Makefile.template @@ -0,0 +1,113 @@ +# -*-makefile-*- + +MESA_MODULES = $(TOP)/src/mesa/libmesa.a + +COMMON_GALLIUM_SOURCES = \ + $(TOP)/src/mesa/drivers/dri/common/utils.c \ + $(TOP)/src/mesa/drivers/dri/common/vblank.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_util.c \ + $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c + +COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ + $(TOP)/src/mesa/drivers/common/driverfuncs.c \ + $(TOP)/src/mesa/drivers/dri/common/texmem.c \ + $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c + +COMMON_BM_SOURCES = \ + $(TOP)/src/mesa/drivers/dri/common/dri_bufmgr.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_drmpool.c + + +ifeq ($(WINDOW_SYSTEM),dri) +WINOBJ= +WINLIB= +INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) + +else +# miniglx +WINOBJ= +WINLIB=-L$(MESA)/src/glx/mini +MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini +INCLUDES = $(MINIGLX_INCLUDES) \ + $(SHARED_INCLUDES) \ + $(PCIACCESS_CFLAGS) + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(MINIGLX_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) +endif + + +### Include directories +SHARED_INCLUDES = \ + -I. \ + -I$(TOP)/src/mesa/drivers/dri/common \ + -Iserver \ + -I$(TOP)/include \ + -I$(TOP)/include/GL/internal \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/mesa/glapi \ + -I$(TOP)/src/mesa/math \ + -I$(TOP)/src/mesa/transform \ + -I$(TOP)/src/mesa/shader \ + -I$(TOP)/src/mesa/swrast \ + -I$(TOP)/src/mesa/swrast_setup \ + -I$(TOP)/src/egl/main \ + -I$(TOP)/src/egl/drivers/dri \ + $(LIBDRM_CFLAGS) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) + + +$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template + $(TOP)/bin/mklib -noprefix -o $@ \ + $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) + + +$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) + $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) + + +depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +install: $(LIBNAME) + $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) + $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + + +include depend diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index 9ae0f01325..40654bb2ac 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -7,8 +7,8 @@ LIBNAME = i915tex_dri.so MINIGLX_SOURCES = server/intel_dri.c PIPE_DRIVERS = \ - $(TOP)/src/mesa/pipe/softpipe/libsoftpipe.a \ - $(TOP)/src/mesa/pipe/i915simple/libi915simple.a + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a DRIVER_SOURCES = \ intel_winsys_pipe.c \ @@ -28,11 +28,11 @@ C_SOURCES = \ ASM_SOURCES = -DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ +DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") include ../Makefile.template -intel_tex_layout.o: ../intel/intel_tex_layout.c +intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c symlinks: diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index 1ba6a9e1b2..0ed3890e93 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -39,7 +39,7 @@ #include "intel_winsys.h" #include "pipe/p_util.h" -#include "pipe/i915simple/i915_winsys.h" +#include "i915simple/i915_winsys.h" struct intel_i915_winsys { diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c index cec3437831..9e483bdc9f 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c @@ -34,7 +34,7 @@ #include "pipe/p_defines.h" #include "pipe/p_util.h" #include "pipe/p_format.h" -#include "pipe/softpipe/sp_winsys.h" +#include "softpipe/sp_winsys.h" struct intel_softpipe_winsys { diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index c3cd22eea3..8da596d419 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -41,11 +41,11 @@ #include "pipe/p_context.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "pipe/softpipe/sp_winsys.h" +#include "softpipe/sp_winsys.h" #ifdef GALLIUM_CELL -#include "pipe/cell/ppu/cell_context.h" -#include "pipe/cell/ppu/cell_winsys.h" +#include "cell/ppu/cell_context.h" +#include "cell/ppu/cell_winsys.h" #else #define TILE_SIZE 32 /* avoid compilation errors */ #endif diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index bf41570257..dbfd37bda2 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -39,7 +39,7 @@ #include "pipe/p_winsys.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "pipe/i965simple/brw_winsys.h" +#include "i965simple/brw_winsys.h" #include "brw_aub.h" #include "xm_winsys_aub.h" -- cgit v1.2.3 From 66f22aa3bf7fa546e946b45156aa578e202982c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Feb 2008 20:11:40 +0900 Subject: Code reorganization: s/aux/auxiliary/ -- update build. --- src/gallium/winsys/dri/Makefile.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index b96305c094..2a261ed669 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -49,7 +49,7 @@ SHARED_INCLUDES = \ -I$(TOP)/include \ -I$(TOP)/include/GL/internal \ -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/main \ -- cgit v1.2.3 From 26add9288c88108e3485ffc57c51ea9bdc0ee719 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 16 Feb 2008 17:23:12 +1100 Subject: nouveau: match gallium code reorginisation. That was... fun.. --- src/gallium/winsys/dri/nouveau/Makefile | 43 +++ src/gallium/winsys/dri/nouveau/nouveau_bo.c | 402 +++++++++++++++++++++ src/gallium/winsys/dri/nouveau/nouveau_channel.c | 118 ++++++ src/gallium/winsys/dri/nouveau/nouveau_context.c | 206 +++++++++++ src/gallium/winsys/dri/nouveau/nouveau_context.h | 89 +++++ src/gallium/winsys/dri/nouveau/nouveau_device.c | 146 ++++++++ src/gallium/winsys/dri/nouveau/nouveau_device.h | 29 ++ src/gallium/winsys/dri/nouveau/nouveau_dma.c | 219 +++++++++++ src/gallium/winsys/dri/nouveau/nouveau_dma.h | 143 ++++++++ src/gallium/winsys/dri/nouveau/nouveau_dri.h | 28 ++ src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 304 ++++++++++++++++ src/gallium/winsys/dri/nouveau/nouveau_fence.c | 215 +++++++++++ src/gallium/winsys/dri/nouveau/nouveau_grobj.c | 107 ++++++ src/gallium/winsys/dri/nouveau/nouveau_local.h | 89 +++++ src/gallium/winsys/dri/nouveau/nouveau_lock.c | 94 +++++ src/gallium/winsys/dri/nouveau/nouveau_notifier.c | 137 +++++++ src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 261 +++++++++++++ src/gallium/winsys/dri/nouveau/nouveau_resource.c | 111 ++++++ src/gallium/winsys/dri/nouveau/nouveau_screen.c | 308 ++++++++++++++++ src/gallium/winsys/dri/nouveau/nouveau_screen.h | 19 + .../winsys/dri/nouveau/nouveau_swapbuffers.c | 86 +++++ .../winsys/dri/nouveau/nouveau_swapbuffers.h | 10 + src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 124 +++++++ .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 196 ++++++++++ .../winsys/dri/nouveau/nouveau_winsys_pipe.h | 34 ++ .../winsys/dri/nouveau/nouveau_winsys_softpipe.c | 83 +++++ src/gallium/winsys/dri/nouveau/nv04_surface.c | 226 ++++++++++++ src/gallium/winsys/dri/nouveau/nv50_surface.c | 160 ++++++++ 28 files changed, 3987 insertions(+) create mode 100644 src/gallium/winsys/dri/nouveau/Makefile create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_bo.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_channel.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_context.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_context.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_device.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_device.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_dma.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_dma.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_dri.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_drmif.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_fence.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_grobj.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_local.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_lock.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_notifier.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_resource.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_screen.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_screen.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c create mode 100644 src/gallium/winsys/dri/nouveau/nv04_surface.c create mode 100644 src/gallium/winsys/dri/nouveau/nv50_surface.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/Makefile b/src/gallium/winsys/dri/nouveau/Makefile new file mode 100644 index 0000000000..b463f218fd --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/Makefile @@ -0,0 +1,43 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = nouveau_dri.so + +MINIGLX_SOURCES = + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.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_bo.c \ + nouveau_channel.c \ + nouveau_context.c \ + nouveau_device.c \ + nouveau_dma.c \ + nouveau_fence.c \ + nouveau_grobj.c \ + nouveau_lock.c \ + nouveau_notifier.c \ + nouveau_pushbuf.c \ + nouveau_resource.c \ + nouveau_screen.c \ + nouveau_swapbuffers.c \ + nouveau_winsys.c \ + nouveau_winsys_pipe.c \ + nouveau_winsys_softpipe.c \ + nv04_surface.c \ + nv50_surface.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../Makefile.template + +symlinks: diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c new file mode 100644 index 0000000000..6887ffa688 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -0,0 +1,402 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" +#include "nouveau_local.h" + +static void +nouveau_mem_free(struct nouveau_device *dev, struct drm_nouveau_mem_alloc *ma, + void **map) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct drm_nouveau_mem_free mf; + + if (map && *map) { + drmUnmap(*map, ma->size); + *map = NULL; + } + + if (ma->size) { + mf.offset = ma->offset; + mf.flags = ma->flags; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_MEM_FREE, + &mf, sizeof(mf)); + ma->size = 0; + } +} + +static int +nouveau_mem_alloc(struct nouveau_device *dev, unsigned size, unsigned align, + uint32_t flags, struct drm_nouveau_mem_alloc *ma, void **map) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + int ret; + + ma->alignment = align; + ma->size = size; + ma->flags = flags; + if (map) + ma->flags |= NOUVEAU_MEM_MAPPED; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_MEM_ALLOC, ma, + sizeof(struct drm_nouveau_mem_alloc)); + if (ret) + return ret; + + if (map) { + ret = drmMap(nvdev->fd, ma->map_handle, ma->size, map); + if (ret) { + *map = NULL; + nouveau_mem_free(dev, ma, map); + return ret; + } + } + + return 0; +} + +static void +nouveau_bo_tmp_del(void *priv) +{ + struct nouveau_resource *r = priv; + + nouveau_fence_ref(NULL, (struct nouveau_fence **)&r->priv); + nouveau_resource_free(&r); +} + +static struct nouveau_resource * +nouveau_bo_tmp(struct nouveau_channel *chan, unsigned size, + struct nouveau_fence *fence) +{ + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_resource *r = NULL; + struct nouveau_fence *ref = NULL; + + if (fence) + nouveau_fence_ref(fence, &ref); + else + nouveau_fence_new(chan, &ref); + assert(ref); + + while (nouveau_resource_alloc(nvdev->sa_heap, size, ref, &r)) { + nouveau_fence_flush(chan); + } + nouveau_fence_signal_cb(ref, nouveau_bo_tmp_del, r); + + return r; +} + +int +nouveau_bo_init(struct nouveau_device *dev) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + int ret; + + ret = nouveau_mem_alloc(dev, 128*1024, 0, NOUVEAU_MEM_AGP | + NOUVEAU_MEM_PCI, &nvdev->sa, &nvdev->sa_map); + if (ret) + return ret; + + ret = nouveau_resource_init(&nvdev->sa_heap, 0, nvdev->sa.size); + if (ret) { + nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); + return ret; + } + + return 0; +} + +void +nouveau_bo_takedown(struct nouveau_device *dev) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); +} + +int +nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, + int size, struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + int ret; + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo = calloc(1, sizeof(struct nouveau_bo_priv)); + if (!nvbo) + return -ENOMEM; + nvbo->base.device = dev; + nvbo->base.size = size; + nvbo->base.handle = bo_to_ptr(nvbo); + nvbo->drm.alignment = align; + nvbo->refcount = 1; + + ret = nouveau_bo_set_status(&nvbo->base, flags); + if (ret) { + free(nvbo); + return ret; + } + + *bo = &nvbo->base; + return 0; +} + +int +nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size, + struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo = calloc(1, sizeof(*nvbo)); + if (!nvbo) + return -ENOMEM; + nvbo->base.device = dev; + + nvbo->sysmem = ptr; + nvbo->user = 1; + + nvbo->base.size = size; + nvbo->base.offset = nvbo->drm.offset; + nvbo->base.handle = bo_to_ptr(nvbo); + nvbo->refcount = 1; + *bo = &nvbo->base; + return 0; +} + +int +nouveau_bo_ref(struct nouveau_device *dev, uint64_t handle, + struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo = ptr_to_bo(handle); + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo->refcount++; + *bo = &nvbo->base; + return 0; +} + +void +nouveau_bo_del(struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + + if (!bo || !*bo) + return; + nvbo = nouveau_bo(*bo); + *bo = NULL; + + if (--nvbo->refcount) + return; + + if (nvbo->fence) + nouveau_fence_wait(&nvbo->fence); + nouveau_mem_free(nvbo->base.device, &nvbo->drm, &nvbo->map); + if (nvbo->sysmem && !nvbo->user) + free(nvbo->sysmem); + free(nvbo); +} + +int +nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + + if (!nvbo) + return -EINVAL; + + if (flags & NOUVEAU_BO_WR) + nouveau_fence_wait(&nvbo->fence); + else + nouveau_fence_wait(&nvbo->wr_fence); + + if (nvbo->sysmem) + bo->map = nvbo->sysmem; + else + bo->map = nvbo->map; + return 0; +} + +void +nouveau_bo_unmap(struct nouveau_bo *bo) +{ + bo->map = NULL; +} + +static int +nouveau_bo_upload(struct nouveau_bo_priv *nvbo) +{ + if (nvbo->fence) + nouveau_fence_wait(&nvbo->fence); + memcpy(nvbo->map, nvbo->sysmem, nvbo->drm.size); + return 0; +} + +int +nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct drm_nouveau_mem_alloc new; + void *new_map = NULL, *new_sysmem = NULL; + unsigned new_flags = 0, ret; + + assert(!bo->map); + + /* Check current memtype vs requested, if they match do nothing */ + if ((nvbo->drm.flags & NOUVEAU_MEM_FB) && (flags & NOUVEAU_BO_VRAM)) + return 0; + if ((nvbo->drm.flags & NOUVEAU_MEM_AGP) && (flags & NOUVEAU_BO_GART)) + return 0; + if (nvbo->drm.size == 0 && nvbo->sysmem && (flags & NOUVEAU_BO_LOCAL)) + return 0; + + memset(&new, 0x00, sizeof(new)); + + /* Allocate new memory */ + if (flags & NOUVEAU_BO_VRAM) + new_flags |= NOUVEAU_MEM_FB; + else + if (flags & NOUVEAU_BO_GART) + new_flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI); + + if (new_flags) { + ret = nouveau_mem_alloc(bo->device, bo->size, + nvbo->drm.alignment, new_flags, + &new, &new_map); + if (ret) + return ret; + } else { + new_sysmem = malloc(bo->size); + } + + /* Copy old -> new */ + /*XXX: use M2MF */ + if (nvbo->sysmem || nvbo->map) { + nouveau_bo_map(bo, NOUVEAU_BO_RD); + memcpy(new_map, bo->map, bo->size); + nouveau_bo_unmap(bo); + } + + /* Free old memory */ + if (nvbo->fence) + nouveau_fence_wait(&nvbo->fence); + nouveau_mem_free(bo->device, &nvbo->drm, &nvbo->map); + if (nvbo->sysmem) + free(nvbo->sysmem); + + nvbo->drm = new; + nvbo->map = new_map; + nvbo->sysmem = new_sysmem; + bo->flags = flags; + bo->offset = nvbo->drm.offset; + return 0; +} + +static int +nouveau_bo_validate_user(struct nouveau_channel *chan, struct nouveau_bo *bo, + struct nouveau_fence *fence, uint32_t flags) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_resource *r; + + if (nvchan->user_charge + bo->size > nvdev->sa.size) + return 1; + nvchan->user_charge += bo->size; + + if (!(flags & NOUVEAU_BO_GART)) + return 1; + + r = nouveau_bo_tmp(chan, bo->size, fence); + if (!r) + return 1; + + memcpy(nvdev->sa_map + r->start, nvbo->sysmem, bo->size); + + nvbo->offset = nvdev->sa.offset + r->start; + nvbo->flags = NOUVEAU_BO_GART; + return 0; +} + +static int +nouveau_bo_validate_bo(struct nouveau_channel *chan, struct nouveau_bo *bo, + struct nouveau_fence *fence, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + int ret; + + ret = nouveau_bo_set_status(bo, flags); + if (ret) + return ret; + + if (nvbo->user) + nouveau_bo_upload(nvbo); + + nvbo->offset = nvbo->drm.offset; + if (nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) + nvbo->flags = NOUVEAU_BO_GART; + else + nvbo->flags = NOUVEAU_BO_VRAM; + + return 0; +} + +int +nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo, + struct nouveau_fence *fence, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + int ret; + + assert(bo->map == NULL); + + if (nvbo->user) { + ret = nouveau_bo_validate_user(chan, bo, fence, flags); + if (ret) { + ret = nouveau_bo_validate_bo(chan, bo, fence, flags); + if (ret) + return ret; + } + } else { + ret = nouveau_bo_validate_bo(chan, bo, fence, flags); + if (ret) + return ret; + } + + if (flags & NOUVEAU_BO_WR) + nouveau_fence_ref(fence, &nvbo->wr_fence); + nouveau_fence_ref(fence, &nvbo->fence); + return 0; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_channel.c b/src/gallium/winsys/dri/nouveau/nouveau_channel.c new file mode 100644 index 0000000000..df80d04add --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_channel.c @@ -0,0 +1,118 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +int +nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, + uint32_t tt_ctxdma, struct nouveau_channel **chan) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct nouveau_channel_priv *nvchan; + int ret; + + if (!nvdev || !chan || *chan) + return -EINVAL; + + nvchan = calloc(1, sizeof(struct nouveau_channel_priv)); + if (!nvchan) + return -ENOMEM; + nvchan->base.device = dev; + + nvchan->drm.fb_ctxdma_handle = fb_ctxdma; + nvchan->drm.tt_ctxdma_handle = tt_ctxdma; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, + &nvchan->drm, sizeof(nvchan->drm)); + if (ret) { + free(nvchan); + return ret; + } + + nvchan->base.id = nvchan->drm.channel; + if (nouveau_grobj_ref(&nvchan->base, nvchan->drm.fb_ctxdma_handle, + &nvchan->base.vram) || + nouveau_grobj_ref(&nvchan->base, nvchan->drm.tt_ctxdma_handle, + &nvchan->base.gart)) { + nouveau_channel_free((void *)&nvchan); + return -EINVAL; + } + + ret = drmMap(nvdev->fd, nvchan->drm.ctrl, nvchan->drm.ctrl_size, + (void*)&nvchan->user); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + nvchan->put = &nvchan->user[0x40/4]; + nvchan->get = &nvchan->user[0x44/4]; + nvchan->ref_cnt = &nvchan->user[0x48/4]; + + ret = drmMap(nvdev->fd, nvchan->drm.notifier, nvchan->drm.notifier_size, + (drmAddressPtr)&nvchan->notifier_block); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + ret = drmMap(nvdev->fd, nvchan->drm.cmdbuf, nvchan->drm.cmdbuf_size, + (void*)&nvchan->pushbuf); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + nouveau_dma_channel_init(&nvchan->base); + nouveau_pushbuf_init(&nvchan->base); + + *chan = &nvchan->base; + return 0; +} + +void +nouveau_channel_free(struct nouveau_channel **chan) +{ + struct nouveau_channel_priv *nvchan; + struct nouveau_device_priv *nvdev; + struct drm_nouveau_channel_free cf; + + if (!chan || !*chan) + return; + nvchan = nouveau_channel(*chan); + *chan = NULL; + nvdev = nouveau_device(nvchan->base.device); + + FIRE_RING_CH(&nvchan->base); + + nouveau_grobj_free(&nvchan->base.vram); + nouveau_grobj_free(&nvchan->base.gart); + + cf.channel = nvchan->drm.channel; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf)); + free(nvchan); +} + + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c new file mode 100644 index 0000000000..01fada5b89 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -0,0 +1,206 @@ +#include "main/glheader.h" +#include "glapi/glthread.h" +#include +#include "utils.h" + +#include "state_tracker/st_public.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" + +#include "nouveau_context.h" +#include "nouveau_dri.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_winsys_pipe.h" + +#ifdef DEBUG +static const struct dri_debug_control debug_control[] = { + { "bo", DEBUG_BO }, + { NULL, 0 } +}; +int __nouveau_debug = 0; +#endif + +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 = CALLOC_STRUCT(nouveau_context); + struct nouveau_device_priv *nvdev; + struct pipe_context *pipe = NULL; + struct st_context *st_share = NULL; + int ret; + + if (sharedContextPrivate) { + st_share = ((struct nouveau_context *)sharedContextPrivate)->st; + } + + if ((ret = nouveau_device_get_param(nv_screen->device, + NOUVEAU_GETPARAM_CHIPSET_ID, + &nv->chipset))) { + NOUVEAU_ERR("Error determining chipset id: %d\n", ret); + return GL_FALSE; + } + + if ((ret = nouveau_channel_alloc(nv_screen->device, + 0x8003d001, 0x8003d002, + &nv->channel))) { + NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); + return GL_FALSE; + } + + driContextPriv->driverPrivate = (void *)nv; + nv->nv_screen = nv_screen; + nv->dri_screen = driScrnPriv; + + nvdev = nouveau_device(nv_screen->device); + nvdev->ctx = driContextPriv->hHWContext; + nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock; + + driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, + nv->dri_screen->myNum, "nouveau"); +#ifdef DEBUG + __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"), + debug_control); +#endif + + /*XXX: Hack up a fake region and buffer object for front buffer. + * This will go away with TTM, replaced with a simple reference + * of the front buffer handle passed to us by the DDX. + */ + { + struct pipe_surface *fb_surf; + struct nouveau_pipe_buffer *fb_buf; + struct nouveau_bo_priv *fb_bo; + + fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); + fb_bo->drm.offset = nv_screen->front_offset; + fb_bo->drm.flags = NOUVEAU_MEM_FB; + fb_bo->drm.size = nv_screen->front_pitch * + nv_screen->front_height; + fb_bo->refcount = 1; + fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; + fb_bo->base.offset = fb_bo->drm.offset; + fb_bo->base.handle = (unsigned long)fb_bo; + fb_bo->base.size = fb_bo->drm.size; + fb_bo->base.device = nv_screen->device; + + fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); + fb_buf->bo = &fb_bo->base; + + fb_surf = calloc(1, sizeof(struct pipe_surface)); + fb_surf->cpp = nv_screen->front_cpp; + fb_surf->pitch = nv_screen->front_pitch / fb_surf->cpp; + fb_surf->height = nv_screen->front_height; + fb_surf->refcount = 1; + fb_surf->buffer = &fb_buf->base; + + nv->frontbuffer = fb_surf; + } + + if ((ret = nouveau_grobj_alloc(nv->channel, 0x00000000, 0x30, + &nv->NvNull))) { + NOUVEAU_ERR("Error creating NULL object: %d\n", ret); + return GL_FALSE; + } + nv->next_handle = 0x80000000; + + if ((ret = nouveau_notifier_alloc(nv->channel, nv->next_handle++, 1, + &nv->sync_notifier))) { + NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); + return GL_FALSE; + } + + if (nv->chipset < 0x50) + ret = nouveau_surface_init_nv04(nv); + else + ret = nouveau_surface_init_nv50(nv); + if (ret) { + return GL_FALSE; + } + + if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { + pipe = nouveau_pipe_create(nv); + if (!pipe) + NOUVEAU_ERR("Couldn't create hw pipe\n"); + } + + if (!pipe) { + NOUVEAU_MSG("Using softpipe\n"); + pipe = nouveau_create_softpipe(nv); + if (!pipe) { + NOUVEAU_ERR("Error creating pipe, bailing\n"); + return GL_FALSE; + } + } + + pipe->priv = nv; + 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_flush(nv->st, PIPE_FLUSH_WAIT); + st_destroy_context(nv->st); + + nouveau_grobj_free(&nv->NvCtxSurf2D); + nouveau_grobj_free(&nv->NvImageBlit); + nouveau_channel_free(&nv->channel); + + 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); + return GL_TRUE; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h new file mode 100644 index 0000000000..5805f969ba --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -0,0 +1,89 @@ +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +#include "dri_util.h" +#include "xmlconfig.h" + +#include "nouveau/nouveau_winsys.h" +#include "nouveau_device.h" +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +struct nouveau_framebuffer { + struct st_framebuffer *stfb; +}; + +struct nouveau_context { + struct st_context *st; + + /* Misc HW info */ + uint64_t chipset; + + /* DRI stuff */ + __DRIscreenPrivate *dri_screen; + __DRIdrawablePrivate *dri_drawable; + unsigned int last_stamp; + driOptionCache dri_option_cache; + drm_context_t drm_context; + drmLock drm_lock; + GLboolean locked; + struct nouveau_screen *nv_screen; + struct pipe_surface *frontbuffer; + + /* Hardware context */ + struct nouveau_channel *channel; + struct nouveau_notifier *sync_notifier; + struct nouveau_grobj *NvNull; + struct nouveau_grobj *NvCtxSurf2D; + struct nouveau_grobj *NvImageBlit; + struct nouveau_grobj *NvGdiRect; + struct nouveau_grobj *NvM2MF; + struct nouveau_grobj *Nv2D; + uint32_t next_handle; + uint32_t next_subchannel; + uint32_t next_sequence; + + /* pipe_surface accel */ + struct pipe_surface *surf_src, *surf_dst; + unsigned surf_src_offset, surf_dst_offset; + int (*surface_copy_prep)(struct nouveau_context *, + struct pipe_surface *dst, + struct pipe_surface *src); + void (*surface_copy)(struct nouveau_context *, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h); + void (*surface_copy_done)(struct nouveau_context *); + int (*surface_fill)(struct nouveau_context *, struct pipe_surface *, + unsigned, unsigned, unsigned, unsigned, unsigned); +}; + +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 *); + +#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 + +extern void LOCK_HARDWARE(struct nouveau_context *); +extern void UNLOCK_HARDWARE(struct nouveau_context *); + +extern int nouveau_surface_init_nv04(struct nouveau_context *); +extern int nouveau_surface_init_nv50(struct nouveau_context *); + +extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int); +extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *); + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_device.c b/src/gallium/winsys/dri/nouveau/nouveau_device.c new file mode 100644 index 0000000000..409e4415f7 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_device.c @@ -0,0 +1,146 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include + +#include "nouveau_drmif.h" + +int +nouveau_device_open_existing(struct nouveau_device **dev, int close, + int fd, drm_context_t ctx) +{ + struct nouveau_device_priv *nvdev; + int ret; + + if (!dev || *dev) + return -EINVAL; + + nvdev = calloc(1, sizeof(*nvdev)); + if (!nvdev) + return -ENOMEM; + nvdev->fd = fd; + nvdev->ctx = ctx; + nvdev->needs_close = close; + + drmCommandNone(nvdev->fd, DRM_NOUVEAU_CARD_INIT); + + if ((ret = nouveau_bo_init(&nvdev->base))) { + nouveau_device_close((void *)&nvdev); + return ret; + } + + *dev = &nvdev->base; + return 0; +} + +int +nouveau_device_open(struct nouveau_device **dev, const char *busid) +{ + drm_context_t ctx; + int fd, ret; + + if (!dev || *dev) + return -EINVAL; + + fd = drmOpen("nouveau", busid); + if (fd < 0) + return -EINVAL; + + ret = drmCreateContext(fd, &ctx); + if (ret) { + drmClose(fd); + return ret; + } + + ret = nouveau_device_open_existing(dev, 1, fd, ctx); + if (ret) { + drmDestroyContext(fd, ctx); + drmClose(fd); + return ret; + } + + return 0; +} + +void +nouveau_device_close(struct nouveau_device **dev) +{ + struct nouveau_device_priv *nvdev; + + if (dev || !*dev) + return; + nvdev = nouveau_device(*dev); + *dev = NULL; + + nouveau_bo_takedown(&nvdev->base); + + if (nvdev->needs_close) { + drmDestroyContext(nvdev->fd, nvdev->ctx); + drmClose(nvdev->fd); + } + free(nvdev); +} + +int +nouveau_device_get_param(struct nouveau_device *dev, + uint64_t param, uint64_t *value) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct drm_nouveau_getparam g; + int ret; + + if (!nvdev || !value) + return -EINVAL; + + g.param = param; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GETPARAM, + &g, sizeof(g)); + if (ret) + return ret; + + *value = g.value; + return 0; +} + +int +nouveau_device_set_param(struct nouveau_device *dev, + uint64_t param, uint64_t value) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct drm_nouveau_setparam s; + int ret; + + if (!nvdev) + return -EINVAL; + + s.param = param; + s.value = value; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_SETPARAM, + &s, sizeof(s)); + if (ret) + return ret; + + return 0; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_device.h b/src/gallium/winsys/dri/nouveau/nouveau_device.h new file mode 100644 index 0000000000..744a89f74b --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_device.h @@ -0,0 +1,29 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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. + */ + +#ifndef __NOUVEAU_DEVICE_H__ +#define __NOUVEAU_DEVICE_H__ + +struct nouveau_device { +}; + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_dma.c b/src/gallium/winsys/dri/nouveau/nouveau_dma.c new file mode 100644 index 0000000000..f8a8ba04f6 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_dma.c @@ -0,0 +1,219 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" +#include "nouveau_local.h" + +static inline uint32_t +READ_GET(struct nouveau_channel_priv *nvchan) +{ + return *nvchan->get; +} + +static inline void +WRITE_PUT(struct nouveau_channel_priv *nvchan, uint32_t val) +{ + uint32_t put = ((val << 2) + nvchan->dma->base); + volatile int dum; + + NOUVEAU_DMA_BARRIER; + dum = READ_GET(nvchan); + + *nvchan->put = put; + nvchan->dma->put = val; +#ifdef NOUVEAU_DMA_TRACE + NOUVEAU_MSG("WRITE_PUT %d/0x%08x\n", nvchan->drm.channel, put); +#endif + + NOUVEAU_DMA_BARRIER; +} + +static inline int +LOCAL_GET(struct nouveau_dma_priv *dma, uint32_t *val) +{ + uint32_t get = *val; + + if (get >= dma->base && get <= (dma->base + (dma->max << 2))) { + *val = (get - dma->base) >> 2; + return 1; + } + + return 0; +} + +void +nouveau_dma_channel_init(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + int i; + + nvchan->dma = &nvchan->dma_master; + nvchan->dma->base = nvchan->drm.put_base; + nvchan->dma->cur = nvchan->dma->put = 0; + nvchan->dma->max = (nvchan->drm.cmdbuf_size >> 2) - 2; + nvchan->dma->free = nvchan->dma->max - nvchan->dma->cur; + + RING_SPACE_CH(chan, RING_SKIPS); + for (i = 0; i < RING_SKIPS; i++) + OUT_RING_CH(chan, 0); +} + +#define CHECK_TIMEOUT() do { \ + if ((NOUVEAU_TIME_MSEC() - t_start) > NOUVEAU_DMA_TIMEOUT) \ + return - EBUSY; \ +} while(0) + +int +nouveau_dma_wait(struct nouveau_channel *chan, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + uint32_t get, t_start; + + FIRE_RING_CH(chan); + + t_start = NOUVEAU_TIME_MSEC(); + while (dma->free < size) { + CHECK_TIMEOUT(); + + get = READ_GET(nvchan); + if (!LOCAL_GET(dma, &get)) + continue; + + if (dma->put >= get) { + dma->free = dma->max - dma->cur; + + if (dma->free < size) { +#ifdef NOUVEAU_DMA_DEBUG + dma->push_free = 1; +#endif + OUT_RING_CH(chan, 0x20000000 | dma->base); + if (get <= RING_SKIPS) { + /*corner case - will be idle*/ + if (dma->put <= RING_SKIPS) + WRITE_PUT(nvchan, + RING_SKIPS + 1); + + do { + CHECK_TIMEOUT(); + get = READ_GET(nvchan); + if (!LOCAL_GET(dma, &get)) + get = 0; + } while (get <= RING_SKIPS); + } + + WRITE_PUT(nvchan, RING_SKIPS); + dma->cur = dma->put = RING_SKIPS; + dma->free = get - (RING_SKIPS + 1); + } + } else { + dma->free = get - dma->cur - 1; + } + } + + return 0; +} + +#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF +static void +nouveau_dma_parse_pushbuf(struct nouveau_channel *chan, int get, int put) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + unsigned mthd_count = 0; + + while (get != put) { + uint32_t gpuget = (get << 2) + nvchan->drm.put_base; + uint32_t data; + + if (get < 0 || get >= nvchan->drm.cmdbuf_size) { + NOUVEAU_ERR("DMA_PT 0x%08x\n", gpuget); + assert(0); + } + data = nvchan->pushbuf[get++]; + + if (mthd_count) { + NOUVEAU_MSG("0x%08x 0x%08x\n", gpuget, data); + mthd_count--; + continue; + } + + switch (data & 0x60000000) { + case 0x00000000: + mthd_count = (data >> 18) & 0x7ff; + NOUVEAU_MSG("0x%08x 0x%08x MTHD " + "Sc %d Mthd 0x%04x Size %d\n", + gpuget, data, (data>>13) & 7, data & 0x1ffc, + mthd_count); + break; + case 0x20000000: + get = (data & 0x1ffffffc) >> 2; + NOUVEAU_MSG("0x%08x 0x%08x JUMP 0x%08x\n", + gpuget, data, data & 0x1ffffffc); + continue; + case 0x40000000: + mthd_count = (data >> 18) & 0x7ff; + NOUVEAU_MSG("0x%08x 0x%08x NINC " + "Sc %d Mthd 0x%04x Size %d\n", + gpuget, data, (data>>13) & 7, data & 0x1ffc, + mthd_count); + break; + case 0x60000000: + /* DMA_OPCODE_CALL apparently, doesn't seem to work on + * my NV40 at least.. + */ + /* fall-through */ + default: + NOUVEAU_MSG("DMA_PUSHER 0x%08x 0x%08x\n", + gpuget, data); + assert(0); + } + } +} +#endif + +void +nouveau_dma_kickoff(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + + if (dma->cur == dma->put) + return; + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free) { + NOUVEAU_ERR("Packet incomplete: %d left\n", dma->push_free); + return; + } +#endif + +#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF + nouveau_dma_parse_pushbuf(chan, dma->put, dma->cur); +#endif + + WRITE_PUT(nvchan, dma->cur); +} diff --git a/src/gallium/winsys/dri/nouveau/nouveau_dma.h b/src/gallium/winsys/dri/nouveau/nouveau_dma.h new file mode 100644 index 0000000000..cfa6d26e82 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_dma.h @@ -0,0 +1,143 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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. + */ + +#ifndef __NOUVEAU_DMA_H__ +#define __NOUVEAU_DMA_H__ + +#include +#include "nouveau_drmif.h" +#include "nouveau_local.h" + +#define RING_SKIPS 8 + +extern int nouveau_dma_wait(struct nouveau_channel *chan, int size); +extern void nouveau_dma_subc_bind(struct nouveau_grobj *); +extern void nouveau_dma_channel_init(struct nouveau_channel *); +extern void nouveau_dma_kickoff(struct nouveau_channel *); + +#ifdef NOUVEAU_DMA_DEBUG +static char faulty[1024]; +#endif + +static inline void +nouveau_dma_out(struct nouveau_channel *chan, uint32_t data) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free == 0) { + NOUVEAU_ERR("No space left in packet at %s\n", faulty); + return; + } + dma->push_free--; +#endif +#ifdef NOUVEAU_DMA_TRACE + { + uint32_t offset = (dma->cur << 2) + dma->base; + NOUVEAU_MSG("\tOUT_RING %d/0x%08x -> 0x%08x\n", + nvchan->drm.channel, offset, data); + } +#endif + nvchan->pushbuf[dma->cur + (dma->base - nvchan->drm.put_base)/4] = data; + dma->cur++; +} + +static inline void +nouveau_dma_outp(struct nouveau_channel *chan, uint32_t *ptr, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + (void)dma; + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free < size) { + NOUVEAU_ERR("Packet too small. Free=%d, Need=%d\n", + dma->push_free, size); + return; + } +#endif +#ifdef NOUVEAU_DMA_TRACE + while (size--) { + nouveau_dma_out(chan, *ptr); + ptr++; + } +#else + memcpy(&nvchan->pushbuf[dma->cur], ptr, size << 2); +#ifdef NOUVEAU_DMA_DEBUG + dma->push_free -= size; +#endif + dma->cur += size; +#endif +} + +static inline void +nouveau_dma_space(struct nouveau_channel *chan, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + + if (dma->free < size) { + if (nouveau_dma_wait(chan, size) && chan->hang_notify) + chan->hang_notify(chan); + } + dma->free -= size; +#ifdef NOUVEAU_DMA_DEBUG + dma->push_free = size; +#endif +} + +static inline void +nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj, + int method, int size, const char* file, int line) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + (void)dma; + +#ifdef NOUVEAU_DMA_TRACE + NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", nvchan->drm.channel, + grobj->handle, grobj->subc, method, size); +#endif + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free) { + NOUVEAU_ERR("Previous packet incomplete: %d left at %s\n", + dma->push_free, faulty); + return; + } + sprintf(faulty,"%s:%d",file,line); +#endif + + nouveau_dma_space(chan, (size + 1)); + nouveau_dma_out(chan, (size << 18) | (grobj->subc << 13) | method); +} + +#define RING_SPACE_CH(ch,sz) nouveau_dma_space((ch), (sz)) +#define BEGIN_RING_CH(ch,gr,m,sz) nouveau_dma_begin((ch), (gr), (m), (sz), __FUNCTION__, __LINE__ ) +#define OUT_RING_CH(ch, data) nouveau_dma_out((ch), (data)) +#define OUT_RINGp_CH(ch,ptr,dwords) nouveau_dma_outp((ch), (void*)(ptr), \ + (dwords)) +#define FIRE_RING_CH(ch) nouveau_dma_kickoff((ch)) +#define WAIT_RING_CH(ch,sz) nouveau_dma_wait((ch), (sz)) + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_dri.h b/src/gallium/winsys/dri/nouveau/nouveau_dri.h new file mode 100644 index 0000000000..1207c2d609 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_dri.h @@ -0,0 +1,28 @@ +#ifndef _NOUVEAU_DRI_ +#define _NOUVEAU_DRI_ + +#include "xf86drm.h" +#include "drm.h" +#include "nouveau_drm.h" + +struct nouveau_dri { + uint32_t device_id; /**< \brief PCI device ID */ + uint32_t width; /**< \brief width in pixels of display */ + uint32_t height; /**< \brief height in scanlines of display */ + uint32_t depth; /**< \brief depth of display (8, 15, 16, 24) */ + uint32_t bpp; /**< \brief bit depth of display (8, 16, 24, 32) */ + + uint32_t bus_type; /**< \brief ths bus type */ + uint32_t bus_mode; /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */ + + uint32_t front_offset; /**< \brief front buffer offset */ + uint32_t front_pitch; /**< \brief front buffer pitch */ + uint32_t back_offset; /**< \brief private back buffer offset */ + uint32_t back_pitch; /**< \brief private back buffer pitch */ + uint32_t depth_offset; /**< \brief private depth buffer offset */ + uint32_t depth_pitch; /**< \brief private depth buffer pitch */ + +}; + +#endif + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h new file mode 100644 index 0000000000..37e404fc6c --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -0,0 +1,304 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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. + */ + +#ifndef __NOUVEAU_DRMIF_H__ +#define __NOUVEAU_DRMIF_H__ + +#include +#include +#include + +#include "nouveau_device.h" +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_grobj.h" +#include "nouveau/nouveau_notifier.h" +#include "nouveau/nouveau_bo.h" +#include "nouveau/nouveau_resource.h" +#include "nouveau/nouveau_pushbuf.h" + +struct nouveau_device_priv { + struct nouveau_device base; + + int fd; + drm_context_t ctx; + drmLock *lock; + int needs_close; + + struct drm_nouveau_mem_alloc sa; + void *sa_map; + struct nouveau_resource *sa_heap; +}; +#define nouveau_device(n) ((struct nouveau_device_priv *)(n)) + +extern int +nouveau_device_open_existing(struct nouveau_device **, int close, + int fd, drm_context_t ctx); + +extern int +nouveau_device_open(struct nouveau_device **, const char *busid); + +extern void +nouveau_device_close(struct nouveau_device **); + +extern int +nouveau_device_get_param(struct nouveau_device *, uint64_t param, uint64_t *v); + +extern int +nouveau_device_set_param(struct nouveau_device *, uint64_t param, uint64_t val); + +struct nouveau_fence { + struct nouveau_channel *channel; +}; + +struct nouveau_fence_cb { + struct nouveau_fence_cb *next; + void (*func)(void *); + void *priv; +}; + +struct nouveau_fence_priv { + struct nouveau_fence base; + int refcount; + + struct nouveau_fence *next; + struct nouveau_fence_cb *signal_cb; + + uint32_t sequence; + int emitted; + int signalled; +}; +#define nouveau_fence(n) ((struct nouveau_fence_priv *)(n)) + +extern int +nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **); + +extern int +nouveau_fence_ref(struct nouveau_fence *, struct nouveau_fence **); + +extern int +nouveau_fence_signal_cb(struct nouveau_fence *, void (*)(void *), void *); + +extern void +nouveau_fence_emit(struct nouveau_fence *); + +extern int +nouveau_fence_wait(struct nouveau_fence **); + +extern void +nouveau_fence_flush(struct nouveau_channel *); + +struct nouveau_pushbuf_reloc { + uint64_t next; + uint64_t handle; + uint32_t *ptr; + uint32_t flags; + uint32_t data; + uint32_t vor; + uint32_t tor; +}; + +struct nouveau_pushbuf_bo { + uint64_t next; + uint64_t handle; + uint64_t flags; + uint64_t relocs; + int nr_relocs; +}; + +struct nouveau_pushbuf_priv { + struct nouveau_pushbuf base; + + unsigned nop_jump; + unsigned start; + unsigned size; + + uint64_t buffers; + int nr_buffers; +}; +#define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n)) + +#define pbbo_to_ptr(o) ((uint64_t)(unsigned long)(o)) +#define ptr_to_pbbo(h) ((struct nouveau_pushbuf_bo *)(unsigned long)(h)) +#define pbrel_to_ptr(o) ((uint64_t)(unsigned long)(o)) +#define ptr_to_pbrel(h) ((struct nouveau_pushbuf_reloc *)(unsigned long)(h)) +#define bo_to_ptr(o) ((uint64_t)(unsigned long)(o)) +#define ptr_to_bo(h) ((struct nouveau_bo_priv *)(unsigned long)(h)) + +extern int +nouveau_pushbuf_init(struct nouveau_channel *); + +extern int +nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); + +extern int +nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr, + struct nouveau_bo *, uint32_t data, uint32_t flags, + uint32_t vor, uint32_t tor); + +struct nouveau_dma_priv { + uint32_t base; + uint32_t max; + uint32_t cur; + uint32_t put; + uint32_t free; + + int push_free; +} dma; + +struct nouveau_channel_priv { + struct nouveau_channel base; + + struct drm_nouveau_channel_alloc drm; + + uint32_t *pushbuf; + void *notifier_block; + + volatile uint32_t *user; + volatile uint32_t *put; + volatile uint32_t *get; + volatile uint32_t *ref_cnt; + + struct nouveau_dma_priv dma_master; + struct nouveau_dma_priv dma_bufmgr; + struct nouveau_dma_priv *dma; + + struct nouveau_fence *fence_head; + struct nouveau_fence *fence_tail; + uint32_t fence_sequence; + + struct nouveau_pushbuf_priv pb; + + unsigned user_charge; +}; +#define nouveau_channel(n) ((struct nouveau_channel_priv *)(n)) + +extern int +nouveau_channel_alloc(struct nouveau_device *, uint32_t fb, uint32_t tt, + struct nouveau_channel **); + +extern void +nouveau_channel_free(struct nouveau_channel **); + +struct nouveau_grobj_priv { + struct nouveau_grobj base; +}; +#define nouveau_grobj(n) ((struct nouveau_grobj_priv *)(n)) + +extern int nouveau_grobj_alloc(struct nouveau_channel *, uint32_t handle, + int class, struct nouveau_grobj **); +extern int nouveau_grobj_ref(struct nouveau_channel *, uint32_t handle, + struct nouveau_grobj **); +extern void nouveau_grobj_free(struct nouveau_grobj **); + + +struct nouveau_notifier_priv { + struct nouveau_notifier base; + + struct drm_nouveau_notifierobj_alloc drm; + volatile void *map; +}; +#define nouveau_notifier(n) ((struct nouveau_notifier_priv *)(n)) + +extern int +nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, int count, + struct nouveau_notifier **); + +extern void +nouveau_notifier_free(struct nouveau_notifier **); + +extern void +nouveau_notifier_reset(struct nouveau_notifier *, int id); + +extern uint32_t +nouveau_notifier_status(struct nouveau_notifier *, int id); + +extern uint32_t +nouveau_notifier_return_val(struct nouveau_notifier *, int id); + +extern int +nouveau_notifier_wait_status(struct nouveau_notifier *, int id, int status, + int timeout); + +struct nouveau_bo_priv { + struct nouveau_bo base; + + struct nouveau_fence *fence; + struct nouveau_fence *wr_fence; + + struct drm_nouveau_mem_alloc drm; + void *map; + + void *sysmem; + int user; + + int refcount; + + uint64_t offset; + uint64_t flags; +}; +#define nouveau_bo(n) ((struct nouveau_bo_priv *)(n)) + +extern int +nouveau_bo_init(struct nouveau_device *); + +extern void +nouveau_bo_takedown(struct nouveau_device *); + +extern int +nouveau_bo_new(struct nouveau_device *, uint32_t flags, int align, int size, + struct nouveau_bo **); + +extern int +nouveau_bo_user(struct nouveau_device *, void *ptr, int size, + struct nouveau_bo **); + +extern int +nouveau_bo_ref(struct nouveau_device *, uint64_t handle, struct nouveau_bo **); + +extern int +nouveau_bo_set_status(struct nouveau_bo *, uint32_t flags); + +extern void +nouveau_bo_del(struct nouveau_bo **); + +extern int +nouveau_bo_map(struct nouveau_bo *, uint32_t flags); + +extern void +nouveau_bo_unmap(struct nouveau_bo *); + +extern int +nouveau_bo_validate(struct nouveau_channel *, struct nouveau_bo *, + struct nouveau_fence *fence, uint32_t flags); + +extern int +nouveau_resource_init(struct nouveau_resource **heap, unsigned start, + unsigned size); + +extern int +nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, + struct nouveau_resource **); + +extern void +nouveau_resource_free(struct nouveau_resource **); + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_fence.c b/src/gallium/winsys/dri/nouveau/nouveau_fence.c new file mode 100644 index 0000000000..7714e6f248 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_fence.c @@ -0,0 +1,215 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" +#include "nouveau_local.h" + +static void +nouveau_fence_del_unsignalled(struct nouveau_fence *fence) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); + struct nouveau_fence *le; + + if (nvchan->fence_head == fence) { + nvchan->fence_head = nouveau_fence(fence)->next; + if (nvchan->fence_head == NULL) + nvchan->fence_tail = NULL; + return; + } + + le = nvchan->fence_head; + while (le && nouveau_fence(le)->next != fence) + le = nouveau_fence(le)->next; + assert(le && nouveau_fence(le)->next == fence); + nouveau_fence(le)->next = nouveau_fence(fence)->next; + if (nvchan->fence_tail == fence) + nvchan->fence_tail = le; +} + +static void +nouveau_fence_del(struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!fence || !*fence) + return; + nvfence = nouveau_fence(*fence); + *fence = NULL; + + if (--nvfence->refcount) + return; + + if (nvfence->emitted && !nvfence->signalled) { + if (nvfence->signal_cb) { + nvfence->refcount++; + nouveau_fence_wait((void *)&nvfence); + return; + } + + nouveau_fence_del_unsignalled(&nvfence->base); + } + free(nvfence); +} + +int +nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!chan || !fence || *fence) + return -EINVAL; + + nvfence = calloc(1, sizeof(struct nouveau_fence_priv)); + if (!nvfence) + return -ENOMEM; + nvfence->base.channel = chan; + nvfence->refcount = 1; + + *fence = &nvfence->base; + return 0; +} + +int +nouveau_fence_ref(struct nouveau_fence *ref, struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!fence) + return -EINVAL; + + if (*fence) { + nouveau_fence_del(fence); + *fence = NULL; + } + + if (ref) { + nvfence = nouveau_fence(ref); + nvfence->refcount++; + *fence = &nvfence->base; + } + + return 0; +} + +int +nouveau_fence_signal_cb(struct nouveau_fence *fence, void (*func)(void *), + void *priv) +{ + struct nouveau_fence_priv *nvfence = nouveau_fence(fence); + struct nouveau_fence_cb *cb; + + if (!nvfence || !func) + return -EINVAL; + + cb = malloc(sizeof(struct nouveau_fence_cb)); + if (!cb) + return -ENOMEM; + + cb->func = func; + cb->priv = priv; + cb->next = nvfence->signal_cb; + nvfence->signal_cb = cb; + return 0; +} + +void +nouveau_fence_emit(struct nouveau_fence *fence) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); + struct nouveau_fence_priv *nvfence = nouveau_fence(fence); + + nvfence->emitted = 1; + nvfence->sequence = ++nvchan->fence_sequence; + if (nvfence->sequence == 0xffffffff) + NOUVEAU_ERR("AII wrap unhandled\n"); + + /*XXX: assumes subc 0 is populated */ + RING_SPACE_CH(fence->channel, 2); + OUT_RING_CH (fence->channel, 0x00040050); + OUT_RING_CH (fence->channel, nvfence->sequence); + + if (nvchan->fence_tail) { + nouveau_fence(nvchan->fence_tail)->next = fence; + } else { + nvchan->fence_head = fence; + } + nvchan->fence_tail = fence; +} + +void +nouveau_fence_flush(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + uint32_t sequence = *nvchan->ref_cnt; + + while (nvchan->fence_head) { + struct nouveau_fence_priv *nvfence; + + nvfence = nouveau_fence(nvchan->fence_head); + if (nvfence->sequence > sequence) + break; + + nouveau_fence_del_unsignalled(&nvfence->base); + nvfence->signalled = 1; + + if (nvfence->signal_cb) { + struct nouveau_fence *fence = NULL; + + nouveau_fence_ref(nvchan->fence_head, &fence); + + while (nvfence->signal_cb) { + struct nouveau_fence_cb *cb; + + cb = nvfence->signal_cb; + nvfence->signal_cb = cb->next; + cb->func(cb->priv); + free(cb); + } + + nouveau_fence_ref(NULL, &fence); + } + } +} + +int +nouveau_fence_wait(struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!fence || !*fence) + return -EINVAL; + nvfence = nouveau_fence(*fence); + + if (nvfence->emitted) { + while (!nvfence->signalled) + nouveau_fence_flush(nvfence->base.channel); + } + nouveau_fence_ref(NULL, fence); + + return 0; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_grobj.c b/src/gallium/winsys/dri/nouveau/nouveau_grobj.c new file mode 100644 index 0000000000..55dfeb99aa --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_grobj.c @@ -0,0 +1,107 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include + +#include "nouveau_drmif.h" + +int +nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle, + int class, struct nouveau_grobj **grobj) +{ + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_grobj_priv *nvgrobj; + struct drm_nouveau_grobj_alloc g; + int ret; + + if (!nvdev || !grobj || *grobj) + return -EINVAL; + + nvgrobj = calloc(1, sizeof(*nvgrobj)); + if (!nvgrobj) + return -ENOMEM; + nvgrobj->base.channel = chan; + nvgrobj->base.handle = handle; + nvgrobj->base.grclass = class; + + g.channel = chan->id; + g.handle = handle; + g.class = class; + ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GROBJ_ALLOC, + &g, sizeof(g)); + if (ret) { + nouveau_grobj_free((void *)&grobj); + return ret; + } + + *grobj = &nvgrobj->base; + return 0; +} + +int +nouveau_grobj_ref(struct nouveau_channel *chan, uint32_t handle, + struct nouveau_grobj **grobj) +{ + struct nouveau_grobj_priv *nvgrobj; + + if (!chan || !grobj || *grobj) + return -EINVAL; + + nvgrobj = calloc(1, sizeof(struct nouveau_grobj_priv)); + if (!nvgrobj) + return -ENOMEM; + nvgrobj->base.channel = chan; + nvgrobj->base.handle = handle; + nvgrobj->base.grclass = 0; + + *grobj = &nvgrobj->base; + return 0; +} + +void +nouveau_grobj_free(struct nouveau_grobj **grobj) +{ + struct nouveau_device_priv *nvdev; + struct nouveau_channel_priv *chan; + struct nouveau_grobj_priv *nvgrobj; + + if (!grobj || !*grobj) + return; + nvgrobj = nouveau_grobj(*grobj); + *grobj = NULL; + + + chan = nouveau_channel(nvgrobj->base.channel); + nvdev = nouveau_device(chan->base.device); + + if (nvgrobj->base.grclass) { + struct drm_nouveau_gpuobj_free f; + + f.channel = chan->drm.channel; + f.handle = nvgrobj->base.handle; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, + &f, sizeof(f)); + } + free(nvgrobj); +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_local.h b/src/gallium/winsys/dri/nouveau/nouveau_local.h new file mode 100644 index 0000000000..59febca292 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_local.h @@ -0,0 +1,89 @@ +#ifndef __NOUVEAU_LOCAL_H__ +#define __NOUVEAU_LOCAL_H__ + +#include + +/* Debug output */ +#define NOUVEAU_MSG(fmt, args...) do { \ + fprintf(stdout, "nouveau: "fmt, ##args); \ + fflush(stdout); \ +} while(0) + +#define NOUVEAU_ERR(fmt, args...) do { \ + fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); \ + fflush(stderr); \ +} while(0) + +#define NOUVEAU_TIME_MSEC() 0 + +/* User FIFO control */ +//#define NOUVEAU_DMA_TRACE +//#define NOUVEAU_DMA_DEBUG +//#define NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF +#define NOUVEAU_DMA_BARRIER +#define NOUVEAU_DMA_TIMEOUT 2000 + +/* Push buffer access macros */ +#define OUT_RING(data) do { \ + (*nv->channel->pushbuf->cur++) = (data); \ +} while(0) + +#define OUT_RINGp(src,size) do { \ + memcpy(nv->channel->pushbuf->cur, (src), (size)<<2); \ + nv->channel->pushbuf->cur += (size); \ +} while(0) + +#define OUT_RINGf(data) do { \ + union { float v; uint32_t u; } c; \ + c.v = (data); \ + OUT_RING(c.u); \ +} while(0) + +#define FIRE_RING() do { \ + nouveau_pushbuf_flush(nv->channel, 0); \ +} while(0) + +#define BEGIN_RING_GR(obj,mthd,size) do { \ + if (nv->channel->pushbuf->remaining < ((size) + 1)) \ + nouveau_pushbuf_flush(nv->channel, ((size) + 1)); \ + OUT_RING(((obj)->subc << 13) | ((size) << 18) | (mthd)); \ + nv->channel->pushbuf->remaining -= ((size) + 1); \ +} while(0) + +#define BEGIN_RING(obj,mthd,size) do { \ + BEGIN_RING_GR(nv->obj, (mthd), (size)); \ +} while(0) + +#define BIND_RING(o,s) do { \ + nv->o->subc = (s); \ + BEGIN_RING(o, 0x0000, 1); \ + OUT_RING (nv->o->handle); \ +} while(0) + +#define OUT_RELOC(buf,data,flags,vor,tor) do { \ + nouveau_pipe_emit_reloc(nv->channel, nv->channel->pushbuf->cur++, \ + buf, (data), (flags), (vor), (tor)); \ +} while(0) + +/* Raw data + flags depending on FB/TT buffer */ +#define OUT_RELOCd(bo,data,flags,vor,tor) do { \ + OUT_RELOC((bo), (data), (flags) | NOUVEAU_BO_OR, (vor), (tor)); \ +} while(0) + +/* FB/TT object handle */ +#define OUT_RELOCo(bo,flags) do { \ + OUT_RELOC((bo), 0, (flags) | NOUVEAU_BO_OR, \ + nv->channel->vram->handle, nv->channel->gart->handle); \ +} while(0) + +/* Low 32-bits of offset */ +#define OUT_RELOCl(bo,delta,flags) do { \ + OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_LOW, 0, 0); \ +} while(0) + +/* High 32-bits of offset */ +#define OUT_RELOCh(bo,delta,flags) do { \ + OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_HIGH, 0, 0); \ +} while(0) + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_lock.c b/src/gallium/winsys/dri/nouveau/nouveau_lock.c new file mode 100644 index 0000000000..9adb9ac854 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_lock.c @@ -0,0 +1,94 @@ +/************************************************************************** + * + * 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 "main/glheader.h" +#include "glapi/glthread.h" +#include + +#include "nouveau_context.h" +#include "nouveau_screen.h" + +_glthread_DECLARE_STATIC_MUTEX( lockMutex ); + +static void +nouveau_contended_lock(struct nouveau_context *nv, GLuint flags) +{ + __DRIdrawablePrivate *dPriv = nv->dri_drawable; + __DRIscreenPrivate *sPriv = nv->dri_screen; + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + drmGetLock(nvdev->fd, nvdev->ctx, flags); + + /* 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); +} + +/* Lock the hardware and validate our state. + */ +void +LOCK_HARDWARE(struct nouveau_context *nv) +{ + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + char __ret=0; + + _glthread_LOCK_MUTEX(lockMutex); + assert(!nv->locked); + + DRM_CAS(nvdev->lock, nvdev->ctx, + (DRM_LOCK_HELD | nvdev->ctx), __ret); + + if (__ret) + nouveau_contended_lock(nv, 0); + nv->locked = GL_TRUE; +} + + + /* Unlock the hardware using the global current context + */ +void +UNLOCK_HARDWARE(struct nouveau_context *nv) +{ + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + assert(nv->locked); + nv->locked = GL_FALSE; + + DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx); + + _glthread_UNLOCK_MUTEX(lockMutex); +} diff --git a/src/gallium/winsys/dri/nouveau/nouveau_notifier.c b/src/gallium/winsys/dri/nouveau/nouveau_notifier.c new file mode 100644 index 0000000000..01e8f38440 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_notifier.c @@ -0,0 +1,137 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include + +#include "nouveau_drmif.h" +#include "nouveau_local.h" + +#define NOTIFIER(__v) \ + struct nouveau_notifier_priv *nvnotify = nouveau_notifier(notifier); \ + volatile uint32_t *__v = (void*)nvnotify->map + (id * 32) + +int +nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, + int count, struct nouveau_notifier **notifier) +{ + struct nouveau_notifier_priv *nvnotify; + int ret; + + if (!chan || !notifier || *notifier) + return -EINVAL; + + nvnotify = calloc(1, sizeof(struct nouveau_notifier_priv)); + if (!nvnotify) + return -ENOMEM; + nvnotify->base.channel = chan; + nvnotify->base.handle = handle; + + nvnotify->drm.channel = chan->id; + nvnotify->drm.handle = handle; + nvnotify->drm.count = count; + if ((ret = drmCommandWriteRead(nouveau_device(chan->device)->fd, + DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, + &nvnotify->drm, + sizeof(nvnotify->drm)))) { + nouveau_notifier_free((void *)&nvnotify); + return ret; + } + + nvnotify->map = (void *)nouveau_channel(chan)->notifier_block + + nvnotify->drm.offset; + *notifier = &nvnotify->base; + return 0; +} + +void +nouveau_notifier_free(struct nouveau_notifier **notifier) +{ + + struct nouveau_notifier_priv *nvnotify; + struct nouveau_channel_priv *nvchan; + struct nouveau_device_priv *nvdev; + struct drm_nouveau_gpuobj_free f; + + if (!notifier || !*notifier) + return; + nvnotify = nouveau_notifier(*notifier); + *notifier = NULL; + + nvchan = nouveau_channel(nvnotify->base.channel); + nvdev = nouveau_device(nvchan->base.device); + + f.channel = nvchan->drm.channel; + f.handle = nvnotify->base.handle; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, &f, sizeof(f)); + free(nvnotify); +} + +void +nouveau_notifier_reset(struct nouveau_notifier *notifier, int id) +{ + NOTIFIER(n); + + n[NV_NOTIFY_TIME_0 /4] = 0x00000000; + n[NV_NOTIFY_TIME_1 /4] = 0x00000000; + n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000; + n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS << + NV_NOTIFY_STATE_STATUS_SHIFT); +} + +uint32_t +nouveau_notifier_status(struct nouveau_notifier *notifier, int id) +{ + NOTIFIER(n); + + return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; +} + +uint32_t +nouveau_notifier_return_val(struct nouveau_notifier *notifier, int id) +{ + NOTIFIER(n); + + return n[NV_NOTIFY_RETURN_VALUE/4]; +} + +int +nouveau_notifier_wait_status(struct nouveau_notifier *notifier, int id, + int status, int timeout) +{ + NOTIFIER(n); + uint32_t time = 0, t_start = NOUVEAU_TIME_MSEC(); + + while (time <= timeout) { + uint32_t v; + + v = n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; + if (v == status) + return 0; + + if (timeout) + time = NOUVEAU_TIME_MSEC() - t_start; + } + + return -EBUSY; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c new file mode 100644 index 0000000000..7d5eddb92f --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -0,0 +1,261 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +#define PB_BUFMGR_DWORDS (4096 / 2) +#define PB_MIN_USER_DWORDS 2048 + +static int +nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; + + assert((min + 1) <= nvchan->dma->max); + + /* Wait for enough space in push buffer */ + min = min < PB_MIN_USER_DWORDS ? PB_MIN_USER_DWORDS : min; + min += 1; /* a bit extra for the NOP */ + if (nvchan->dma->free < min) + WAIT_RING_CH(chan, min); + + /* Insert NOP, may turn into a jump later */ + RING_SPACE_CH(chan, 1); + nvpb->nop_jump = nvchan->dma->cur; + OUT_RING_CH(chan, 0); + + /* Any remaining space is available to the user */ + nvpb->start = nvchan->dma->cur; + nvpb->size = nvchan->dma->free; + nvpb->base.channel = chan; + nvpb->base.remaining = nvpb->size; + nvpb->base.cur = &nvchan->pushbuf[nvpb->start]; + + return 0; +} + +int +nouveau_pushbuf_init(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *m = &nvchan->dma_master; + struct nouveau_dma_priv *b = &nvchan->dma_bufmgr; + int i; + + if (!nvchan) + return -EINVAL; + + /* Reassign last bit of push buffer for a "separate" bufmgr + * ring buffer + */ + m->max -= PB_BUFMGR_DWORDS; + m->free -= PB_BUFMGR_DWORDS; + + b->base = m->base + ((m->max + 2) << 2); + b->max = PB_BUFMGR_DWORDS - 2; + b->cur = b->put = 0; + b->free = b->max - b->cur; + + /* Some NOPs just to be safe + *XXX: RING_SKIPS + */ + nvchan->dma = b; + RING_SPACE_CH(chan, 8); + for (i = 0; i < 8; i++) + OUT_RING_CH(chan, 0); + nvchan->dma = m; + + nouveau_pushbuf_space(chan, 0); + chan->pushbuf = &nvchan->pb.base; + + return 0; +} + +static uint32_t +nouveau_pushbuf_calc_reloc(struct nouveau_bo *bo, + struct nouveau_pushbuf_reloc *r) +{ + uint32_t push; + + if (r->flags & NOUVEAU_BO_LOW) { + push = bo->offset + r->data; + } else + if (r->flags & NOUVEAU_BO_HIGH) { + push = (bo->offset + r->data) >> 32; + } else { + push = r->data; + } + + if (r->flags & NOUVEAU_BO_OR) { + if (bo->flags & NOUVEAU_BO_VRAM) + push |= r->vor; + else + push |= r->tor; + } + + return push; +} + +/* This would be our TTM "superioctl" */ +int +nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; + struct nouveau_pushbuf_bo *pbbo; + struct nouveau_fence *fence = NULL; + int ret; + + if (nvpb->base.remaining == nvpb->size) + return 0; + + nvpb->size -= nvpb->base.remaining; + nvchan->dma->cur += nvpb->size; + nvchan->dma->free -= nvpb->size; + assert(nvchan->dma->cur <= nvchan->dma->max); + + ret = nouveau_fence_new(chan, &fence); + if (ret) + return ret; + + nvchan->dma = &nvchan->dma_bufmgr; + nvchan->pushbuf[nvpb->nop_jump] = 0x20000000 | + (nvchan->dma->base + (nvchan->dma->cur << 2)); + + /* Validate buffers + apply relocations */ + nvchan->user_charge = 0; + while ((pbbo = ptr_to_pbbo(nvpb->buffers))) { + struct nouveau_pushbuf_reloc *r; + struct nouveau_bo *bo = &ptr_to_bo(pbbo->handle)->base; + + ret = nouveau_bo_validate(chan, bo, fence, pbbo->flags); + assert (ret == 0); + + if (bo->offset == nouveau_bo(bo)->offset && + bo->flags == nouveau_bo(bo)->flags) { + while ((r = ptr_to_pbrel(pbbo->relocs))) { + pbbo->relocs = r->next; + free(r); + } + + nvpb->buffers = pbbo->next; + free(pbbo); + continue; + } + bo->offset = nouveau_bo(bo)->offset; + bo->flags = nouveau_bo(bo)->flags; + + while ((r = ptr_to_pbrel(pbbo->relocs))) { + *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); + pbbo->relocs = r->next; + free(r); + } + + nvpb->buffers = pbbo->next; + free(pbbo); + } + nvpb->nr_buffers = 0; + + /* Switch back to user's ring */ + RING_SPACE_CH(chan, 1); + OUT_RING_CH(chan, 0x20000000 | ((nvpb->start << 2) + + nvchan->dma_master.base)); + nvchan->dma = &nvchan->dma_master; + + /* Fence + kickoff */ + nouveau_fence_emit(fence); + FIRE_RING_CH(chan); + nouveau_fence_ref(NULL, &fence); + + /* Allocate space for next push buffer */ + assert(!nouveau_pushbuf_space(chan, min)); + + return 0; +} + +static struct nouveau_pushbuf_bo * +nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) +{ + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); + struct nouveau_pushbuf_bo *pbbo = ptr_to_pbbo(nvpb->buffers); + + while (pbbo) { + if (pbbo->handle == bo->handle) + return pbbo; + pbbo = ptr_to_pbbo(pbbo->next); + } + + pbbo = malloc(sizeof(struct nouveau_pushbuf_bo)); + pbbo->next = nvpb->buffers; + nvpb->buffers = pbbo_to_ptr(pbbo); + nvpb->nr_buffers++; + + pbbo->handle = bo_to_ptr(bo); + pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + pbbo->relocs = 0; + pbbo->nr_relocs = 0; + return pbbo; +} + +int +nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, + struct nouveau_bo *bo, uint32_t data, uint32_t flags, + uint32_t vor, uint32_t tor) +{ + struct nouveau_pushbuf_bo *pbbo; + struct nouveau_pushbuf_reloc *r; + + if (!chan) + return -EINVAL; + + pbbo = nouveau_pushbuf_emit_buffer(chan, bo); + if (!pbbo) + return -EFAULT; + + r = malloc(sizeof(struct nouveau_pushbuf_reloc)); + r->next = pbbo->relocs; + pbbo->relocs = pbrel_to_ptr(r); + pbbo->nr_relocs++; + + pbbo->flags |= (flags & NOUVEAU_BO_RDWR); + pbbo->flags &= (flags | NOUVEAU_BO_RDWR); + + r->handle = bo_to_ptr(r); + r->ptr = ptr; + r->flags = flags; + r->data = data; + r->vor = vor; + r->tor = tor; + + if (flags & NOUVEAU_BO_DUMMY) + *(uint32_t *)ptr = 0; + else + *(uint32_t *)ptr = nouveau_pushbuf_calc_reloc(bo, r); + return 0; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_resource.c b/src/gallium/winsys/dri/nouveau/nouveau_resource.c new file mode 100644 index 0000000000..5d9d578b4f --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_resource.c @@ -0,0 +1,111 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include + +#include "nouveau_drmif.h" +#include "nouveau_local.h" + +int +nouveau_resource_init(struct nouveau_resource **heap, + unsigned start, unsigned size) +{ + struct nouveau_resource *r; + + r = calloc(1, sizeof(struct nouveau_resource)); + if (!r) + return 1; + + r->start = start; + r->size = size; + *heap = r; + return 0; +} + +int +nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, + struct nouveau_resource **res) +{ + struct nouveau_resource *r; + + if (!heap || !size || !res || *res) + return 1; + + while (heap) { + if (!heap->in_use && heap->size >= size) { + r = calloc(1, sizeof(struct nouveau_resource)); + if (!r) + return 1; + + r->start = (heap->start + heap->size) - size; + r->size = size; + r->in_use = 1; + r->priv = priv; + + heap->size -= size; + + r->next = heap->next; + if (heap->next) + heap->next->prev = r; + r->prev = heap; + heap->next = r; + + *res = r; + return 0; + } + + heap = heap->next; + } + + return 1; +} + +void +nouveau_resource_free(struct nouveau_resource **res) +{ + struct nouveau_resource *r; + + if (!res || !*res) + return; + r = *res; + + if (r->prev && !r->prev->in_use) { + r->prev->next = r->next; + if (r->next) + r->next->prev = r->prev; + r->prev->size += r->size; + free(r); + } else + if (r->next && !r->next->in_use) { + r->next->prev = r->prev; + if (r->prev) + r->prev->next = r->next; + r->next->size += r->size; + r->next->start = r->start; + free(r); + } else { + r->in_use = 0; + } + + *res = NULL; +} diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c new file mode 100644 index 0000000000..f06e178483 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -0,0 +1,308 @@ +#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 "nouveau_context.h" +#include "nouveau_device.h" +#include "nouveau_drm.h" +#include "nouveau_dri.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" + +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 +#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_screen_create(__DRIscreenPrivate *driScrnPriv) +{ + struct nouveau_dri *nv_dri = driScrnPriv->pDevPriv; + struct nouveau_screen *nv_screen; + int ret; + + if (driScrnPriv->devPrivSize != sizeof(struct nouveau_dri)) { + NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n"); + return GL_FALSE; + } + + nv_screen = CALLOC_STRUCT(nouveau_screen); + if (!nv_screen) + return GL_FALSE; + nv_screen->driScrnPriv = driScrnPriv; + driScrnPriv->private = (void *)nv_screen; + + driParseOptionInfo(&nv_screen->option_cache, + __driConfigOptions, __driNConfigOptions); + + if ((ret = nouveau_device_open_existing(&nv_screen->device, 0, + driScrnPriv->fd, 0))) { + NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret); + return GL_FALSE; + } + + nv_screen->front_offset = nv_dri->front_offset; + nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8); + nv_screen->front_cpp = nv_dri->bpp / 8; + nv_screen->front_height = nv_dri->height; + + return GL_TRUE; +} + +static void +nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv) +{ + struct nouveau_screen *nv_screen = driScrnPriv->private; + + driScrnPriv->private = NULL; + FREE(nv_screen); +} + +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 struct __DriverAPIRec +nouveau_api = { + .InitDriver = 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, + .GetSwapInfo = NULL, + .GetMSC = NULL, + .WaitForMSC = NULL, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = nouveau_copy_sub_buffer, + .setTexOffset = NULL +}; + +static __GLcontextModes * +nouveau_fill_in_modes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) +{ + __GLcontextModes * modes; + __GLcontextModes * m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + int i; + + static const struct { + GLenum format; + GLenum type; + } fb_format_array[] = { + { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV }, + { GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV }, + }; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + u_int8_t depth_bits_array[4] = { 0, 16, 24, 24 }; + u_int8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; + + depth_buffer_factor = 4; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = ((pixel_bits==16) ? 1 : 2) * + depth_buffer_factor * back_buffer_factor * 4; + modes = (*dri_interface->createContextModes)(num_modes, + sizeof(__GLcontextModes)); + m = modes; + + for (i=((pixel_bits==16)?0:1);i<((pixel_bits==16)?1:3);i++) { + if (!driFillInModes(&m, fb_format_array[i].format, + fb_format_array[i].type, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + GLX_TRUE_COLOR)) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + + if (!driFillInModes(&m, fb_format_array[i].format, + fb_format_array[i].type, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + GLX_DIRECT_COLOR)) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + } + + return modes; +} +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay *dpy, int scrn, + __DRIscreen *psc, const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + void * pSAREA, int fd, int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) +{ + __DRIscreenPrivate *psp; + 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 }; + struct nouveau_dri *nv_dri = NULL; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("nouveau", + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + if (drm_expected.patch != drm_version->patch) { + fprintf(stderr, "Incompatible DRM patch level.\n" + "Expected: %d\n" "Current : %d\n", + drm_expected.patch, drm_version->patch); + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, + &nouveau_api); + if (psp == NULL) + return NULL; + nv_dri = psp->pDevPriv; + + *driver_modes = nouveau_fill_in_modes(nv_dri->bpp, + (nv_dri->bpp == 16) ? 16 : 24, + (nv_dri->bpp == 16) ? 0 : 8, + 1); + + driInitExtensions(NULL, card_extensions, GL_FALSE); + + return (void *)psp; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.h b/src/gallium/winsys/dri/nouveau/nouveau_screen.h new file mode 100644 index 0000000000..019823bd44 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.h @@ -0,0 +1,19 @@ +#ifndef __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_SCREEN_H__ + +#include "xmlconfig.h" +#include "nouveau_device.h" + +struct nouveau_screen { + __DRIscreenPrivate *driScrnPriv; + driOptionCache option_cache; + + struct nouveau_device *device; + + uint32_t front_offset; + uint32_t front_pitch; + uint32_t front_cpp; + uint32_t front_height; +}; + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c new file mode 100644 index 0000000000..91bf243f42 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c @@ -0,0 +1,86 @@ +#include "main/glheader.h" +#include "glapi/glthread.h" +#include + +#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_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" + +void +nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate; + drm_clip_rect_t *pbox; + int nbox, i; + + LOCK_HARDWARE(nv); + if (!dPriv->numClipRects) { + UNLOCK_HARDWARE(nv); + return; + } + pbox = dPriv->pClipRects; + nbox = dPriv->numClipRects; + + nv->surface_copy_prep(nv, nv->frontbuffer, surf); + 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; + + nv->surface_copy(nv, dx, dy, sx, sy, w, h); + } + + FIRE_RING(); + 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; + + surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); + 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; + + surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); + if (surf) { + st_notify_swapbuffers(nvfb->stfb); + nouveau_copy_buffer(dPriv, surf, NULL); + } +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h new file mode 100644 index 0000000000..825d3da6da --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h @@ -0,0 +1,10 @@ +#ifndef __NOUVEAU_SWAPBUFFERS_H__ +#define __NOUVEAU_SWAPBUFFERS_H__ + +extern void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *, + const drm_clip_rect_t *); +extern void nouveau_copy_sub_buffer(__DRIdrawablePrivate *, + int x, int y, int w, int h); +extern void nouveau_swap_buffers(__DRIdrawablePrivate *); + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c new file mode 100644 index 0000000000..2ca05d84c6 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -0,0 +1,124 @@ +#include "pipe/p_util.h" + +#include "nouveau_context.h" +#include "nouveau_winsys_pipe.h" + +#include "nouveau/nouveau_winsys.h" + +static int +nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count, + struct nouveau_notifier **notify) +{ + struct nouveau_context *nv = nvws->nv; + + return nouveau_notifier_alloc(nv->channel, nv->next_handle++, + count, notify); +} + +static int +nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass, + struct nouveau_grobj **grobj) +{ + struct nouveau_context *nv = nvws->nv; + int ret; + + ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, + grclass, grobj); + if (ret) + return ret; + + (*grobj)->subc = nv->next_subchannel++; + assert((*grobj)->subc <= 7); + BEGIN_RING_GR(*grobj, 0x0000, 1); + OUT_RING ((*grobj)->handle); + return 0; +} + +static int +nouveau_pipe_surface_copy(struct nouveau_winsys *nvws, struct pipe_surface *dst, + unsigned dx, unsigned dy, struct pipe_surface *src, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_context *nv = nvws->nv; + + if (nv->surface_copy_prep(nv, dst, src)) + return 1; + nv->surface_copy(nv, dx, dy, sx, sy, w, h); + nv->surface_copy_done(nv); + + return 0; +} + +static int +nouveau_pipe_surface_fill(struct nouveau_winsys *nvws, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + if (nvws->nv->surface_fill(nvws->nv, dst, dx, dy, w, h, value)) + return 1; + return 0; +} + +int +nouveau_pipe_emit_reloc(struct nouveau_channel *chan, void *ptr, + struct pipe_buffer *buf, uint32_t data, + uint32_t flags, uint32_t vor, uint32_t tor) +{ + return nouveau_pushbuf_emit_reloc(chan, ptr, nouveau_buffer(buf)->bo, + data, flags, vor, tor); +} + +struct pipe_context * +nouveau_pipe_create(struct nouveau_context *nv) +{ + struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); + struct pipe_context *(*hw_create)(struct pipe_winsys *, + struct nouveau_winsys *, + unsigned); + + if (!nvws) + return NULL; + + switch (nv->chipset & 0xf0) { + case 0x30: + hw_create = nv30_create; + break; + case 0x40: + case 0x60: + hw_create = nv40_create; + break; + case 0x50: + case 0x80: + hw_create = nv50_create; + break; + default: + NOUVEAU_ERR("Unknown chipset NV%02x\n", (int)nv->chipset); + return NULL; + } + + nvws->nv = nv; + nvws->channel = nv->channel; + + nvws->res_init = nouveau_resource_init; + nvws->res_alloc = nouveau_resource_alloc; + nvws->res_free = nouveau_resource_free; + + nvws->push_reloc = nouveau_pipe_emit_reloc; + nvws->push_flush = nouveau_pushbuf_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->surface_copy = nouveau_pipe_surface_copy; + nvws->surface_fill = nouveau_pipe_surface_fill; + + return hw_create(nouveau_create_pipe_winsys(nv), nvws, nv->chipset); +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c new file mode 100644 index 0000000000..e1a9271395 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -0,0 +1,196 @@ +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "nouveau_context.h" +#include "nouveau_device.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" +#include "nouveau_winsys_pipe.h" + +static void +nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, + void *context_private) +{ + struct nouveau_context *nv = context_private; + __DRIdrawablePrivate *dPriv = nv->dri_drawable; + + nouveau_copy_buffer(dPriv, surf, NULL); +} + +static void +nouveau_printf(struct pipe_winsys *pws, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); +} + +static const char * +nouveau_get_name(struct pipe_winsys *pws) +{ + return "Nouveau/DRI"; +} + +static struct pipe_surface * +nouveau_surface_alloc(struct pipe_winsys *ws) +{ + struct pipe_surface *surf; + + surf = CALLOC_STRUCT(pipe_surface); + if (!surf) + return NULL; + + surf->refcount = 1; + surf->winsys = ws; + return surf; +} + +static int +nouveau_surface_alloc_storage(struct pipe_winsys *ws, struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, unsigned flags) +{ + unsigned pitch = ((width * pf_get_size(format)) + 63) & ~63; + + surf->format = format; + surf->width = width; + surf->height = height; + surf->cpp = pf_get_size(format); + surf->pitch = pitch / surf->cpp; + + surf->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, + pitch * height); + if (!surf->buffer) + return 1; + + return 0; +} + +static void +nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + + *s = NULL; + if (--surf->refcount <= 0) { + if (surf->buffer) + pipe_buffer_reference(ws, &surf->buffer, NULL); + free(surf); + } +} + +static struct pipe_buffer * +nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, + unsigned usage, unsigned size) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_device *dev = nvpws->nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + uint32_t flags = 0; + + nvbuf = calloc(1, sizeof(*nvbuf)); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 1; + nvbuf->base.alignment = alignment; + nvbuf->base.usage = usage; + nvbuf->base.size = size; + + flags = NOUVEAU_BO_LOCAL; + 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 *pws, void *ptr, unsigned bytes) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_device *dev = nvpws->nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + + nvbuf = calloc(1, sizeof(*nvbuf)); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 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_winsys *ws, struct pipe_buffer *buf) +{ + struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + + nouveau_bo_del(&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_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_buffer(buf); + + nouveau_bo_unmap(nvbuf->bo); +} + +struct pipe_winsys * +nouveau_create_pipe_winsys(struct nouveau_context *nv) +{ + struct nouveau_pipe_winsys *nvpws; + struct pipe_winsys *pws; + + nvpws = CALLOC_STRUCT(nouveau_pipe_winsys); + if (!nvpws) + return NULL; + nvpws->nv = nv; + pws = &nvpws->pws; + + pws->flush_frontbuffer = nouveau_flush_frontbuffer; + pws->printf = nouveau_printf; + + pws->surface_alloc = nouveau_surface_alloc; + pws->surface_alloc_storage = nouveau_surface_alloc_storage; + pws->surface_release = nouveau_surface_release; + + pws->buffer_create = nouveau_pipe_bo_create; + pws->buffer_destroy = nouveau_pipe_bo_del; + pws->user_buffer_create = nouveau_pipe_bo_user_create; + pws->buffer_map = nouveau_pipe_bo_map; + pws->buffer_unmap = nouveau_pipe_bo_unmap; + + pws->get_name = nouveau_get_name; + + return &nvpws->pws; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h new file mode 100644 index 0000000000..6a03ac0d77 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h @@ -0,0 +1,34 @@ +#ifndef NOUVEAU_PIPE_WINSYS_H +#define NOUVEAU_PIPE_WINSYS_H + +#include "pipe/p_context.h" +#include "pipe/p_winsys.h" +#include "nouveau_context.h" + +struct nouveau_pipe_buffer { + struct pipe_buffer base; + struct nouveau_bo *bo; +}; + +static inline struct nouveau_pipe_buffer * +nouveau_buffer(struct pipe_buffer *buf) +{ + return (struct nouveau_pipe_buffer *)buf; +} + +struct nouveau_pipe_winsys { + struct pipe_winsys pws; + + struct nouveau_context *nv; +}; + +extern struct pipe_winsys * +nouveau_create_pipe_winsys(struct nouveau_context *nv); + +struct pipe_context * +nouveau_create_softpipe(struct nouveau_context *nv); + +struct pipe_context * +nouveau_pipe_create(struct nouveau_context *nv); + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c new file mode 100644 index 0000000000..0e1b4273d1 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c @@ -0,0 +1,83 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include "imports.h" + +#include "pipe/p_defines.h" +#include "pipe/p_format.h" +#include "softpipe/sp_winsys.h" + +#include "nouveau_context.h" +#include "nouveau_winsys_pipe.h" + +struct nouveau_softpipe_winsys { + struct softpipe_winsys sws; + struct nouveau_context *nv; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean +nouveau_is_format_supported(struct softpipe_winsys *sws, uint format) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + }; + + return FALSE; +} + + + +struct pipe_context * +nouveau_create_softpipe(struct nouveau_context *nv) +{ + struct nouveau_softpipe_winsys *nvsws; + + nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys); + + /* Fill in this struct with callbacks that softpipe will need to + * communicate with the window system, buffer manager, etc. + */ + nvsws->sws.is_format_supported = nouveau_is_format_supported; + nvsws->nv = nv; + + /* Create the softpipe context: + */ + return softpipe_create(nouveau_create_pipe_winsys(nv), &nvsws->sws); +} + diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c new file mode 100644 index 0000000000..fe1ea4ed70 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -0,0 +1,226 @@ +#include "pipe/p_context.h" + +#include "nouveau_context.h" + +static INLINE int +nv04_surface_format(int cpp) +{ + switch (cpp) { + case 1: return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; + case 2: return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; + case 4: return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; + default: + return -1; + } +} + +static INLINE int +nv04_rect_format(int cpp) +{ + switch (cpp) { + case 1: return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + case 2: return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; + case 4: return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + default: + return -1; + } +} + +static void +nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct pipe_surface *dst = nv->surf_dst; + struct pipe_surface *src = nv->surf_src; + unsigned dst_offset, src_offset; + + dst_offset = dst->offset + (dy * dst->pitch + dx) * dst->cpp; + src_offset = src->offset + (sy * src->pitch + sx) * src->cpp; + + while (h) { + int count = (h > 2047) ? 2047 : h; + + BEGIN_RING(NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RELOCl(src->buffer, src_offset, NOUVEAU_BO_VRAM | + NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCl(dst->buffer, dst_offset, NOUVEAU_BO_VRAM | + NOUVEAU_BO_GART | NOUVEAU_BO_WR); + OUT_RING (src->pitch * src->cpp); + OUT_RING (dst->pitch * dst->cpp); + OUT_RING (w * src->cpp); + OUT_RING (count); + OUT_RING (0x0101); + OUT_RING (0); + + h -= count; + src_offset += src->pitch * src->cpp * count; + dst_offset += dst->pitch * dst->cpp * count; + } +} + +static void +nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + BEGIN_RING(NvImageBlit, 0x0300, 3); + OUT_RING ((sy << 16) | sx); + OUT_RING ((dy << 16) | dx); + OUT_RING (( h << 16) | w); +} + +static int +nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, + struct pipe_surface *src) +{ + int format; + + if (src->cpp != dst->cpp) + return 1; + + /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback + * to NV_MEMORY_TO_MEMORY_FORMAT in this case. + */ + if ((src->offset & 63) || (dst->offset & 63)) { + BEGIN_RING(NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); + OUT_RELOCo(src->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | + NOUVEAU_BO_WR); + + nv->surface_copy = nv04_surface_copy_m2mf; + nv->surf_dst = dst; + nv->surf_src = src; + return 0; + + } + + if ((format = nv04_surface_format(dst->cpp)) < 0) { + NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp); + return 1; + } + nv->surface_copy = nv04_surface_copy_blit; + + BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (format); + OUT_RING (((dst->pitch * dst->cpp) << 16) | (src->pitch * src->cpp)); + OUT_RELOCl(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + return 0; +} + +static void +nv04_surface_copy_done(struct nouveau_context *nv) +{ + FIRE_RING(); +} + +static int +nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + int cs2d_format, gdirect_format; + + if ((cs2d_format = nv04_surface_format(dst->cpp)) < 0) { + NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp); + return 1; + } + + if ((gdirect_format = nv04_rect_format(dst->cpp)) < 0) { + NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp); + return 1; + } + + BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (cs2d_format); + OUT_RING (((dst->pitch * dst->cpp) << 16) | (dst->pitch * dst->cpp)); + OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); + OUT_RING (gdirect_format); + BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); + OUT_RING (value); + BEGIN_RING(NvGdiRect, + NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); + OUT_RING ((dx << 16) | dy); + OUT_RING (( w << 16) | h); + + FIRE_RING(); + return 0; +} + +int +nouveau_surface_init_nv04(struct nouveau_context *nv) +{ + unsigned class; + int ret; + + if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, 0x39, + &nv->NvM2MF))) { + NOUVEAU_ERR("Error creating m2mf object: %d\n", ret); + return 1; + } + BIND_RING (NvM2MF, nv->next_subchannel++); + BEGIN_RING(NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + OUT_RING (nv->sync_notifier->handle); + + class = nv->chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : + NV10_CONTEXT_SURFACES_2D; + if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, + &nv->NvCtxSurf2D))) { + NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); + return 1; + } + BIND_RING (NvCtxSurf2D, nv->next_subchannel++); + BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RING (nv->channel->vram->handle); + OUT_RING (nv->channel->vram->handle); + + class = nv->chipset < 0x10 ? NV04_IMAGE_BLIT : + NV12_IMAGE_BLIT; + if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, + &nv->NvImageBlit))) { + NOUVEAU_ERR("Error creating blit object: %d\n", ret); + return 1; + } + BIND_RING (NvImageBlit, nv->next_subchannel++); + BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); + OUT_RING (nv->sync_notifier->handle); + BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); + OUT_RING (nv->NvCtxSurf2D->handle); + BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); + OUT_RING (NV04_IMAGE_BLIT_OPERATION_SRCCOPY); + + class = NV04_GDI_RECTANGLE_TEXT; + if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, + &nv->NvGdiRect))) { + NOUVEAU_ERR("Error creating rect object: %d\n", ret); + return 1; + } + BIND_RING (NvGdiRect, nv->next_subchannel++); + BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); + OUT_RING (nv->sync_notifier->handle); + BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); + OUT_RING (nv->NvCtxSurf2D->handle); + BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + OUT_RING (NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); + BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); + OUT_RING (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + + nv->surface_copy_prep = nv04_surface_copy_prep; + nv->surface_copy = nv04_surface_copy_blit; + nv->surface_copy_done = nv04_surface_copy_done; + nv->surface_fill = nv04_surface_fill; + return 0; +} + diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c new file mode 100644 index 0000000000..15a1002861 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -0,0 +1,160 @@ +#include "pipe/p_context.h" + +#include "nouveau_context.h" + +static INLINE int +nv50_format(int cpp) +{ + switch (cpp) { + case 4: return NV50_2D_DST_FORMAT_32BPP; + case 3: return NV50_2D_DST_FORMAT_24BPP; + case 2: return NV50_2D_DST_FORMAT_16BPP; + case 1: return NV50_2D_DST_FORMAT_8BPP; + default: + return -1; + } +} + +static int +nv50_surface_copy_prep(struct nouveau_context *nv, + struct pipe_surface *dst, struct pipe_surface *src) +{ + int surf_format; + + assert(src->cpp == dst->cpp); + + surf_format = nv50_format(dst->cpp); + assert(surf_format >= 0); + + BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2); + OUT_RING (surf_format); + OUT_RING (1); + BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5); + OUT_RING (dst->pitch * dst->cpp); + OUT_RING (dst->pitch); + OUT_RING (dst->height); + OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4); + OUT_RING (0); + OUT_RING (0); + OUT_RING (dst->pitch); + OUT_RING (dst->height); + + BEGIN_RING(Nv2D, NV50_2D_SRC_FORMAT, 2); + OUT_RING (surf_format); + OUT_RING (1); + BEGIN_RING(Nv2D, NV50_2D_SRC_PITCH, 5); + OUT_RING (src->pitch * src->cpp); + OUT_RING (src->pitch); + OUT_RING (src->height); + OUT_RELOCh(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + + return 0; +} + +static void +nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + BEGIN_RING(Nv2D, 0x0110, 1); + OUT_RING (0); + BEGIN_RING(Nv2D, NV50_2D_BLIT_DST_X, 12); + OUT_RING (dx); + OUT_RING (dy); + OUT_RING (w); + OUT_RING (h); + OUT_RING (0); + OUT_RING (1); + OUT_RING (0); + OUT_RING (1); + OUT_RING (0); + OUT_RING (sx); + OUT_RING (0); + OUT_RING (sy); +} + +static void +nv50_surface_copy_done(struct nouveau_context *nv) +{ + FIRE_RING(); +} + +static int +nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + int surf_format, rect_format; + + surf_format = nv50_format(dst->cpp); + if (surf_format < 0) + return 1; + + rect_format = nv50_format(dst->cpp); + if (rect_format < 0) + return 1; + + BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY1, 1); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2); + OUT_RING (surf_format); + OUT_RING (1); + BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5); + OUT_RING (dst->pitch * dst->cpp); + OUT_RING (dst->pitch); + OUT_RING (dst->height); + OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4); + OUT_RING (0); + OUT_RING (0); + OUT_RING (dst->pitch); + OUT_RING (dst->height); + + BEGIN_RING(Nv2D, 0x0580, 3); + OUT_RING (4); + OUT_RING (rect_format); + OUT_RING (value); + + BEGIN_RING(Nv2D, NV50_2D_RECT_X1, 4); + OUT_RING (dx); + OUT_RING (dy); + OUT_RING (dx + w); + OUT_RING (dy + h); + + FIRE_RING(); + + return 0; +} + +int +nouveau_surface_init_nv50(struct nouveau_context *nv) +{ + int ret; + + ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, NV50_2D, + &nv->Nv2D); + if (ret) + return ret; + BIND_RING (Nv2D, 0); + BEGIN_RING(Nv2D, NV50_2D_DMA_NOTIFY, 1); + OUT_RING (nv->sync_notifier->handle); + BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RING (nv->channel->vram->handle); + OUT_RING (nv->channel->vram->handle); + BEGIN_RING(Nv2D, NV50_2D_OPERATION, 1); + OUT_RING (NV50_2D_OPERATION_SRCCOPY); + + nv->surface_copy_prep = nv50_surface_copy_prep; + nv->surface_copy = nv50_surface_copy; + nv->surface_copy_done = nv50_surface_copy_done; + nv->surface_fill = nv50_surface_fill; + return 0; +} + -- cgit v1.2.3 From c303cf15dcf2744028f920cf71d7e6fda709bd15 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 16 Feb 2008 17:51:44 +1100 Subject: nouveau: fix potential userbuf crash. --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 6887ffa688..ad587bafdf 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -295,7 +295,8 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) &new, &new_map); if (ret) return ret; - } else { + } else + if (!nvbo->user) { new_sysmem = malloc(bo->size); } @@ -311,12 +312,13 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) if (nvbo->fence) nouveau_fence_wait(&nvbo->fence); nouveau_mem_free(bo->device, &nvbo->drm, &nvbo->map); - if (nvbo->sysmem) + if (nvbo->sysmem && !nvbo->user) free(nvbo->sysmem); nvbo->drm = new; nvbo->map = new_map; - nvbo->sysmem = new_sysmem; + if (!nvbo->user) + nvbo->sysmem = new_sysmem; bo->flags = flags; bo->offset = nvbo->drm.offset; return 0; @@ -333,7 +335,6 @@ nouveau_bo_validate_user(struct nouveau_channel *chan, struct nouveau_bo *bo, if (nvchan->user_charge + bo->size > nvdev->sa.size) return 1; - nvchan->user_charge += bo->size; if (!(flags & NOUVEAU_BO_GART)) return 1; @@ -341,6 +342,7 @@ nouveau_bo_validate_user(struct nouveau_channel *chan, struct nouveau_bo *bo, r = nouveau_bo_tmp(chan, bo->size, fence); if (!r) return 1; + nvchan->user_charge += bo->size; memcpy(nvdev->sa_map + r->start, nvbo->sysmem, bo->size); -- cgit v1.2.3 From bfd5916eafb9a97ad10f1d4a8738e7dcb02e04f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 18 Feb 2008 14:25:04 +0900 Subject: Code reorganization: split gallium and mesa makefiles. In other words, don't build src/gallium source code from within src/mesa/Makefile. Also, allow to customize which gallium auxiliary dirs, driver driver, winsys dirs get built from the config/* files. --- src/gallium/winsys/Makefile | 20 ++++++ src/gallium/winsys/dri/Makefile.template | 6 +- src/gallium/winsys/xlib/Makefile | 113 +++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 src/gallium/winsys/Makefile create mode 100644 src/gallium/winsys/xlib/Makefile (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/Makefile b/src/gallium/winsys/Makefile new file mode 100644 index 0000000000..3dc5ea5744 --- /dev/null +++ b/src/gallium/winsys/Makefile @@ -0,0 +1,20 @@ +TOP = ../../.. +include $(TOP)/configs/current + + +SUBDIRS = $(GALLIUM_WINSYS_DIRS) + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index 2a261ed669..65a93bd53e 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -1,7 +1,9 @@ # -*-makefile-*- -MESA_MODULES = $(TOP)/src/mesa/libmesa.a - +MESA_MODULES = \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + COMMON_GALLIUM_SOURCES = \ $(TOP)/src/mesa/drivers/dri/common/utils.c \ $(TOP)/src/mesa/drivers/dri/common/vblank.c \ diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile new file mode 100644 index 0000000000..2664ac47ce --- /dev/null +++ b/src/gallium/winsys/xlib/Makefile @@ -0,0 +1,113 @@ +# src/mesa/Makefile + +TOP = ../../../.. +include $(TOP)/configs/current + + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/auxiliary + +X11_DRIVER_SOURCES = \ + glxapi.c \ + fakeglx.c \ + xfonts.c \ + xm_api.c \ + xm_winsys.c \ + xm_winsys_aub.c \ + brw_aub.c + + +GL_MAJOR = 1 +GL_MINOR = 5 +GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) + + +PIPE_LIB = \ + $(GALLIUM_DRIVERS) \ + $(TOP)/src/mesa/libglapi.a \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + +ifeq ($(CONFIG_NAME), linux-cell) +CELL_LIB = $(TOP)/src/gallium/drivers/cell/ppu/libcell.a +CELL_LIB_SPU = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a +endif + +ifeq ($(CONFIG_NAME), linux-llvm) +LLVM_LIB = $(TOP)/src/gallium/auxiliary/llvm/libgallivm.a +endif + + +.SUFFIXES : .cpp + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + + +default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) + + +###################################################################### +# Stand-alone Mesa libGL and libOSMesa +STAND_ALONE_DRIVER_SOURCES = \ + $(X11_DRIVER_SOURCES) + +STAND_ALONE_DRIVER_OBJECTS = $(STAND_ALONE_DRIVER_SOURCES:.c=.o) + +STAND_ALONE_OBJECTS = \ + $(STAND_ALONE_DRIVER_OBJECTS) + +# Make the GL library +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(LLVM_LIB) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) + $(TOP)/bin/mklib -o $(GL_LIB) \ + -linker "$(CC)" \ + -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ + -install $(TOP)/$(LIB_DIR) \ + $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ + --start-group $(PIPE_LIB) $(LLVM_LIB) --end-group $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) + + +###################################################################### +# Generic stuff + +depend: $(ALL_SOURCES) + @ echo "running $(MKDEP)" + @ rm -f depend # workaround oops on gutsy?!? + @ touch depend + @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \ + > /dev/null 2>/dev/null + + +install: default + $(INSTALL) -d $(INSTALL_DIR)/include/GL + $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL + @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \ + $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \ + fi + +## NOT INSTALLED YET: +## $(INSTALL) -d $(INSTALL_DIR)/include/GLES +## $(INSTALL) -m 644 include/GLES/*.h $(INSTALL_DIR)/include/GLES + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h + +clean: + -rm -f *.o + + +include depend -- cgit v1.2.3 From 33ceb6716a2166db75659fa66d85fb4cfb9633c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 18 Feb 2008 10:52:44 +0000 Subject: Update scons build for new code layout. --- src/gallium/winsys/SConscript | 10 +++++++ src/gallium/winsys/dri/SConscript | 51 +++++++++++++++++++++++++++++++++ src/gallium/winsys/dri/intel/SConscript | 14 ++++----- src/gallium/winsys/xlib/SConscript | 28 ++++++++++++++++++ 4 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 src/gallium/winsys/SConscript create mode 100644 src/gallium/winsys/dri/SConscript create mode 100644 src/gallium/winsys/xlib/SConscript (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript new file mode 100644 index 0000000000..32215d8d58 --- /dev/null +++ b/src/gallium/winsys/SConscript @@ -0,0 +1,10 @@ +Import('*') + +if dri: + SConscript([ + 'dri/SConscript', + ]) +else: + SConscript([ + 'xlib/SConscript', + ]) diff --git a/src/gallium/winsys/dri/SConscript b/src/gallium/winsys/dri/SConscript new file mode 100644 index 0000000000..8c56ce917c --- /dev/null +++ b/src/gallium/winsys/dri/SConscript @@ -0,0 +1,51 @@ +Import('*') + +drienv = env.Clone() + +drienv.Replace(CPPPATH = [ + '#src/mesa/drivers/dri/common', + '#include', + '#include/GL/internal', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/gallium/drivers', + '#src/mesa', + '#src/mesa/main', + '#src/mesa/glapi', + '#src/mesa/math', + '#src/mesa/transform', + '#src/mesa/shader', + '#src/mesa/swrast', + '#src/mesa/swrast_setup', + '#src/egl/main', + '#src/egl/drivers/dri', +]) + +drienv.ParseConfig('pkg-config --cflags --libs libdrm') + +COMMON_GALLIUM_SOURCES = [ + '#src/mesa/drivers/dri/common/utils.c', + '#src/mesa/drivers/dri/common/vblank.c', + '#src/mesa/drivers/dri/common/dri_util.c', + '#src/mesa/drivers/dri/common/xmlconfig.c', +] + +COMMON_BM_SOURCES = [ + '#src/mesa/drivers/dri/common/dri_bufmgr.c', + '#src/mesa/drivers/dri/common/dri_drmpool.c', +] + +Export([ + 'drienv', + 'COMMON_GALLIUM_SOURCES', + 'COMMON_BM_SOURCES', +]) + +# TODO: Installation +#install: $(LIBNAME) +# $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) +# $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + +SConscript([ + 'intel/SConscript', +]) diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript index a7cc10450e..525ba580e8 100644 --- a/src/gallium/winsys/dri/intel/SConscript +++ b/src/gallium/winsys/dri/intel/SConscript @@ -9,11 +9,6 @@ env.Append(CPPPATH = [ #MINIGLX_SOURCES = server/intel_dri.c -pipe_drivers = [ - softpipe, - i915simple -] - DRIVER_SOURCES = [ 'intel_winsys_pipe.c', 'intel_winsys_softpipe.c', @@ -31,11 +26,14 @@ sources = \ COMMON_BM_SOURCES + \ DRIVER_SOURCES -# DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ -# && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") +drivers = [ + softpipe, + i915simple +] +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions env.SharedLibrary( target ='i915tex_dri.so', source = sources, - LIBS = pipe_drivers + env['LIBS'], + LIBS = mesa + drivers + auxiliaries + env['LIBS'], ) \ No newline at end of file diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript new file mode 100644 index 0000000000..f8aa5ef945 --- /dev/null +++ b/src/gallium/winsys/xlib/SConscript @@ -0,0 +1,28 @@ +####################################################################### +# SConscript for xlib winsys + +Import('*') + + +sources = [ + 'glxapi.c', + 'fakeglx.c', + 'xfonts.c', + 'xm_api.c', + 'xm_winsys.c', + 'xm_winsys_aub.c', + 'brw_aub.c', +] + +drivers = [ + softpipe, + i915simple, + i965simple, +] + +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions +env.SharedLibrary( + target ='GL', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], +) -- cgit v1.2.3 From 0448dbd64a2ef217349f4ada4777d432bc82e46d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 18 Feb 2008 12:33:34 +0000 Subject: Update for llvm -> gallivm rename. --- src/gallium/winsys/xlib/Makefile | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 2664ac47ce..17405388ee 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -38,10 +38,6 @@ CELL_LIB = $(TOP)/src/gallium/drivers/cell/ppu/libcell.a CELL_LIB_SPU = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a endif -ifeq ($(CONFIG_NAME), linux-llvm) -LLVM_LIB = $(TOP)/src/gallium/auxiliary/llvm/libgallivm.a -endif - .SUFFIXES : .cpp @@ -69,13 +65,13 @@ STAND_ALONE_OBJECTS = \ $(STAND_ALONE_DRIVER_OBJECTS) # Make the GL library -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(LLVM_LIB) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) $(TOP)/bin/mklib -o $(GL_LIB) \ -linker "$(CC)" \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ - --start-group $(PIPE_LIB) $(LLVM_LIB) --end-group $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) + --start-group $(PIPE_LIB) --end-group $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) ###################################################################### -- cgit v1.2.3 From 90b2beb661f630966788a6e909dc759c99e38973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 13:27:13 +0900 Subject: Simplify makefile boilerplate code. Don't define ASM_SOURCES variable globally -- reserve that variable to be defined locally by makefiles, together with C_SOURCES and CPP_SOURCES. --- src/gallium/winsys/dri/Makefile.template | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index 65a93bd53e..3bc1fdd4d4 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -25,8 +25,9 @@ WINOBJ= WINLIB= INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) -OBJECTS = $(C_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) +OBJECTS = \ + $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) else # miniglx -- cgit v1.2.3 From b9da3791c934e05b82063a8c79c423a0a8e29a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 15:07:53 +0900 Subject: Remove src/mesa and src/mesa/main from gallium source include paths. --- src/gallium/winsys/dri/intel/SConscript | 2 +- src/gallium/winsys/dri/intel/intel_batchpool.c | 15 +++++++++------ src/gallium/winsys/xlib/SConscript | 6 ++++++ src/gallium/winsys/xlib/brw_aub.c | 16 +++++++++------- 4 files changed, 25 insertions(+), 14 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript index 525ba580e8..0ad19d42a8 100644 --- a/src/gallium/winsys/dri/intel/SConscript +++ b/src/gallium/winsys/dri/intel/SConscript @@ -35,5 +35,5 @@ drivers = [ env.SharedLibrary( target ='i915tex_dri.so', source = sources, - LIBS = mesa + drivers + auxiliaries + env['LIBS'], + LIBS = drivers + mesa + auxiliaries + env['LIBS'], ) \ No newline at end of file diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.c b/src/gallium/winsys/dri/intel/intel_batchpool.c index 33b56817f6..ce154c7b88 100644 --- a/src/gallium/winsys/dri/intel/intel_batchpool.c +++ b/src/gallium/winsys/dri/intel/intel_batchpool.c @@ -36,9 +36,12 @@ #include #include +#include #include -#include "imports.h" -#include "glthread.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_thread.h" + #include "dri_bufpool.h" #include "dri_bufmgr.h" #include "intel_batchpool.h" @@ -196,7 +199,7 @@ pool_create(struct _DriBufferPool *pool, _glthread_LOCK_MUTEX(p->mutex); if (p->numFree == 0) - pool_checkFree(p, GL_TRUE); + pool_checkFree(p, TRUE); if (p->numFree == 0) { fprintf(stderr, "Out of fixed size buffer objects\n"); @@ -278,7 +281,7 @@ pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, return -EBUSY; } - buf->mapped = GL_TRUE; + buf->mapped = TRUE; *virtual = (unsigned char *) p->virtual + buf->start; _glthread_UNLOCK_MUTEX(p->mutex); return 0; @@ -361,7 +364,7 @@ pool_validate(struct _DriBufferPool *pool, void *private) BBuf *buf = (BBuf *) private; BPool *p = buf->parent; _glthread_LOCK_MUTEX(p->mutex); - buf->unfenced = GL_TRUE; + buf->unfenced = TRUE; _glthread_UNLOCK_MUTEX(p->mutex); return 0; } @@ -379,7 +382,7 @@ pool_takedown(struct _DriBufferPool *pool) while ((p->numFree < p->numTot) && p->numDelayed) { _glthread_UNLOCK_MUTEX(p->mutex); sched_yield(); - pool_checkFree(p, GL_TRUE); + pool_checkFree(p, TRUE); _glthread_LOCK_MUTEX(p->mutex); } diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index f8aa5ef945..c38b5be52c 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -3,6 +3,12 @@ Import('*') +env = env.Clone() + +env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', +]) sources = [ 'glxapi.c', diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c index 541d50c6e4..10eedd8402 100644 --- a/src/gallium/winsys/xlib/brw_aub.c +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -29,11 +29,13 @@ * Keith Whitwell */ +#include +#include #include "brw_aub.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "imports.h" -//#include "intel_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" struct brw_aubfile { @@ -350,9 +352,9 @@ struct brw_aubfile *brw_aubfile_create( void ) i++; - if (_mesa_getenv("INTEL_AUBFILE")) { - val = snprintf(filename, sizeof(filename), "%s%d.aub", _mesa_getenv("INTEL_AUBFILE"), i%4); - _mesa_printf("--> Aub file: %s\n", filename); + if (getenv("INTEL_AUBFILE")) { + val = snprintf(filename, sizeof(filename), "%s%d.aub", getenv("INTEL_AUBFILE"), i%4); + debug_printf("--> Aub file: %s\n", filename); aubfile->file = fopen(filename, "w"); } else { @@ -360,12 +362,12 @@ struct brw_aubfile *brw_aubfile_create( void ) if (val < 0 || val > sizeof(filename)) strcpy(filename, "default.aub"); - _mesa_printf("--> Aub file: %s\n", filename); + debug_printf("--> Aub file: %s\n", filename); aubfile->file = fopen(filename, "w"); } if (!aubfile->file) { - _mesa_printf("couldn't open aubfile\n"); + debug_printf("couldn't open aubfile\n"); exit(1); } -- cgit v1.2.3 From 3e329ea7e41e8d97de5b5f345ecab0833c8afe70 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 11:14:54 -0700 Subject: gallium: updated cell build Building on Ian's Cell build fix. Put libcell.a in the gallium/drivers/cell/ directory. General Makefile clean-up, simplification, updated comments. --- src/gallium/winsys/xlib/Makefile | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 17405388ee..09f10e5ea8 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -1,4 +1,4 @@ -# src/mesa/Makefile +# src/gallium/winsys/xlib/Makefile TOP = ../../../.. include $(TOP)/configs/current @@ -27,16 +27,17 @@ GL_MINOR = 5 GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) +ifeq ($(CONFIG_NAME), linux-cell) +# The SPU code is in a separate .a file, unfortunately +CELL_SPU_LIB = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a +endif + PIPE_LIB = \ $(GALLIUM_DRIVERS) \ $(TOP)/src/mesa/libglapi.a \ $(TOP)/src/mesa/libmesa.a \ - $(GALLIUM_AUXILIARIES) - -ifeq ($(CONFIG_NAME), linux-cell) -CELL_LIB = $(TOP)/src/gallium/drivers/cell/ppu/libcell.a -CELL_LIB_SPU = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a -endif + $(GALLIUM_AUXILIARIES) \ + $(CELL_SPU_LIB) \ .SUFFIXES : .cpp @@ -65,13 +66,13 @@ STAND_ALONE_OBJECTS = \ $(STAND_ALONE_DRIVER_OBJECTS) # Make the GL library -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(TOP)/bin/mklib -o $(GL_LIB) \ -linker "$(CC)" \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ - --start-group $(PIPE_LIB) --end-group $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) + --start-group $(PIPE_LIB) --end-group $(GL_LIB_DEPS) ###################################################################### -- cgit v1.2.3 From 49c3f3b537cdad847eaa24f90d01c4b1f604f724 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 16:51:19 -0700 Subject: gallium: general clean-up of xlib winsys Makefile --- src/gallium/winsys/xlib/Makefile | 41 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 09f10e5ea8..c443330942 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -4,6 +4,11 @@ TOP = ../../../.. include $(TOP)/configs/current +GL_MAJOR = 1 +GL_MINOR = 5 +GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) + + INCLUDE_DIRS = \ -I$(TOP)/include \ -I$(TOP)/src/mesa \ @@ -12,7 +17,7 @@ INCLUDE_DIRS = \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/gallium/auxiliary -X11_DRIVER_SOURCES = \ +XLIB_WINSYS_SOURCES = \ glxapi.c \ fakeglx.c \ xfonts.c \ @@ -21,10 +26,7 @@ X11_DRIVER_SOURCES = \ xm_winsys_aub.c \ brw_aub.c - -GL_MAJOR = 1 -GL_MINOR = 5 -GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) +XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o) ifeq ($(CONFIG_NAME), linux-cell) @@ -32,7 +34,7 @@ ifeq ($(CONFIG_NAME), linux-cell) CELL_SPU_LIB = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a endif -PIPE_LIB = \ +LIBS = \ $(GALLIUM_DRIVERS) \ $(TOP)/src/mesa/libglapi.a \ $(TOP)/src/mesa/libmesa.a \ @@ -48,35 +50,20 @@ PIPE_LIB = \ .cpp.o: $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@ -.S.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) -###################################################################### -# Stand-alone Mesa libGL and libOSMesa -STAND_ALONE_DRIVER_SOURCES = \ - $(X11_DRIVER_SOURCES) - -STAND_ALONE_DRIVER_OBJECTS = $(STAND_ALONE_DRIVER_SOURCES:.c=.o) - -STAND_ALONE_OBJECTS = \ - $(STAND_ALONE_DRIVER_OBJECTS) - -# Make the GL library -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) +# Make the libGL.so library +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) $(TOP)/bin/mklib -o $(GL_LIB) \ -linker "$(CC)" \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ - $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ - --start-group $(PIPE_LIB) --end-group $(GL_LIB_DEPS) - + $(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \ + --start-group $(LIBS) --end-group $(GL_LIB_DEPS) -###################################################################### -# Generic stuff depend: $(ALL_SOURCES) @ echo "running $(MKDEP)" @@ -94,10 +81,6 @@ install: default $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \ fi -## NOT INSTALLED YET: -## $(INSTALL) -d $(INSTALL_DIR)/include/GLES -## $(INSTALL) -m 644 include/GLES/*.h $(INSTALL_DIR)/include/GLES - # Emacs tags tags: -- cgit v1.2.3 From 26c57d163092d8069c69ff47929e73682b819ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 23 Feb 2008 00:46:40 +0900 Subject: Avoid building problematic module/drivers on windows. --- src/gallium/winsys/SConscript | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index 32215d8d58..3f0596e19c 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -4,7 +4,8 @@ if dri: SConscript([ 'dri/SConscript', ]) -else: + +if env['x11'] and not dri and platform != 'winddk': SConscript([ 'xlib/SConscript', ]) -- cgit v1.2.3 From 24f3d7de29c5cd30ced7c3ce7293902460a82e0b Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 22 Feb 2008 14:07:12 -0700 Subject: i915: include p_debug.h (resolves undefined assert()) --- src/gallium/winsys/dri/intel/intel_batchbuffer.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h index 82feafa21f..caf6870a3c 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -28,6 +28,7 @@ #ifndef INTEL_BATCHBUFFER_H #define INTEL_BATCHBUFFER_H +#include "pipe/p_debug.h" #include "pipe/p_compiler.h" #include "dri_bufmgr.h" -- cgit v1.2.3 From 8cd7c1d03ce045bfa39471c3f77a31030195b899 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 22 Feb 2008 14:07:33 -0700 Subject: i915: include stdio.h --- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 49e04d81ec..5830b88b37 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "intel_batchbuffer.h" #include "intel_context.h" #include "intel_screen.h" -- cgit v1.2.3 From 58a3d7dfd94453c25607106835fbbb3a54d42306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 23 Feb 2008 19:49:08 +0900 Subject: Revamp scons usage. --- src/gallium/winsys/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index 3f0596e19c..635a68eea2 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -5,7 +5,7 @@ if dri: 'dri/SConscript', ]) -if env['x11'] and not dri and platform != 'winddk': +if 'xlib' in env['drivers'] and not dri: SConscript([ 'xlib/SConscript', ]) -- cgit v1.2.3 From ea02342c11eaeb700495b403caecc13a129333e8 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 11:21:03 -0700 Subject: gallium/i915: Use hardware rendering, unless INTEL_SP env var is set --- src/gallium/winsys/dri/intel/intel_context.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index c033f2a592..79b320c6bf 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -188,7 +188,8 @@ intelCreateContext(const __GLcontextModes * visual, /* * Pipe-related setup */ - if (!getenv("INTEL_HW")) { + if (getenv("INTEL_SP")) { + /* use softpipe driver instead of hw */ pipe = intel_create_softpipe( intel, intelScreen->winsys ); } else { -- cgit v1.2.3 From dbf12dcdb78aa251fe0d09b49aa661481727ecf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 26 Feb 2008 18:48:13 +0000 Subject: intel_winsys: Fix build failure due to DEBUG_IOCTL being undefined. Include pipe/p_debug.h to consistently enable or disable the debugging code. --- src/gallium/winsys/dri/intel/intel_context.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h index b01370c049..45430984d8 100644 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -30,6 +30,9 @@ #include "drm.h" + +#include "pipe/p_debug.h" + #include "intel_screen.h" #include "i915_drm.h" -- cgit v1.2.3 From aa59a937ccf41609081d3f9a4973df5478979785 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 20:15:14 -0700 Subject: gallium: introduce 'pipe_screen' for context-independent functions This will allow creating textures before a rendering context exists, for example. Only implemented in i915 driver for now. i915pipe->texture_create() just dispatches through to the i915screen->texture_create() to avoid state tracker changes for now. --- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index 0ed3890e93..2def1afc31 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -40,6 +40,7 @@ #include "pipe/p_util.h" #include "i915simple/i915_winsys.h" +#include "i915simple/i915_screen.h" struct intel_i915_winsys { @@ -135,6 +136,7 @@ intel_create_i915simple( struct intel_context *intel, struct pipe_winsys *winsys ) { struct intel_i915_winsys *iws = CALLOC_STRUCT( intel_i915_winsys ); + struct pipe_screen *screen; /* Fill in this struct with callbacks that i915simple will need to * communicate with the window system, buffer manager, etc. @@ -146,9 +148,11 @@ intel_create_i915simple( struct intel_context *intel, iws->winsys.batch_finish = intel_i915_batch_finish; iws->intel = intel; + screen = i915_create_screen(winsys, intel->intelScreen->deviceID); + /* Create the i915simple context: */ - return i915_create( winsys, - &iws->winsys, - intel->intelScreen->deviceID ); + return i915_create_context( screen, + winsys, + &iws->winsys ); } -- cgit v1.2.3 From 4f36cf5858a7e53181c3578685675e15fbfcbb82 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 09:47:46 -0700 Subject: gallium: implement pipe_screen for softpipe driver --- src/gallium/winsys/dri/intel/intel_winsys_softpipe.c | 3 ++- src/gallium/winsys/xlib/xm_winsys.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c index 9e483bdc9f..0bc2dc4002 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c @@ -68,6 +68,7 @@ intel_create_softpipe( struct intel_context *intel, struct pipe_winsys *winsys ) { struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); + struct pipe_screen *screen = softpipe_create_screen(winsys); /* Fill in this struct with callbacks that softpipe will need to * communicate with the window system, buffer manager, etc. @@ -77,5 +78,5 @@ intel_create_softpipe( struct intel_context *intel, /* Create the softpipe context: */ - return softpipe_create( winsys, &isws->sws ); + return softpipe_create( screen, winsys, &isws->sws ); } diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 8da596d419..adebe4020a 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -457,7 +457,8 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) #endif { struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(pixelformat); - pipe = softpipe_create( pws, spws ); + struct pipe_screen *screen = softpipe_create_screen(pws); + pipe = softpipe_create( screen, pws, spws ); if (pipe) pipe->priv = xmesa; -- cgit v1.2.3 From f04736c8be5d30c510e1799ac0c8fa5173516513 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 09:55:17 -0700 Subject: Cell: implement pipe_screen for cell driver --- src/gallium/winsys/xlib/xm_winsys.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index adebe4020a..018cf01cd6 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -36,6 +36,8 @@ #include "glxheader.h" #include "xmesaP.h" +#undef ASSERT + #include "pipe/p_winsys.h" #include "pipe/p_format.h" #include "pipe/p_context.h" @@ -45,6 +47,7 @@ #ifdef GALLIUM_CELL #include "cell/ppu/cell_context.h" +#include "cell/ppu/cell_screen.h" #include "cell/ppu/cell_winsys.h" #else #define TILE_SIZE 32 /* avoid compilation errors */ @@ -448,7 +451,8 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) #ifdef GALLIUM_CELL if (!getenv("GALLIUM_NOCELL")) { struct cell_winsys *cws = cell_get_winsys(pixelformat); - pipe = cell_create_context(pws, cws); + struct pipe_screen *screen = cell_create_screen(pws); + pipe = cell_create_context(screen, cws); if (pipe) pipe->priv = xmesa; return pipe; -- cgit v1.2.3 From 03b5267f52d440b1b357918ed7de2ca948f314e1 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 10:17:57 -0700 Subject: gallium/i965: implement pipe_screen for i965 driver (untested) --- src/gallium/winsys/xlib/xm_winsys_aub.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index dbfd37bda2..d55d8c39eb 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -40,6 +40,7 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "i965simple/brw_winsys.h" +#include "i965simple/brw_screen.h" #include "brw_aub.h" #include "xm_winsys_aub.h" @@ -565,6 +566,7 @@ struct pipe_context * xmesa_create_i965simple( struct pipe_winsys *winsys ) { struct aub_brw_winsys *iws = CALLOC_STRUCT( aub_brw_winsys ); + struct pipe_screen *screen = brw_create_screen(winsys, 0/* XXX pci_id */); /* Fill in this struct with callbacks that i965simple will need to * communicate with the window system, buffer manager, etc. @@ -583,7 +585,7 @@ xmesa_create_i965simple( struct pipe_winsys *winsys ) /* Create the i965simple context: */ - return brw_create( winsys, + return brw_create( screen, &iws->winsys, 0 ); } -- cgit v1.2.3 From 84cc07dc89c0ebce4ad55b4b3684d4420a202683 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 29 Feb 2008 15:03:57 +1100 Subject: nouveau: implement pipe_screen Untested on NV3x/NV5x. Quite possibly broken. --- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 16 +++++++++--- .../winsys/dri/nouveau/nouveau_winsys_softpipe.c | 30 ++++++++++++---------- 2 files changed, 28 insertions(+), 18 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 2ca05d84c6..1d758e29e7 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -72,23 +72,29 @@ struct pipe_context * nouveau_pipe_create(struct nouveau_context *nv) { struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); - struct pipe_context *(*hw_create)(struct pipe_winsys *, - struct nouveau_winsys *, - unsigned); + struct pipe_screen *(*hws_create)(struct pipe_winsys *, + unsigned chipset); + struct pipe_context *(*hw_create)(struct pipe_screen *, + struct nouveau_winsys *); + struct pipe_winsys *ws; + struct pipe_screen *pscreen; if (!nvws) return NULL; switch (nv->chipset & 0xf0) { case 0x30: + hws_create = nv30_screen_create; hw_create = nv30_create; break; case 0x40: case 0x60: + hws_create = nv40_screen_create; hw_create = nv40_create; break; case 0x50: case 0x80: + hws_create = nv50_screen_create; hw_create = nv50_create; break; default: @@ -119,6 +125,8 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->surface_copy = nouveau_pipe_surface_copy; nvws->surface_fill = nouveau_pipe_surface_fill; - return hw_create(nouveau_create_pipe_winsys(nv), nvws, nv->chipset); + ws = nouveau_create_pipe_winsys(nv); + pscreen = hws_create(ws, nv->chipset); + return hw_create(pscreen, nvws); } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c index 0e1b4273d1..704f6c7750 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c @@ -61,23 +61,25 @@ nouveau_is_format_supported(struct softpipe_winsys *sws, uint format) return FALSE; } - - struct pipe_context * nouveau_create_softpipe(struct nouveau_context *nv) { - struct nouveau_softpipe_winsys *nvsws; - - nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys); - - /* Fill in this struct with callbacks that softpipe will need to - * communicate with the window system, buffer manager, etc. - */ - nvsws->sws.is_format_supported = nouveau_is_format_supported; - nvsws->nv = nv; + struct nouveau_softpipe_winsys *nvsws; + struct pipe_screen *pscreen; + struct pipe_winsys *ws; + + ws = nouveau_create_pipe_winsys(nv); + if (!ws) + return NULL; + pscreen = softpipe_create_screen(ws); + + nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys); + if (!nvsws) + return NULL; + + nvsws->sws.is_format_supported = nouveau_is_format_supported; + nvsws->nv = nv; - /* Create the softpipe context: - */ - return softpipe_create(nouveau_create_pipe_winsys(nv), &nvsws->sws); + return softpipe_create(pscreen, ws, &nvsws->sws); } -- cgit v1.2.3 From baaae562f02563c5966b857c61b3eae7341950e3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 29 Feb 2008 22:54:40 +1100 Subject: nouveau: hand nouveau_winsys in with pipe_screen init --- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 1d758e29e7..529f577181 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -73,9 +73,9 @@ nouveau_pipe_create(struct nouveau_context *nv) { struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); struct pipe_screen *(*hws_create)(struct pipe_winsys *, + struct nouveau_winsys *, unsigned chipset); - struct pipe_context *(*hw_create)(struct pipe_screen *, - struct nouveau_winsys *); + struct pipe_context *(*hw_create)(struct pipe_screen *); struct pipe_winsys *ws; struct pipe_screen *pscreen; @@ -126,7 +126,7 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->surface_fill = nouveau_pipe_surface_fill; ws = nouveau_create_pipe_winsys(nv); - pscreen = hws_create(ws, nv->chipset); - return hw_create(pscreen, nvws); + pscreen = hws_create(ws, nvws, nv->chipset); + return hw_create(pscreen); } -- cgit v1.2.3 From 0a12e4587ccf2c4fa71e93bb00b4582deb99a82c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 14:09:57 +1100 Subject: nouveau: turn pushbuf macros into inline functions --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 93 +++++++--- src/gallium/winsys/dri/nouveau/nouveau_context.h | 35 ++-- src/gallium/winsys/dri/nouveau/nouveau_local.h | 133 ++++++++------ .../winsys/dri/nouveau/nouveau_swapbuffers.c | 2 +- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 13 +- src/gallium/winsys/dri/nouveau/nv04_surface.c | 192 ++++++++++++--------- src/gallium/winsys/dri/nouveau/nv50_surface.c | 187 +++++++++++--------- 7 files changed, 396 insertions(+), 259 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 01fada5b89..7915afae22 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -21,6 +21,75 @@ static const struct dri_debug_control debug_control[] = { int __nouveau_debug = 0; #endif +static void +nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) +{ + nouveau_grobj_free(&nvc->NvNull); + nouveau_grobj_free(&nvc->NvCtxSurf2D); + nouveau_grobj_free(&nvc->NvImageBlit); + nouveau_grobj_free(&nvc->NvGdiRect); + nouveau_grobj_free(&nvc->NvM2MF); + nouveau_grobj_free(&nvc->Nv2D); + + nouveau_notifier_free(&nvc->sync_notifier); + + nouveau_channel_free(&nvc->channel); + + FREE(nvc); +} + +static struct nouveau_channel_context * +nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) +{ + struct nouveau_channel_context *nvc; + int ret; + + nvc = CALLOC_STRUCT(nouveau_channel_context); + if (!nvc) + return NULL; + nvc->chipset = chipset; + + if ((ret = nouveau_channel_alloc(nvdev, 0x8003d001, 0x8003d002, + &nvc->channel))) { + NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + if ((ret = nouveau_grobj_alloc(nvc->channel, 0x00000000, 0x30, + &nvc->NvNull))) { + NOUVEAU_ERR("Error creating NULL object: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + nvc->next_handle = 0x80000000; + + if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, + &nvc->sync_notifier))) { + NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + switch (chipset) { + case 0x50: + case 0x80: + ret = nouveau_surface_channel_create_nv50(nvc); + break; + default: + ret = nouveau_surface_channel_create_nv04(nvc); + break; + } + + if (ret) { + NOUVEAU_ERR("Error initialising surface objects: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + return nvc; +} + GLboolean nouveau_context_create(const __GLcontextModes *glVis, __DRIcontextPrivate *driContextPriv, @@ -45,13 +114,6 @@ nouveau_context_create(const __GLcontextModes *glVis, return GL_FALSE; } - if ((ret = nouveau_channel_alloc(nv_screen->device, - 0x8003d001, 0x8003d002, - &nv->channel))) { - NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); - return GL_FALSE; - } - driContextPriv->driverPrivate = (void *)nv; nv->nv_screen = nv_screen; nv->dri_screen = driScrnPriv; @@ -101,16 +163,9 @@ nouveau_context_create(const __GLcontextModes *glVis, nv->frontbuffer = fb_surf; } - if ((ret = nouveau_grobj_alloc(nv->channel, 0x00000000, 0x30, - &nv->NvNull))) { - NOUVEAU_ERR("Error creating NULL object: %d\n", ret); - return GL_FALSE; - } - nv->next_handle = 0x80000000; - - if ((ret = nouveau_notifier_alloc(nv->channel, nv->next_handle++, 1, - &nv->sync_notifier))) { - NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); + nv->nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset); + if (!nv->nvc) { + NOUVEAU_ERR("Failed initialising GPU channel context\n"); return GL_FALSE; } @@ -152,9 +207,7 @@ nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) st_flush(nv->st, PIPE_FLUSH_WAIT); st_destroy_context(nv->st); - nouveau_grobj_free(&nv->NvCtxSurf2D); - nouveau_grobj_free(&nv->NvImageBlit); - nouveau_channel_free(&nv->channel); + nouveau_channel_context_destroy(nv->nvc); free(nv); } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index 5805f969ba..736c8d8bef 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -13,6 +13,25 @@ struct nouveau_framebuffer { struct st_framebuffer *stfb; }; +struct nouveau_channel_context { + unsigned chipset; + + struct nouveau_channel *channel; + + struct nouveau_notifier *sync_notifier; + + struct nouveau_grobj *NvNull; + struct nouveau_grobj *NvCtxSurf2D; + struct nouveau_grobj *NvImageBlit; + struct nouveau_grobj *NvGdiRect; + struct nouveau_grobj *NvM2MF; + struct nouveau_grobj *Nv2D; + + uint32_t next_handle; + uint32_t next_subchannel; + uint32_t next_sequence; +}; + struct nouveau_context { struct st_context *st; @@ -31,17 +50,7 @@ struct nouveau_context { struct pipe_surface *frontbuffer; /* Hardware context */ - struct nouveau_channel *channel; - struct nouveau_notifier *sync_notifier; - struct nouveau_grobj *NvNull; - struct nouveau_grobj *NvCtxSurf2D; - struct nouveau_grobj *NvImageBlit; - struct nouveau_grobj *NvGdiRect; - struct nouveau_grobj *NvM2MF; - struct nouveau_grobj *Nv2D; - uint32_t next_handle; - uint32_t next_subchannel; - uint32_t next_sequence; + struct nouveau_channel_context *nvc; /* pipe_surface accel */ struct pipe_surface *surf_src, *surf_dst; @@ -80,6 +89,10 @@ extern int __nouveau_debug; extern void LOCK_HARDWARE(struct nouveau_context *); extern void UNLOCK_HARDWARE(struct nouveau_context *); +extern int +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *); +extern int +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *); extern int nouveau_surface_init_nv04(struct nouveau_context *); extern int nouveau_surface_init_nv50(struct nouveau_context *); diff --git a/src/gallium/winsys/dri/nouveau/nouveau_local.h b/src/gallium/winsys/dri/nouveau/nouveau_local.h index 59febca292..f7d91fc748 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_local.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_local.h @@ -1,8 +1,11 @@ #ifndef __NOUVEAU_LOCAL_H__ #define __NOUVEAU_LOCAL_H__ +#include "pipe/p_compiler.h" #include +struct pipe_buffer; + /* Debug output */ #define NOUVEAU_MSG(fmt, args...) do { \ fprintf(stdout, "nouveau: "fmt, ##args); \ @@ -24,66 +27,90 @@ #define NOUVEAU_DMA_TIMEOUT 2000 /* Push buffer access macros */ -#define OUT_RING(data) do { \ - (*nv->channel->pushbuf->cur++) = (data); \ -} while(0) - -#define OUT_RINGp(src,size) do { \ - memcpy(nv->channel->pushbuf->cur, (src), (size)<<2); \ - nv->channel->pushbuf->cur += (size); \ -} while(0) - -#define OUT_RINGf(data) do { \ - union { float v; uint32_t u; } c; \ - c.v = (data); \ - OUT_RING(c.u); \ -} while(0) - -#define FIRE_RING() do { \ - nouveau_pushbuf_flush(nv->channel, 0); \ -} while(0) - -#define BEGIN_RING_GR(obj,mthd,size) do { \ - if (nv->channel->pushbuf->remaining < ((size) + 1)) \ - nouveau_pushbuf_flush(nv->channel, ((size) + 1)); \ - OUT_RING(((obj)->subc << 13) | ((size) << 18) | (mthd)); \ - nv->channel->pushbuf->remaining -= ((size) + 1); \ -} while(0) - -#define BEGIN_RING(obj,mthd,size) do { \ - BEGIN_RING_GR(nv->obj, (mthd), (size)); \ -} while(0) - -#define BIND_RING(o,s) do { \ - nv->o->subc = (s); \ - BEGIN_RING(o, 0x0000, 1); \ - OUT_RING (nv->o->handle); \ -} while(0) - -#define OUT_RELOC(buf,data,flags,vor,tor) do { \ - nouveau_pipe_emit_reloc(nv->channel, nv->channel->pushbuf->cur++, \ - buf, (data), (flags), (vor), (tor)); \ -} while(0) +static INLINE void +OUT_RING(struct nouveau_channel *chan, unsigned data) +{ + *(chan->pushbuf->cur++) = (data); +} + +static INLINE void +OUT_RINGp(struct nouveau_channel *chan, uint32_t *data, unsigned size) +{ + memcpy(chan->pushbuf->cur, data, size * 4); + chan->pushbuf->cur += size; +} + +static INLINE void +OUT_RINGf(struct nouveau_channel *chan, float f) +{ + union { uint32_t i; float f; } c; + c.f = f; + OUT_RING(chan, c.i); +} + +static INLINE void +BEGIN_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, + unsigned mthd, unsigned size) +{ + if (chan->pushbuf->remaining < (size + 1)) + nouveau_pushbuf_flush(chan, (size + 1)); + OUT_RING(chan, (gr->subc << 13) | (size << 18) | mthd); + chan->pushbuf->remaining -= (size + 1); +} + +static INLINE void +FIRE_RING(struct nouveau_channel *chan) +{ + nouveau_pushbuf_flush(chan, 0); +} + +static INLINE void +BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc) +{ + gr->subc = subc; + BEGIN_RING(chan, gr, 0x0000, 1); + OUT_RING (chan, gr->handle); +} + +static INLINE void +OUT_RELOC(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + nouveau_pipe_emit_reloc(chan, chan->pushbuf->cur++, buf, + data, flags, vor, tor); +} /* Raw data + flags depending on FB/TT buffer */ -#define OUT_RELOCd(bo,data,flags,vor,tor) do { \ - OUT_RELOC((bo), (data), (flags) | NOUVEAU_BO_OR, (vor), (tor)); \ -} while(0) +static INLINE void +OUT_RELOCd(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + OUT_RELOC(chan, buf, data, flags | NOUVEAU_BO_OR, vor, tor); +} /* FB/TT object handle */ -#define OUT_RELOCo(bo,flags) do { \ - OUT_RELOC((bo), 0, (flags) | NOUVEAU_BO_OR, \ - nv->channel->vram->handle, nv->channel->gart->handle); \ -} while(0) +static INLINE void +OUT_RELOCo(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned flags) +{ + OUT_RELOC(chan, buf, 0, flags | NOUVEAU_BO_OR, + chan->vram->handle, chan->gart->handle); +} /* Low 32-bits of offset */ -#define OUT_RELOCl(bo,delta,flags) do { \ - OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_LOW, 0, 0); \ -} while(0) +static INLINE void +OUT_RELOCl(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned delta, unsigned flags) +{ + OUT_RELOC(chan, buf, delta, flags | NOUVEAU_BO_LOW, 0, 0); +} /* High 32-bits of offset */ -#define OUT_RELOCh(bo,delta,flags) do { \ - OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_HIGH, 0, 0); \ -} while(0) +static INLINE void +OUT_RELOCh(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned delta, unsigned flags) +{ + OUT_RELOC(chan, buf, delta, flags | NOUVEAU_BO_HIGH, 0, 0); +} #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c index 91bf243f42..70e0104e83 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c @@ -42,7 +42,7 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, nv->surface_copy(nv, dx, dy, sx, sy, w, h); } - FIRE_RING(); + FIRE_RING(nv->nvc->channel); UNLOCK_HARDWARE(nv); if (nv->last_stamp != dPriv->lastStamp) { diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 529f577181..50d7549b1b 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -11,7 +11,7 @@ nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count, { struct nouveau_context *nv = nvws->nv; - return nouveau_notifier_alloc(nv->channel, nv->next_handle++, + return nouveau_notifier_alloc(nv->nvc->channel, nv->nvc->next_handle++, count, notify); } @@ -20,17 +20,16 @@ nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass, struct nouveau_grobj **grobj) { struct nouveau_context *nv = nvws->nv; + struct nouveau_channel *chan = nv->nvc->channel; int ret; - ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, + ret = nouveau_grobj_alloc(chan, nv->nvc->next_handle++, grclass, grobj); if (ret) return ret; - (*grobj)->subc = nv->next_subchannel++; - assert((*grobj)->subc <= 7); - BEGIN_RING_GR(*grobj, 0x0000, 1); - OUT_RING ((*grobj)->handle); + assert(nv->nvc->next_subchannel < 7); + BIND_RING(chan, *grobj, nv->nvc->next_subchannel++); return 0; } @@ -103,7 +102,7 @@ nouveau_pipe_create(struct nouveau_context *nv) } nvws->nv = nv; - nvws->channel = nv->channel; + nvws->channel = nv->nvc->channel; nvws->res_init = nouveau_resource_init; nvws->res_alloc = nouveau_resource_alloc; diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index fe1ea4ed70..cdcd71eaad 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -30,6 +30,7 @@ static void nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h) { + struct nouveau_channel *chan = nv->nvc->channel; struct pipe_surface *dst = nv->surf_dst; struct pipe_surface *src = nv->surf_src; unsigned dst_offset, src_offset; @@ -40,17 +41,18 @@ nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, while (h) { int count = (h > 2047) ? 2047 : h; - BEGIN_RING(NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RELOCl(src->buffer, src_offset, NOUVEAU_BO_VRAM | + BEGIN_RING(chan, nv->nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RELOCl(chan, src->buffer, src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(dst->buffer, dst_offset, NOUVEAU_BO_VRAM | + OUT_RELOCl(chan, dst->buffer, dst_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RING (src->pitch * src->cpp); - OUT_RING (dst->pitch * dst->cpp); - OUT_RING (w * src->cpp); - OUT_RING (count); - OUT_RING (0x0101); - OUT_RING (0); + OUT_RING (chan, src->pitch * src->cpp); + OUT_RING (chan, dst->pitch * dst->cpp); + OUT_RING (chan, w * src->cpp); + OUT_RING (chan, count); + OUT_RING (chan, 0x0101); + OUT_RING (chan, 0); h -= count; src_offset += src->pitch * src->cpp * count; @@ -62,16 +64,19 @@ static void nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h) { - BEGIN_RING(NvImageBlit, 0x0300, 3); - OUT_RING ((sy << 16) | sx); - OUT_RING ((dy << 16) | dx); - OUT_RING (( h << 16) | w); + struct nouveau_channel *chan = nv->nvc->channel; + + BEGIN_RING(chan, nv->nvc->NvImageBlit, 0x0300, 3); + OUT_RING (chan, (sy << 16) | sx); + OUT_RING (chan, (dy << 16) | dx); + OUT_RING (chan, ( h << 16) | w); } static int nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, struct pipe_surface *src) { + struct nouveau_channel *chan = nv->nvc->channel; int format; if (src->cpp != dst->cpp) @@ -81,12 +86,12 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, * to NV_MEMORY_TO_MEMORY_FORMAT in this case. */ if ((src->offset & 63) || (dst->offset & 63)) { - BEGIN_RING(NvM2MF, + BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); - OUT_RELOCo(src->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | - NOUVEAU_BO_RD); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | - NOUVEAU_BO_WR); + OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_GART | + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_GART | + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); nv->surface_copy = nv04_surface_copy_m2mf; nv->surf_dst = dst; @@ -101,15 +106,20 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, } nv->surface_copy = nv04_surface_copy_blit; - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (format); - OUT_RING (((dst->pitch * dst->cpp) << 16) | (src->pitch * src->cpp)); - OUT_RELOCl(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, format); + OUT_RING (chan, ((dst->pitch * dst->cpp) << 16) | + (src->pitch * src->cpp)); + OUT_RELOCl(chan, src->buffer, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); return 0; } @@ -117,7 +127,7 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, static void nv04_surface_copy_done(struct nouveau_context *nv) { - FIRE_RING(); + FIRE_RING(nv->nvc->channel); } static int @@ -125,6 +135,9 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, unsigned dx, unsigned dy, unsigned w, unsigned h, unsigned value) { + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *surf2d = nv->nvc->NvCtxSurf2D; + struct nouveau_grobj *rect = nv->nvc->NvGdiRect; int cs2d_format, gdirect_format; if ((cs2d_format = nv04_surface_format(dst->cpp)) < 0) { @@ -137,86 +150,99 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, return 1; } - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (cs2d_format); - OUT_RING (((dst->pitch * dst->cpp) << 16) | (dst->pitch * dst->cpp)); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); - OUT_RING (gdirect_format); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); - OUT_RING (value); - BEGIN_RING(NvGdiRect, + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, cs2d_format); + OUT_RING (chan, ((dst->pitch * dst->cpp) << 16) | + (dst->pitch * dst->cpp)); + OUT_RELOCl(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); + OUT_RING (chan, gdirect_format); + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); + OUT_RING (chan, value); + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); - OUT_RING ((dx << 16) | dy); - OUT_RING (( w << 16) | h); + OUT_RING (chan, (dx << 16) | dy); + OUT_RING (chan, ( w << 16) | h); - FIRE_RING(); + FIRE_RING(chan); return 0; } int -nouveau_surface_init_nv04(struct nouveau_context *nv) +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) { + struct nouveau_channel *chan = nvc->channel; unsigned class; int ret; - if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, 0x39, - &nv->NvM2MF))) { + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, 0x39, + &nvc->NvM2MF))) { NOUVEAU_ERR("Error creating m2mf object: %d\n", ret); return 1; } - BIND_RING (NvM2MF, nv->next_subchannel++); - BEGIN_RING(NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); - OUT_RING (nv->sync_notifier->handle); - - class = nv->chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : - NV10_CONTEXT_SURFACES_2D; - if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, - &nv->NvCtxSurf2D))) { + BIND_RING (chan, nvc->NvM2MF, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + + class = nvc->chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : + NV10_CONTEXT_SURFACES_2D; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvCtxSurf2D))) { NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); return 1; } - BIND_RING (NvCtxSurf2D, nv->next_subchannel++); - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RING (nv->channel->vram->handle); - OUT_RING (nv->channel->vram->handle); - - class = nv->chipset < 0x10 ? NV04_IMAGE_BLIT : - NV12_IMAGE_BLIT; - if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, - &nv->NvImageBlit))) { + BIND_RING (chan, nvc->NvCtxSurf2D, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RING (chan, nvc->channel->vram->handle); + OUT_RING (chan, nvc->channel->vram->handle); + + class = nvc->chipset < 0x10 ? NV04_IMAGE_BLIT : + NV12_IMAGE_BLIT; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvImageBlit))) { NOUVEAU_ERR("Error creating blit object: %d\n", ret); return 1; } - BIND_RING (NvImageBlit, nv->next_subchannel++); - BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); - OUT_RING (nv->sync_notifier->handle); - BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); - OUT_RING (nv->NvCtxSurf2D->handle); - BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); - OUT_RING (NV04_IMAGE_BLIT_OPERATION_SRCCOPY); + BIND_RING (chan, nvc->NvImageBlit, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); + OUT_RING (chan, nvc->NvCtxSurf2D->handle); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); + OUT_RING (chan, NV04_IMAGE_BLIT_OPERATION_SRCCOPY); class = NV04_GDI_RECTANGLE_TEXT; - if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, - &nv->NvGdiRect))) { + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvGdiRect))) { NOUVEAU_ERR("Error creating rect object: %d\n", ret); return 1; } - BIND_RING (NvGdiRect, nv->next_subchannel++); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); - OUT_RING (nv->sync_notifier->handle); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); - OUT_RING (nv->NvCtxSurf2D->handle); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); - OUT_RING (NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); - OUT_RING (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + BIND_RING (chan, nvc->NvGdiRect, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); + OUT_RING (chan, nvc->NvCtxSurf2D->handle); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); + BEGIN_RING(chan, nvc->NvGdiRect, + NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + return 0; +} + +int +nouveau_surface_init_nv04(struct nouveau_context *nv) +{ nv->surface_copy_prep = nv04_surface_copy_prep; nv->surface_copy = nv04_surface_copy_blit; nv->surface_copy_done = nv04_surface_copy_done; diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c index 15a1002861..5d74fb8d2b 100644 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -19,6 +19,8 @@ static int nv50_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, struct pipe_surface *src) { + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; int surf_format; assert(src->cpp == dst->cpp); @@ -26,34 +28,38 @@ nv50_surface_copy_prep(struct nouveau_context *nv, surf_format = nv50_format(dst->cpp); assert(surf_format >= 0); - BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); - OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2); - OUT_RING (surf_format); - OUT_RING (1); - BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5); - OUT_RING (dst->pitch * dst->cpp); - OUT_RING (dst->pitch); - OUT_RING (dst->height); - OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4); - OUT_RING (0); - OUT_RING (0); - OUT_RING (dst->pitch); - OUT_RING (dst->height); - - BEGIN_RING(Nv2D, NV50_2D_SRC_FORMAT, 2); - OUT_RING (surf_format); - OUT_RING (1); - BEGIN_RING(Nv2D, NV50_2D_SRC_PITCH, 5); - OUT_RING (src->pitch * src->cpp); - OUT_RING (src->pitch); - OUT_RING (src->height); - OUT_RELOCh(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); + OUT_RING (chan, dst->pitch * dst->cpp); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->height); + OUT_RELOCh(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->height); + + BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, NV50_2D_SRC_PITCH, 5); + OUT_RING (chan, src->pitch * src->cpp); + OUT_RING (chan, src->pitch); + OUT_RING (chan, src->height); + OUT_RELOCh(chan, src->buffer, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, src->buffer, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); return 0; } @@ -62,27 +68,30 @@ static void nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h) { - BEGIN_RING(Nv2D, 0x0110, 1); - OUT_RING (0); - BEGIN_RING(Nv2D, NV50_2D_BLIT_DST_X, 12); - OUT_RING (dx); - OUT_RING (dy); - OUT_RING (w); - OUT_RING (h); - OUT_RING (0); - OUT_RING (1); - OUT_RING (0); - OUT_RING (1); - OUT_RING (0); - OUT_RING (sx); - OUT_RING (0); - OUT_RING (sy); + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; + + BEGIN_RING(chan, eng2d, 0x0110, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12); + OUT_RING (chan, dx); + OUT_RING (chan, dy); + OUT_RING (chan, w); + OUT_RING (chan, h); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, sx); + OUT_RING (chan, 0); + OUT_RING (chan, sy); } static void nv50_surface_copy_done(struct nouveau_context *nv) { - FIRE_RING(); + FIRE_RING(nv->nvc->channel); } static int @@ -90,6 +99,8 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, unsigned dx, unsigned dy, unsigned w, unsigned h, unsigned value) { + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; int surf_format, rect_format; surf_format = nv50_format(dst->cpp); @@ -100,57 +111,65 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, if (rect_format < 0) return 1; - BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY1, 1); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2); - OUT_RING (surf_format); - OUT_RING (1); - BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5); - OUT_RING (dst->pitch * dst->cpp); - OUT_RING (dst->pitch); - OUT_RING (dst->height); - OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4); - OUT_RING (0); - OUT_RING (0); - OUT_RING (dst->pitch); - OUT_RING (dst->height); - - BEGIN_RING(Nv2D, 0x0580, 3); - OUT_RING (4); - OUT_RING (rect_format); - OUT_RING (value); - - BEGIN_RING(Nv2D, NV50_2D_RECT_X1, 4); - OUT_RING (dx); - OUT_RING (dy); - OUT_RING (dx + w); - OUT_RING (dy + h); - - FIRE_RING(); + BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY1, 1); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); + OUT_RING (chan, dst->pitch * dst->cpp); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->height); + OUT_RELOCh(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->height); + + BEGIN_RING(chan, eng2d, 0x0580, 3); + OUT_RING (chan, 4); + OUT_RING (chan, rect_format); + OUT_RING (chan, value); + + BEGIN_RING(chan, eng2d, NV50_2D_RECT_X1, 4); + OUT_RING (chan, dx); + OUT_RING (chan, dy); + OUT_RING (chan, dx + w); + OUT_RING (chan, dy + h); + + FIRE_RING(chan); return 0; } int -nouveau_surface_init_nv50(struct nouveau_context *nv) +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) { int ret; - ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, NV50_2D, - &nv->Nv2D); + ret = nouveau_grobj_alloc(nvc->channel, nvc->next_handle++, NV50_2D, + &nvc->Nv2D); if (ret) return ret; - BIND_RING (Nv2D, 0); - BEGIN_RING(Nv2D, NV50_2D_DMA_NOTIFY, 1); - OUT_RING (nv->sync_notifier->handle); - BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); - OUT_RING (nv->channel->vram->handle); - OUT_RING (nv->channel->vram->handle); - BEGIN_RING(Nv2D, NV50_2D_OPERATION, 1); - OUT_RING (NV50_2D_OPERATION_SRCCOPY); + BIND_RING (nvc->channel, nvc->Nv2D, 0); + BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_NOTIFY, 1); + OUT_RING (nvc->channel, nvc->sync_notifier->handle); + BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RING (nvc->channel, nvc->channel->vram->handle); + OUT_RING (nvc->channel, nvc->channel->vram->handle); + BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_OPERATION, 1); + OUT_RING (nvc->channel, NV50_2D_OPERATION_SRCCOPY); + + return 0; +} +int +nouveau_surface_init_nv50(struct nouveau_context *nv) +{ nv->surface_copy_prep = nv50_surface_copy_prep; nv->surface_copy = nv50_surface_copy; nv->surface_copy_done = nv50_surface_copy_done; -- cgit v1.2.3 From b560ed2444383b9634786fe742b8cb6f5cdfc781 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 14:56:42 +1100 Subject: nouveau: enable multi-context/single-channel support for nv40 --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 63 +++++++++++++++++++++--- src/gallium/winsys/dri/nouveau/nouveau_context.h | 8 +++ src/gallium/winsys/dri/nouveau/nouveau_screen.h | 2 + src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 10 ++-- 4 files changed, 74 insertions(+), 9 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 7915afae22..dc852c9f49 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -4,6 +4,7 @@ #include "utils.h" #include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" #include "pipe/p_defines.h" #include "pipe/p_context.h" @@ -101,7 +102,8 @@ nouveau_context_create(const __GLcontextModes *glVis, struct nouveau_device_priv *nvdev; struct pipe_context *pipe = NULL; struct st_context *st_share = NULL; - int ret; + struct nouveau_channel_context *nvc = NULL; + int i, ret; if (sharedContextPrivate) { st_share = ((struct nouveau_context *)sharedContextPrivate)->st; @@ -163,12 +165,56 @@ nouveau_context_create(const __GLcontextModes *glVis, nv->frontbuffer = fb_surf; } - nv->nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset); - if (!nv->nvc) { - NOUVEAU_ERR("Failed initialising GPU channel context\n"); - return GL_FALSE; + /* Attempt to share a single channel between multiple contexts from + * a single process. + */ + nvc = nv_screen->nvc; + if (!nvc && st_share) { + struct nouveau_context *snv = st_share->pipe->priv; + if (snv) { + nvc = snv->nvc; + } + } + + /*XXX: temporary - disable multi-context/single-channel on non-NV4x */ + switch (nv->chipset & 0xf0) { + case 0x40: + case 0x60: + break; + default: + nvc = NULL; + break; + } + + if (!nvc) { + nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset); + if (!nvc) { + NOUVEAU_ERR("Failed initialising GPU context\n"); + return GL_FALSE; + } + nv_screen->nvc = nvc; + } + + nvc->refcount++; + nv->nvc = nvc; + + /* Find a free slot for a pipe context, allocate a new one if needed */ + nv->pctx_id = -1; + for (i = 0; i < nvc->nr_pctx; i++) { + if (nvc->pctx[i] == NULL) { + nv->pctx_id = i; + break; + } } + if (nv->pctx_id < 0) { + nv->pctx_id = nvc->nr_pctx++; + nvc->pctx = + realloc(nvc->pctx, + sizeof(struct pipe_context *) * nvc->nr_pctx); + } + + /* Create pipe */ if (nv->chipset < 0x50) ret = nouveau_surface_init_nv04(nv); else @@ -201,13 +247,18 @@ void nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) { struct nouveau_context *nv = driContextPriv->driverPrivate; + struct nouveau_channel_context *nvc = nv->nvc; assert(nv); st_flush(nv->st, PIPE_FLUSH_WAIT); st_destroy_context(nv->st); - nouveau_channel_context_destroy(nv->nvc); + if (nv->pctx_id >= 0) { + nvc->pctx[nv->pctx_id] = NULL; + if (--nvc->refcount <= 0) + nouveau_channel_context_destroy(nvc); + } free(nv); } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index 736c8d8bef..92f551855a 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -14,6 +14,13 @@ struct nouveau_framebuffer { }; struct nouveau_channel_context { + struct pipe_screen *pscreen; + int refcount; + + unsigned cur_pctx; + unsigned nr_pctx; + struct pipe_context **pctx; + unsigned chipset; struct nouveau_channel *channel; @@ -51,6 +58,7 @@ struct nouveau_context { /* Hardware context */ struct nouveau_channel_context *nvc; + int pctx_id; /* pipe_surface accel */ struct pipe_surface *surf_src, *surf_dst; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.h b/src/gallium/winsys/dri/nouveau/nouveau_screen.h index 019823bd44..e9da202690 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.h @@ -14,6 +14,8 @@ struct nouveau_screen { uint32_t front_pitch; uint32_t front_cpp; uint32_t front_height; + + void *nvc; }; #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 50d7549b1b..87619bdcfb 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -70,11 +70,12 @@ nouveau_pipe_emit_reloc(struct nouveau_channel *chan, void *ptr, struct pipe_context * nouveau_pipe_create(struct nouveau_context *nv) { + struct nouveau_channel_context *nvc = nv->nvc; struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); struct pipe_screen *(*hws_create)(struct pipe_winsys *, struct nouveau_winsys *, unsigned chipset); - struct pipe_context *(*hw_create)(struct pipe_screen *); + struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); struct pipe_winsys *ws; struct pipe_screen *pscreen; @@ -125,7 +126,10 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->surface_fill = nouveau_pipe_surface_fill; ws = nouveau_create_pipe_winsys(nv); - pscreen = hws_create(ws, nvws, nv->chipset); - return hw_create(pscreen); + + if (!nvc->pscreen) + nvc->pscreen = hws_create(ws, nvws, nv->chipset); + nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id); + return nvc->pctx[nv->pctx_id]; } -- cgit v1.2.3 From 578b5cd9a030189bcba5c3e86080e1e26eb6e108 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 16:35:47 +1100 Subject: nouveau: fix potential crash --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index dc852c9f49..2e54729aa9 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -256,8 +256,10 @@ nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) if (nv->pctx_id >= 0) { nvc->pctx[nv->pctx_id] = NULL; - if (--nvc->refcount <= 0) + if (--nvc->refcount <= 0) { nouveau_channel_context_destroy(nvc); + nv->nv_screen->nvc = NULL; + } } free(nv); -- cgit v1.2.3 From a5966c8b28702bba1e4eb4bb4aec2247c90fcfa2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 16:39:24 +1100 Subject: nouveau: silence some warnings --- src/gallium/winsys/dri/nouveau/nouveau_local.h | 6 ++++-- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_local.h b/src/gallium/winsys/dri/nouveau/nouveau_local.h index f7d91fc748..8a52f26714 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_local.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_local.h @@ -2,6 +2,7 @@ #define __NOUVEAU_LOCAL_H__ #include "pipe/p_compiler.h" +#include "nouveau_winsys_pipe.h" #include struct pipe_buffer; @@ -76,8 +77,9 @@ static INLINE void OUT_RELOC(struct nouveau_channel *chan, struct pipe_buffer *buf, unsigned data, unsigned flags, unsigned vor, unsigned tor) { - nouveau_pipe_emit_reloc(chan, chan->pushbuf->cur++, buf, - data, flags, vor, tor); + nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, + nouveau_buffer(buf)->bo, + data, flags, vor, tor); } /* Raw data + flags depending on FB/TT buffer */ diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 87619bdcfb..dc7c4c3d71 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -58,7 +58,7 @@ nouveau_pipe_surface_fill(struct nouveau_winsys *nvws, struct pipe_surface *dst, return 0; } -int +static int nouveau_pipe_emit_reloc(struct nouveau_channel *chan, void *ptr, struct pipe_buffer *buf, uint32_t data, uint32_t flags, uint32_t vor, uint32_t tor) @@ -77,7 +77,6 @@ nouveau_pipe_create(struct nouveau_context *nv) unsigned chipset); struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); struct pipe_winsys *ws; - struct pipe_screen *pscreen; if (!nvws) return NULL; -- cgit v1.2.3 From 5b9b5c850f3b34d8891890d808a520a64dd779bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 4 Mar 2008 18:32:16 +0100 Subject: gallium: Fix scons condition for building the xlib winsys. --- src/gallium/winsys/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index 635a68eea2..f18d3bd2f8 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -5,7 +5,7 @@ if dri: 'dri/SConscript', ]) -if 'xlib' in env['drivers'] and not dri: +if 'xlib' in env['winsys'] and not dri: SConscript([ 'xlib/SConscript', ]) -- cgit v1.2.3 From 66ba021e9fa2fa932cb9be8fc2fb8272baf51fc6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 7 Mar 2008 22:48:26 +1100 Subject: nouveau: another "argh gallium fscks with assert" fix --- src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c index 7d5eddb92f..fd9a5c5a96 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -193,7 +193,8 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) nouveau_fence_ref(NULL, &fence); /* Allocate space for next push buffer */ - assert(!nouveau_pushbuf_space(chan, min)); + ret = nouveau_pushbuf_space(chan, min); + assert(!ret); return 0; } -- cgit v1.2.3 From 1fb3c94f03e07a80bb7a93777d4fef5173da71ca Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 12 Mar 2008 02:20:40 +1100 Subject: nv50: some forgotten changes --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 2e54729aa9..8dac08a5d2 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -72,7 +72,7 @@ nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) return NULL; } - switch (chipset) { + switch (chipset & 0xf0) { case 0x50: case 0x80: ret = nouveau_surface_channel_create_nv50(nvc); -- cgit v1.2.3 From 9911ca2226cf87e2cc4ffc32e40bccaf0a4e5745 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 12 Mar 2008 03:21:48 +1100 Subject: nv50: ouch, next_subchannel++ :) --- src/gallium/winsys/dri/nouveau/nv50_surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c index 5d74fb8d2b..5c6733e44a 100644 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -155,7 +155,7 @@ nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) &nvc->Nv2D); if (ret) return ret; - BIND_RING (nvc->channel, nvc->Nv2D, 0); + BIND_RING (nvc->channel, nvc->Nv2D, nvc->next_subchannel++); BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_NOTIFY, 1); OUT_RING (nvc->channel, nvc->sync_notifier->handle); BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); -- cgit v1.2.3 From 1cec61e441ad5b4b1ac8d1abcaa7535bc1827eb3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 13 Mar 2008 18:08:22 +1100 Subject: nouveau: NV9X is basically a G80, fix issue with NV6X being detected as G80. --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 42 ++++++++++++++++++++---- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 1 + 2 files changed, 36 insertions(+), 7 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 8dac08a5d2..8b20b3689c 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -75,6 +75,7 @@ nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) switch (chipset & 0xf0) { case 0x50: case 0x80: + case 0x90: ret = nouveau_surface_channel_create_nv50(nvc); break; default: @@ -109,6 +110,7 @@ nouveau_context_create(const __GLcontextModes *glVis, st_share = ((struct nouveau_context *)sharedContextPrivate)->st; } + /* Check for supported arch */ if ((ret = nouveau_device_get_param(nv_screen->device, NOUVEAU_GETPARAM_CHIPSET_ID, &nv->chipset))) { @@ -116,6 +118,22 @@ nouveau_context_create(const __GLcontextModes *glVis, return GL_FALSE; } + switch (nv->chipset & 0xf0) { + case 0x30: + /* NV30 */ + case 0x40: + case 0x60: + /* NV40 */ + case 0x50: + case 0x80: + case 0x90: + /* G80 */ + break; + default: + NOUVEAU_ERR("Unsupported chipset: NV%02x\n", nv->chipset); + return GL_FALSE; + } + driContextPriv->driverPrivate = (void *)nv; nv->nv_screen = nv_screen; nv->dri_screen = driScrnPriv; @@ -176,10 +194,15 @@ nouveau_context_create(const __GLcontextModes *glVis, } } - /*XXX: temporary - disable multi-context/single-channel on non-NV4x */ + /*XXX: temporary - disable multi-context/single-channel on pre-NV4x */ switch (nv->chipset & 0xf0) { case 0x40: case 0x60: + /* NV40 class */ + case 0x50: + case 0x80: + case 0x90: + /* G80 class */ break; default: nvc = NULL; @@ -215,12 +238,17 @@ nouveau_context_create(const __GLcontextModes *glVis, } /* Create pipe */ - if (nv->chipset < 0x50) - ret = nouveau_surface_init_nv04(nv); - else - ret = nouveau_surface_init_nv50(nv); - if (ret) { - return GL_FALSE; + switch (nv->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + if (nouveau_surface_init_nv50(nv)) + return GL_FALSE; + break; + default: + if (nouveau_surface_init_nv04(nv)) + return GL_FALSE; + break; } if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index dc7c4c3d71..64e84fb68e 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -93,6 +93,7 @@ nouveau_pipe_create(struct nouveau_context *nv) break; case 0x50: case 0x80: + case 0x90: hws_create = nv50_screen_create; hw_create = nv50_create; break; -- cgit v1.2.3 From a254d0c36870724e51e91de3a3da9220b67af850 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 14 Mar 2008 10:22:53 -0600 Subject: gallium: added dummy install target --- src/gallium/winsys/Makefile | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/Makefile b/src/gallium/winsys/Makefile index 3dc5ea5744..2360a6a94a 100644 --- a/src/gallium/winsys/Makefile +++ b/src/gallium/winsys/Makefile @@ -18,3 +18,7 @@ subdirs: clean: rm -f `find . -name \*.[oa]` + + +# Dummy install target +install: -- cgit v1.2.3 From d493203045b214770473f8afeaa610542fe42c2a Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 15 Mar 2008 05:37:57 +0100 Subject: nv10. --- src/gallium/winsys/dri/nouveau/Makefile | 1 + src/gallium/winsys/dri/nouveau/nouveau_context.c | 3 +++ src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 5 +++++ 3 files changed, 9 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/Makefile b/src/gallium/winsys/dri/nouveau/Makefile index b463f218fd..f637b2cebf 100644 --- a/src/gallium/winsys/dri/nouveau/Makefile +++ b/src/gallium/winsys/dri/nouveau/Makefile @@ -8,6 +8,7 @@ MINIGLX_SOURCES = PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/nv10/libnv10.a \ $(TOP)/src/gallium/drivers/nv30/libnv30.a \ $(TOP)/src/gallium/drivers/nv40/libnv40.a \ $(TOP)/src/gallium/drivers/nv50/libnv50.a diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 8b20b3689c..336dd65847 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -119,6 +119,9 @@ nouveau_context_create(const __GLcontextModes *glVis, } switch (nv->chipset & 0xf0) { + case 0x10: + case 0x20: + /* NV10 */ case 0x30: /* NV30 */ case 0x40: diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 64e84fb68e..6c85aab9f5 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -82,6 +82,11 @@ nouveau_pipe_create(struct nouveau_context *nv) return NULL; switch (nv->chipset & 0xf0) { + case 0x10: + case 0x20: + hws_create = nv10_screen_create; + hw_create = nv10_create; + break; case 0x30: hws_create = nv30_screen_create; hw_create = nv30_create; -- cgit v1.2.3 From f93386de0fb281e79633c3bf57060f660abdfade Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 17 Mar 2008 14:22:36 +1100 Subject: nouveau: create fence object when allocating pushbuf, instead of submit --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 3 ++- src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 4 +++- src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 14 ++++++-------- 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index ad587bafdf..40d4667c47 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -376,9 +376,10 @@ nouveau_bo_validate_bo(struct nouveau_channel *chan, struct nouveau_bo *bo, int nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo, - struct nouveau_fence *fence, uint32_t flags) + uint32_t flags) { struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_fence *fence = nouveau_pushbuf(chan->pushbuf)->fence; int ret; assert(bo->map == NULL); diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h index 37e404fc6c..1c9b5799f9 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -127,6 +127,8 @@ struct nouveau_pushbuf_bo { struct nouveau_pushbuf_priv { struct nouveau_pushbuf base; + struct nouveau_fence *fence; + unsigned nop_jump; unsigned start; unsigned size; @@ -288,7 +290,7 @@ nouveau_bo_unmap(struct nouveau_bo *); extern int nouveau_bo_validate(struct nouveau_channel *, struct nouveau_bo *, - struct nouveau_fence *fence, uint32_t flags); + uint32_t flags); extern int nouveau_resource_init(struct nouveau_resource **heap, unsigned start, diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c index fd9a5c5a96..a2b9321b15 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -56,6 +56,10 @@ nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) nvpb->base.remaining = nvpb->size; nvpb->base.cur = &nvchan->pushbuf[nvpb->start]; + /* Create a new fence object for this "frame" */ + nouveau_fence_ref(NULL, &nvpb->fence); + nouveau_fence_new(chan, &nvpb->fence); + return 0; } @@ -128,7 +132,6 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) struct nouveau_channel_priv *nvchan = nouveau_channel(chan); struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; struct nouveau_pushbuf_bo *pbbo; - struct nouveau_fence *fence = NULL; int ret; if (nvpb->base.remaining == nvpb->size) @@ -139,10 +142,6 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) nvchan->dma->free -= nvpb->size; assert(nvchan->dma->cur <= nvchan->dma->max); - ret = nouveau_fence_new(chan, &fence); - if (ret) - return ret; - nvchan->dma = &nvchan->dma_bufmgr; nvchan->pushbuf[nvpb->nop_jump] = 0x20000000 | (nvchan->dma->base + (nvchan->dma->cur << 2)); @@ -153,7 +152,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) struct nouveau_pushbuf_reloc *r; struct nouveau_bo *bo = &ptr_to_bo(pbbo->handle)->base; - ret = nouveau_bo_validate(chan, bo, fence, pbbo->flags); + ret = nouveau_bo_validate(chan, bo, pbbo->flags); assert (ret == 0); if (bo->offset == nouveau_bo(bo)->offset && @@ -188,9 +187,8 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) nvchan->dma = &nvchan->dma_master; /* Fence + kickoff */ - nouveau_fence_emit(fence); + nouveau_fence_emit(nvpb->fence); FIRE_RING_CH(chan); - nouveau_fence_ref(NULL, &fence); /* Allocate space for next push buffer */ ret = nouveau_pushbuf_space(chan, min); -- cgit v1.2.3 From 9575e35807c89c0b8a745671bc2dcd54d96379ff Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 19 Mar 2008 00:06:15 +1100 Subject: nouveau: pass nvws to nvws->push_* functions, rather than nouveau_channel* --- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 6c85aab9f5..bf1afce5d9 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -59,14 +59,21 @@ nouveau_pipe_surface_fill(struct nouveau_winsys *nvws, struct pipe_surface *dst, } static int -nouveau_pipe_emit_reloc(struct nouveau_channel *chan, void *ptr, +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) { - return nouveau_pushbuf_emit_reloc(chan, ptr, nouveau_buffer(buf)->bo, + return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, + nouveau_buffer(buf)->bo, data, flags, vor, tor); } +static int +nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size) +{ + return nouveau_pushbuf_flush(nvws->channel, size); +} + struct pipe_context * nouveau_pipe_create(struct nouveau_context *nv) { @@ -114,8 +121,8 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->res_alloc = nouveau_resource_alloc; nvws->res_free = nouveau_resource_free; - nvws->push_reloc = nouveau_pipe_emit_reloc; - nvws->push_flush = nouveau_pushbuf_flush; + 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; -- cgit v1.2.3 From 5d2577e576635559da202d0d062601e404843b2c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 17:38:24 +1100 Subject: nouveau: try combining prev and next resources on free Fixes some cases where we end up with a list of many unused chunks that are too small to be useful. --- src/gallium/winsys/dri/nouveau/nouveau_resource.c | 29 +++++++++++++---------- 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_resource.c b/src/gallium/winsys/dri/nouveau/nouveau_resource.c index 5d9d578b4f..3bbcb5c45e 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_resource.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_resource.c @@ -88,6 +88,22 @@ nouveau_resource_free(struct nouveau_resource **res) if (!res || !*res) return; r = *res; + *res = NULL; + + r->in_use = 0; + + if (r->next && !r->next->in_use) { + struct nouveau_resource *new = r->next; + + new->prev = r->prev; + if (r->prev) + r->prev->next = new; + new->size += r->size; + new->start = r->start; + + free(r); + r = new; + } if (r->prev && !r->prev->in_use) { r->prev->next = r->next; @@ -95,17 +111,6 @@ nouveau_resource_free(struct nouveau_resource **res) r->next->prev = r->prev; r->prev->size += r->size; free(r); - } else - if (r->next && !r->next->in_use) { - r->next->prev = r->prev; - if (r->prev) - r->prev->next = r->next; - r->next->size += r->size; - r->next->start = r->start; - free(r); - } else { - r->in_use = 0; } - - *res = NULL; + } -- cgit v1.2.3 From 735ecf5de8587f8e52fe6ffc7f3f17403d140e23 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 17:40:01 +1100 Subject: nouveau: potentially delay buffer destruction Rather than spinning waiting for the GPU to finish with the buffer, add a callback on the buffer's fence object instead. Gives a sizable performance increase in OA. --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 40d4667c47..5dbb7d0374 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -206,6 +206,18 @@ nouveau_bo_ref(struct nouveau_device *dev, uint64_t handle, return 0; } +static void +nouveau_bo_del_cb(void *priv) +{ + struct nouveau_bo_priv *nvbo = priv; + + nouveau_fence_ref(NULL, &nvbo->fence); + nouveau_mem_free(nvbo->base.device, &nvbo->drm, &nvbo->map); + if (nvbo->sysmem && !nvbo->user) + free(nvbo->sysmem); + free(nvbo); +} + void nouveau_bo_del(struct nouveau_bo **bo) { @@ -220,11 +232,9 @@ nouveau_bo_del(struct nouveau_bo **bo) return; if (nvbo->fence) - nouveau_fence_wait(&nvbo->fence); - nouveau_mem_free(nvbo->base.device, &nvbo->drm, &nvbo->map); - if (nvbo->sysmem && !nvbo->user) - free(nvbo->sysmem); - free(nvbo); + nouveau_fence_signal_cb(nvbo->fence, nouveau_bo_del_cb, nvbo); + else + nouveau_bo_del_cb(nvbo); } int -- cgit v1.2.3 From 83e94189c424303fee4218a9d9380fc73b7ba318 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 18:15:58 +1100 Subject: nouveau: use saved fence pointer, not head of unsignalled list It's possible for the unsignalled list head to change during fence_flush. Fixes valgrind complaint exposed by a previous commit. --- src/gallium/winsys/dri/nouveau/nouveau_fence.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_fence.c b/src/gallium/winsys/dri/nouveau/nouveau_fence.c index 7714e6f248..e7b0b4ff07 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_fence.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_fence.c @@ -172,14 +172,13 @@ nouveau_fence_flush(struct nouveau_channel *chan) nvfence = nouveau_fence(nvchan->fence_head); if (nvfence->sequence > sequence) break; - nouveau_fence_del_unsignalled(&nvfence->base); nvfence->signalled = 1; if (nvfence->signal_cb) { struct nouveau_fence *fence = NULL; - nouveau_fence_ref(nvchan->fence_head, &fence); + nouveau_fence_ref(&nvfence->base, &fence); while (nvfence->signal_cb) { struct nouveau_fence_cb *cb; -- cgit v1.2.3 From 1a4dcde808dbd5daa58f939361d9a9b539f81b50 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 18:28:07 +1100 Subject: nouveau: do a retry if initial buffer alloc fails --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 5dbb7d0374..46c0759dbb 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -369,8 +369,13 @@ nouveau_bo_validate_bo(struct nouveau_channel *chan, struct nouveau_bo *bo, int ret; ret = nouveau_bo_set_status(bo, flags); - if (ret) - return ret; + if (ret) { + nouveau_fence_flush(chan); + + ret = nouveau_bo_set_status(bo, flags); + if (ret) + return ret; + } if (nvbo->user) nouveau_bo_upload(nvbo); -- cgit v1.2.3 From 46a7f297a1477b9b59a5a11bf090db0ecbdf1ed7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 24 Mar 2008 13:01:35 +1100 Subject: nouveau: fix infinite wait on space for userbuf. A recent commit removed a bug which essentially caused a sync after each use of a user buffer. In fixing it, the scratch area can now become fragmented under some circumstances leading to nouveau_bo_tmp() waiting forever for a large enough block of free space. This fixes ppracer, gl-117 and probably a heap of other apps. --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 46c0759dbb..792eaaa79e 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -88,6 +88,26 @@ nouveau_bo_tmp_del(void *priv) nouveau_resource_free(&r); } +static unsigned +nouveau_bo_tmp_max(struct nouveau_device_priv *nvdev) +{ + struct nouveau_resource *r = nvdev->sa_heap; + unsigned max = 0; + + while (r) { + if (r->in_use && !nouveau_fence(r->priv)->emitted) { + r = r->next; + continue; + } + + if (max < r->size) + max = r->size; + r = r->next; + } + + return max; +} + static struct nouveau_resource * nouveau_bo_tmp(struct nouveau_channel *chan, unsigned size, struct nouveau_fence *fence) @@ -103,6 +123,11 @@ nouveau_bo_tmp(struct nouveau_channel *chan, unsigned size, assert(ref); while (nouveau_resource_alloc(nvdev->sa_heap, size, ref, &r)) { + if (nouveau_bo_tmp_max(nvdev) < size) { + nouveau_fence_ref(NULL, &ref); + return NULL; + } + nouveau_fence_flush(chan); } nouveau_fence_signal_cb(ref, nouveau_bo_tmp_del, r); -- cgit v1.2.3 From 601b018a9a6143c634239d5bb51616724c2e593d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 25 Mar 2008 12:12:26 +1100 Subject: nouveau: refcount buffers on validate list. --- src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 1 - src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 8 ++++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h index 1c9b5799f9..d5a0e25b57 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -108,7 +108,6 @@ nouveau_fence_flush(struct nouveau_channel *); struct nouveau_pushbuf_reloc { uint64_t next; - uint64_t handle; uint32_t *ptr; uint32_t flags; uint32_t data; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c index a2b9321b15..2e3ac5492f 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -157,11 +157,13 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) if (bo->offset == nouveau_bo(bo)->offset && bo->flags == nouveau_bo(bo)->flags) { + while ((r = ptr_to_pbrel(pbbo->relocs))) { pbbo->relocs = r->next; free(r); } + nouveau_bo_del(&bo); nvpb->buffers = pbbo->next; free(pbbo); continue; @@ -175,6 +177,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) free(r); } + nouveau_bo_del(&bo); nvpb->buffers = pbbo->next; free(pbbo); } @@ -202,6 +205,7 @@ nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) { struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); struct nouveau_pushbuf_bo *pbbo = ptr_to_pbbo(nvpb->buffers); + struct nouveau_bo *ref = NULL; while (pbbo) { if (pbbo->handle == bo->handle) @@ -214,7 +218,8 @@ nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) nvpb->buffers = pbbo_to_ptr(pbbo); nvpb->nr_buffers++; - pbbo->handle = bo_to_ptr(bo); + nouveau_bo_ref(bo->device, bo->handle, &ref); + pbbo->handle = bo_to_ptr(ref); pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; pbbo->relocs = 0; pbbo->nr_relocs = 0; @@ -244,7 +249,6 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, pbbo->flags |= (flags & NOUVEAU_BO_RDWR); pbbo->flags &= (flags | NOUVEAU_BO_RDWR); - r->handle = bo_to_ptr(r); r->ptr = ptr; r->flags = flags; r->data = data; -- cgit v1.2.3 From b09de96a17028c3c936f6a196e048c4f224da89f Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 25 Mar 2008 18:07:56 -0700 Subject: xlib: Add support for MIT-SHM in xlib winsys driver Gives about a 3% performance increase in gears on x86-64 (non-tiled) and about 10% performance increase in gears on Cell (tiled). I actually expected more of a boost. :( --- src/gallium/winsys/xlib/xm_api.c | 16 +- src/gallium/winsys/xlib/xm_winsys.c | 301 ++++++++++++++++++++++++++------ src/gallium/winsys/xlib/xm_winsys_aub.h | 3 +- src/gallium/winsys/xlib/xmesaP.h | 3 + 4 files changed, 267 insertions(+), 56 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index e5fef1d7a8..6b46327e21 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -104,12 +104,16 @@ static int host_byte_order( void ) * 1 = shared XImage support available * 2 = shared Pixmap support available also */ -static int check_for_xshm( XMesaDisplay *display ) +int xmesa_check_for_xshm( XMesaDisplay *display ) { #if defined(USE_XSHM) && !defined(XFree86Server) int major, minor, ignore; Bool pixmaps; + if (getenv("MESA_NOSHM")) { + return 0; + } + if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { return (pixmaps==True) ? 2 : 1; @@ -528,7 +532,7 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, /* Setup for single/double buffering */ if (v->mesa_visual.doubleBufferMode) { /* Double buffered */ - b->shm = check_for_xshm( v->display ); + b->shm = xmesa_check_for_xshm( v->display ); } /* X11 graphics context */ @@ -770,13 +774,16 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) pf = choose_pixel_format(v); assert(pf); + c->xm_visual = v; + c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ + if (!getenv("XM_AUB")) { xmesa_mode = XMESA_SOFTPIPE; pipe = xmesa_create_pipe_context( c, pf ); } else { xmesa_mode = XMESA_AUB; - pipe = xmesa_create_i965simple( xmesa_get_pipe_winsys_aub() ); + pipe = xmesa_create_i965simple(xmesa_get_pipe_winsys_aub(v)); } c->st = st_create_context(pipe, &v->mesa_visual, @@ -800,9 +807,6 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) #endif /* finish up xmesa context initializations */ - c->xm_visual = v; - c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ - c->st->haveFramebufferSurfaces = GL_TRUE; return c; diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 018cf01cd6..7baaae295c 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -65,8 +65,19 @@ struct xm_buffer boolean userBuffer; /** Is this a user-space buffer? */ void *data; void *mapped; + + XImage *tempImage; + int shm; +#if defined(USE_XSHM) && !defined(XFree86Server) + XShmSegmentInfo shminfo; +#endif }; +#if defined(USE_XSHM) && !defined(XFree86Server) +# define XSHM_ENABLED(b) ((b)->shm) +#else +# define XSHM_ENABLED(b) 0 +#endif struct xmesa_surface { @@ -88,6 +99,16 @@ struct xmesa_softpipe_winsys }; +struct xmesa_pipe_winsys +{ + struct pipe_winsys base; + struct xmesa_visual *xm_visual; + int shm; +}; + + +static void alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, + unsigned width, unsigned height); /** Cast wrapper */ static INLINE struct xmesa_surface * @@ -136,13 +157,27 @@ xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) static void xm_buffer_destroy(struct pipe_winsys *pws, - struct pipe_buffer *buf) + struct pipe_buffer *buf) { struct xm_buffer *oldBuf = xm_buffer(buf); if (oldBuf->data) { - if (!oldBuf->userBuffer) - align_free(oldBuf->data); +#if defined(USE_XSHM) && !defined(XFree86Server) + if (oldBuf->shminfo.shmid >= 0) { + shmdt(oldBuf->shminfo.shmaddr); + shmctl(oldBuf->shminfo.shmid, IPC_RMID, 0); + + oldBuf->shminfo.shmid = -1; + oldBuf->shminfo.shmaddr = (char *) -1; + } + else +#endif + { + if (!oldBuf->userBuffer) { + align_free(oldBuf->data); + } + } + oldBuf->data = NULL; } @@ -157,7 +192,7 @@ xm_buffer_destroy(struct pipe_winsys *pws, static void xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) { - XImage *ximage = b->tempImage; + XImage *ximage; struct xm_buffer *xm_buf = xm_buffer(surf->buffer); const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE; uint x, y; @@ -166,10 +201,18 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) assert(ximage->format); assert(ximage->bitmap_unit); - /* update XImage's fields */ - ximage->width = TILE_SIZE; - ximage->height = TILE_SIZE; - ximage->bytes_per_line = TILE_SIZE * 4; + if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { + alloc_shm_ximage(xm_buf, b, TILE_SIZE, TILE_SIZE); + } + + ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; + + if (!XSHM_ENABLED(xm_buf)) { + /* update XImage's fields */ + ximage->width = TILE_SIZE; + ximage->height = TILE_SIZE; + ximage->bytes_per_line = TILE_SIZE * 4; + } for (y = 0; y < surf->height; y += TILE_SIZE) { for (x = 0; x < surf->width; x += TILE_SIZE) { @@ -183,8 +226,15 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) ximage->data = (char *) xm_buf->data + offset; - XPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, dx, dy, TILE_SIZE, TILE_SIZE); + if (XSHM_ENABLED(xm_buf)) { +#if defined(USE_XSHM) && !defined(XFree86Server) + XShmPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, x, y, TILE_SIZE, TILE_SIZE, False); +#endif + } else { + XPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, dx, dy, TILE_SIZE, TILE_SIZE); + } } } } @@ -197,7 +247,7 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) void xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) { - XImage *ximage = b->tempImage; + XImage *ximage; struct xm_buffer *xm_buf = xm_buffer(surf->buffer); const struct xmesa_surface *xm_surf = xmesa_surface((struct pipe_surface *) surf); @@ -207,19 +257,33 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) return; } - /* check that the XImage has been previously initialized */ - assert(ximage->format); - assert(ximage->bitmap_unit); - /* update XImage's fields */ - ximage->width = surf->width; - ximage->height = surf->height; - ximage->bytes_per_line = surf->pitch * (ximage->bits_per_pixel / 8); + if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { + alloc_shm_ximage(xm_buf, b, surf->pitch, surf->height); + } + + ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; ximage->data = xm_buf->data; /* display image in Window */ - XPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, 0, 0, surf->width, surf->height); + if (XSHM_ENABLED(xm_buf)) { +#if defined(USE_XSHM) && !defined(XFree86Server) + XShmPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, 0, 0, surf->width, surf->height, False); +#endif + } else { + /* check that the XImage has been previously initialized */ + assert(ximage->format); + assert(ximage->bitmap_unit); + + /* update XImage's fields */ + ximage->width = surf->width; + ximage->height = surf->height; + ximage->bytes_per_line = surf->pitch * surf->cpp; + + XPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, 0, 0, surf->width, surf->height); + } } @@ -256,6 +320,119 @@ xm_get_name(struct pipe_winsys *pws) } +#if defined(USE_XSHM) && !defined(XFree86Server) +static volatile int mesaXErrorFlag = 0; + +/** + * Catches potential Xlib errors. + */ +static int +mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event) +{ + (void) dpy; + (void) event; + mesaXErrorFlag = 1; + return 0; +} + + +static GLboolean alloc_shm(struct xm_buffer *buf, unsigned size) +{ + XShmSegmentInfo *const shminfo = & buf->shminfo; + + shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); + if (shminfo->shmid < 0) { + return GL_FALSE; + } + + shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); + if (shminfo->shmaddr == (char *) -1) { + shmctl(shminfo->shmid, IPC_RMID, 0); + return GL_FALSE; + } + + shminfo->readOnly = False; + return GL_TRUE; +} + + +/** + * Allocate a shared memory XImage back buffer for the given XMesaBuffer. + */ +static void +alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, + unsigned width, unsigned height) +{ + /* + * We have to do a _lot_ of error checking here to be sure we can + * really use the XSHM extension. It seems different servers trigger + * errors at different points if the extension won't work. Therefore + * we have to be very careful... + */ +#if 0 + GC gc; +#endif + int (*old_handler)(XMesaDisplay *, XErrorEvent *); + + b->tempImage = XShmCreateImage(xmb->xm_visual->display, + xmb->xm_visual->visinfo->visual, + xmb->xm_visual->visinfo->depth, + ZPixmap, + NULL, + &b->shminfo, + width, height); + if (b->tempImage == NULL) { + b->shm = 0; + return; + } + + + mesaXErrorFlag = 0; + old_handler = XSetErrorHandler(mesaHandleXError); + /* This may trigger the X protocol error we're ready to catch: */ + XShmAttach(xmb->xm_visual->display, &b->shminfo); + XSync(xmb->xm_visual->display, False); + + if (mesaXErrorFlag) { + /* we are on a remote display, this error is normal, don't print it */ + XFlush(xmb->xm_visual->display); + mesaXErrorFlag = 0; + XDestroyImage(b->tempImage); + b->tempImage = NULL; + b->shm = 0; + (void) XSetErrorHandler(old_handler); + return; + } + + + /* Finally, try an XShmPutImage to be really sure the extension works */ +#if 0 + gc = XCreateGC(xmb->xm_visual->display, xmb->drawable, 0, NULL); + XShmPutImage(xmb->xm_visual->display, xmb->drawable, gc, + b->tempImage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False); + XSync(xmb->xm_visual->display, False); + XFreeGC(xmb->xm_visual->display, gc); + (void) XSetErrorHandler(old_handler); + if (mesaXErrorFlag) { + XFlush(xmb->xm_visual->display); + mesaXErrorFlag = 0; + XDestroyImage(b->tempImage); + b->tempImage = NULL; + b->shm = 0; + return; + } +#endif +} +#else +static void +alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, + unsigned width, unsigned height) +{ + b->shm = 0; +} +#endif + + static struct pipe_buffer * xm_buffer_create(struct pipe_winsys *pws, unsigned alignment, @@ -263,13 +440,35 @@ xm_buffer_create(struct pipe_winsys *pws, unsigned size) { struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); +#if defined(USE_XSHM) && !defined(XFree86Server) + struct xmesa_pipe_winsys *xpws = (struct xmesa_pipe_winsys *) pws; +#endif + buffer->base.refcount = 1; buffer->base.alignment = alignment; buffer->base.usage = usage; buffer->base.size = size; - /* align to 16-byte multiple for Cell */ - buffer->data = align_malloc(size, max(alignment, 16)); + +#if defined(USE_XSHM) && !defined(XFree86Server) + buffer->shminfo.shmid = -1; + buffer->shminfo.shmaddr = (char *) -1; + + if (xpws->shm && (usage & PIPE_BUFFER_USAGE_PIXEL) != 0) { + buffer->shm = xpws->shm; + + if (alloc_shm(buffer, size)) { + buffer->data = buffer->shminfo.shmaddr; + } + } +#endif + + if (buffer->data == NULL) { + buffer->shm = 0; + + /* align to 16-byte multiple for Cell */ + buffer->data = align_malloc(size, max(alignment, 16)); + } return &buffer->base; } @@ -286,6 +485,7 @@ xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) buffer->base.size = bytes; buffer->userBuffer = TRUE; buffer->data = ptr; + buffer->shm = 0; return &buffer->base; } @@ -377,35 +577,38 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) * Nothing special for the Xlib driver so no subclassing or anything. */ struct pipe_winsys * -xmesa_get_pipe_winsys_aub(void) +xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) { - static struct pipe_winsys *ws = NULL; + static struct xmesa_pipe_winsys *ws = NULL; if (!ws && getenv("XM_AUB")) { - ws = xmesa_create_pipe_winsys_aub(); + ws = (struct xmesa_pipe_winsys *) xmesa_create_pipe_winsys_aub(); } else if (!ws) { - ws = CALLOC_STRUCT(pipe_winsys); - + ws = CALLOC_STRUCT(xmesa_pipe_winsys); + + ws->xm_visual = xm_vis; + ws->shm = xmesa_check_for_xshm(xm_vis->display); + /* Fill in this struct with callbacks that pipe will need to * communicate with the window system, buffer manager, etc. */ - ws->buffer_create = xm_buffer_create; - ws->user_buffer_create = xm_user_buffer_create; - ws->buffer_map = xm_buffer_map; - ws->buffer_unmap = xm_buffer_unmap; - ws->buffer_destroy = xm_buffer_destroy; - - ws->surface_alloc = xm_surface_alloc; - ws->surface_alloc_storage = xm_surface_alloc_storage; - ws->surface_release = xm_surface_release; - - ws->flush_frontbuffer = xm_flush_frontbuffer; - ws->printf = xm_printf; - ws->get_name = xm_get_name; + ws->base.buffer_create = xm_buffer_create; + ws->base.user_buffer_create = xm_user_buffer_create; + ws->base.buffer_map = xm_buffer_map; + ws->base.buffer_unmap = xm_buffer_unmap; + ws->base.buffer_destroy = xm_buffer_destroy; + + ws->base.surface_alloc = xm_surface_alloc; + ws->base.surface_alloc_storage = xm_surface_alloc_storage; + ws->base.surface_release = xm_surface_release; + + ws->base.flush_frontbuffer = xm_flush_frontbuffer; + ws->base.printf = xm_printf; + ws->base.get_name = xm_get_name; } - return ws; + return &ws->base; } @@ -445,27 +648,27 @@ xmesa_get_softpipe_winsys(uint pixelformat) struct pipe_context * xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) { - struct pipe_winsys *pws = xmesa_get_pipe_winsys_aub(); + struct pipe_winsys *pws = xmesa_get_pipe_winsys_aub(xmesa->xm_visual); struct pipe_context *pipe; #ifdef GALLIUM_CELL if (!getenv("GALLIUM_NOCELL")) { struct cell_winsys *cws = cell_get_winsys(pixelformat); struct pipe_screen *screen = cell_create_screen(pws); + pipe = cell_create_context(screen, cws); - if (pipe) - pipe->priv = xmesa; - return pipe; } else #endif { struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(pixelformat); struct pipe_screen *screen = softpipe_create_screen(pws); - pipe = softpipe_create( screen, pws, spws ); - if (pipe) - pipe->priv = xmesa; - return pipe; + pipe = softpipe_create(screen, pws, spws); } + + if (pipe) + pipe->priv = xmesa; + + return pipe; } diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.h b/src/gallium/winsys/xlib/xm_winsys_aub.h index 7bee199116..cc2a755277 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.h +++ b/src/gallium/winsys/xlib/xm_winsys_aub.h @@ -62,6 +62,7 @@ void xmesa_commands_aub(struct pipe_winsys *winsys, void xmesa_display_aub( /* struct pipe_winsys *winsys, */ struct pipe_surface *surface ); -struct pipe_winsys *xmesa_get_pipe_winsys_aub(void); +extern struct pipe_winsys * +xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis); #endif diff --git a/src/gallium/winsys/xlib/xmesaP.h b/src/gallium/winsys/xlib/xmesaP.h index fa8d1f14b9..9b15b2ddf9 100644 --- a/src/gallium/winsys/xlib/xmesaP.h +++ b/src/gallium/winsys/xlib/xmesaP.h @@ -173,4 +173,7 @@ xmesa_buffer_height(XMesaBuffer b) extern void xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf); +extern int +xmesa_check_for_xshm(XMesaDisplay *display); + #endif -- cgit v1.2.3 From 4abe1eb980ed76d2b2d3383eaab520d0aa2ae6f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 26 Mar 2008 09:36:40 +0000 Subject: gallium: Change pipe->flush() interface to optionally return a fence. The cell driver still uses an internal CELL_FLUSH_WAIT flag, in the long run proper fencing should be implemented for it. --- src/gallium/winsys/dri/intel/intel_context.c | 4 +-- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 25 +++++++++++-------- src/gallium/winsys/xlib/xm_winsys.c | 31 ++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 12 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 79b320c6bf..8eba33c313 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -228,7 +228,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) assert(intel); /* should never be null */ if (intel) { - st_flush(intel->st, PIPE_FLUSH_WAIT); + st_finish(intel->st); intel_batchbuffer_free(intel->batch); @@ -256,7 +256,7 @@ GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv) { struct intel_context *intel = intel_context(driContextPriv); - st_flush(intel->st, 0x0); + st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL); /* XXX make_current(NULL)? */ return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index 2def1afc31..4d183db7c3 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -39,12 +39,14 @@ #include "intel_winsys.h" #include "pipe/p_util.h" +#include "pipe/p_winsys.h" #include "i915simple/i915_winsys.h" #include "i915simple/i915_screen.h" struct intel_i915_winsys { struct i915_winsys winsys; /**< batch buffer funcs */ + struct pipe_winsys *pws; struct intel_context *intel; }; @@ -112,19 +114,22 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws, -static void intel_i915_batch_flush( struct i915_winsys *sws ) +static void intel_i915_batch_flush( struct i915_winsys *sws, + struct pipe_fence_handle **fence ) { - struct intel_context *intel = intel_i915_winsys(sws)->intel; + struct intel_i915_winsys *iws = intel_i915_winsys(sws); + struct intel_context *intel = iws->intel; + union { + struct _DriFenceObject *dri; + struct pipe_fence_handle *pipe; + } fu; - intel_batchbuffer_flush( intel->batch ); -// if (0) intel_i915_batch_wait_idle( sws ); -} + fu.dri = intel_batchbuffer_flush( intel->batch ); + if (fu.dri) + iws->pws->fence_reference(iws->pws, fence, fu.pipe); -static void intel_i915_batch_finish( struct i915_winsys *sws ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - intel_batchbuffer_finish( intel->batch ); +// if (0) intel_i915_batch_wait_idle( sws ); } @@ -145,7 +150,7 @@ intel_create_i915simple( struct intel_context *intel, iws->winsys.batch_dword = intel_i915_batch_dword; iws->winsys.batch_reloc = intel_i915_batch_reloc; iws->winsys.batch_flush = intel_i915_batch_flush; - iws->winsys.batch_finish = intel_i915_batch_finish; + iws->pws = winsys; iws->intel = intel; screen = i915_create_screen(winsys, intel->intelScreen->deviceID); diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 7baaae295c..c930a1d196 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -570,6 +570,33 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) } +/* + * Fence functions - basically nothing to do, as we don't create any actual + * fence objects. + */ + +static void +xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + /** * Return pointer to a pipe_winsys object. @@ -603,6 +630,10 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) ws->base.surface_alloc_storage = xm_surface_alloc_storage; ws->base.surface_release = xm_surface_release; + ws->fence_reference = xm_fence_reference; + ws->fence_signalled = xm_fence_signalled; + ws->fence_finish = xm_fence_finish; + ws->base.flush_frontbuffer = xm_flush_frontbuffer; ws->base.printf = xm_printf; ws->base.get_name = xm_get_name; -- cgit v1.2.3 From 70659e8ec8ba0c599daa36d9ed81e86efd99eb52 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 26 Mar 2008 10:52:08 -0700 Subject: xlib: Fix build error from recent fence changes --- src/gallium/winsys/xlib/xm_winsys.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index c930a1d196..7459756279 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -630,9 +630,9 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) ws->base.surface_alloc_storage = xm_surface_alloc_storage; ws->base.surface_release = xm_surface_release; - ws->fence_reference = xm_fence_reference; - ws->fence_signalled = xm_fence_signalled; - ws->fence_finish = xm_fence_finish; + ws->base.fence_reference = xm_fence_reference; + ws->base.fence_signalled = xm_fence_signalled; + ws->base.fence_finish = xm_fence_finish; ws->base.flush_frontbuffer = xm_flush_frontbuffer; ws->base.printf = xm_printf; -- cgit v1.2.3 From 5935b16ff5d8cbe07c97f2990e281a9c5986d0a1 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Mar 2008 21:11:45 -0600 Subject: If visual is 32bpp, set visual->alphaBits = 8. This works since we always use XImages for color buffers. It wouldn't always work for Windows/Pixmaps. --- src/gallium/winsys/xlib/xm_api.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 6b46327e21..a82d3c990e 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -511,6 +511,14 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, return GL_FALSE; } v->mesa_visual.indexBits = 0; + + if (v->BitsPerPixel == 32) { + /* We use XImages for all front/back buffers. If an X Window or + * X Pixmap is 32bpp, there's no guarantee that the alpha channel + * will be preserved. For XImages we're in luck. + */ + v->mesa_visual.alphaBits = 8; + } } /* -- cgit v1.2.3 From bbefb541ad94382debb0f7a8daa636729799a31a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 30 Mar 2008 20:32:22 +1000 Subject: nouveau: adapt to recent gallium changes --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 4 +-- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 12 ++++++- .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 42 ++++++++++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 336dd65847..cf1d83b18f 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -282,7 +282,7 @@ nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) assert(nv); - st_flush(nv->st, PIPE_FLUSH_WAIT); + st_finish(nv->st); st_destroy_context(nv->st); if (nv->pctx_id >= 0) { @@ -337,7 +337,7 @@ nouveau_context_unbind(__DRIcontextPrivate *driContextPriv) struct nouveau_context *nv = driContextPriv->driverPrivate; (void)nv; - st_flush(nv->st, 0); + st_flush(nv->st, 0, NULL); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index bf1afce5d9..60fdbb8dfd 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -69,8 +69,18 @@ nouveau_pipe_push_reloc(struct nouveau_winsys *nvws, void *ptr, } static int -nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size) +nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size, + struct pipe_fence_handle **fence) { + if (fence) { + struct nouveau_pushbuf *pb = nvws->channel->pushbuf; + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(pb); + struct nouveau_fence *ref = NULL; + + nouveau_fence_ref(nvpb->fence, &ref); + *fence = (struct pipe_fence_handle *)ref; + } + return nouveau_pushbuf_flush(nvws->channel, size); } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index e1a9271395..453b3623f4 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -164,6 +164,44 @@ nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) nouveau_bo_unmap(nvbuf->bo); } +static INLINE struct nouveau_fence * +nouveau_pipe_fence(struct pipe_fence_handle *pfence) +{ + return (struct nouveau_fence *)pfence; +} + +static void +nouveau_pipe_fence_reference(struct pipe_winsys *ws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *pfence) +{ + nouveau_fence_ref((void *)pfence, (void *)ptr); +} + +static int +nouveau_pipe_fence_signalled(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, unsigned flag) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)ws; + struct nouveau_fence *fence = nouveau_pipe_fence(pfence); + + if (nouveau_fence(fence)->signalled == 0) + nouveau_fence_flush(nvpws->nv->nvc->channel); + + return !nouveau_fence(fence)->signalled; +} + +static int +nouveau_pipe_fence_finish(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, unsigned flag) +{ + struct nouveau_fence *fence = nouveau_pipe_fence(pfence); + struct nouveau_fence *ref = NULL; + + nouveau_fence_ref(fence, &ref); + return nouveau_fence_wait(&ref); +} + struct pipe_winsys * nouveau_create_pipe_winsys(struct nouveau_context *nv) { @@ -189,6 +227,10 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv) pws->buffer_map = nouveau_pipe_bo_map; pws->buffer_unmap = nouveau_pipe_bo_unmap; + pws->fence_reference = nouveau_pipe_fence_reference; + pws->fence_signalled = nouveau_pipe_fence_signalled; + pws->fence_finish = nouveau_pipe_fence_finish; + pws->get_name = nouveau_get_name; return &nvpws->pws; -- cgit v1.2.3 From baab98a637d526871fb77ec6f313012f49c0e998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 31 Mar 2008 09:02:08 +0900 Subject: gallium: Eliminate p_winsys::printf Not convenient and almost not used at all. Better replacements in p_debug.h --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 10 ---------- src/gallium/winsys/xlib/xm_winsys.c | 11 ----------- src/gallium/winsys/xlib/xm_winsys_aub.c | 10 ---------- 3 files changed, 31 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 789a386500..77dec9488d 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -243,15 +243,6 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -static void -intel_printf( struct pipe_winsys *winsys, const char *fmtString, ... ) -{ - va_list args; - va_start( args, fmtString ); - vfprintf(stderr, fmtString, args); - va_end( args ); -} - static const char * intel_get_name( struct pipe_winsys *winsys ) { @@ -277,7 +268,6 @@ intel_create_pipe_winsys( int fd ) iws->winsys.buffer_unmap = intel_buffer_unmap; iws->winsys.buffer_destroy = intel_buffer_destroy; iws->winsys.flush_frontbuffer = intel_flush_frontbuffer; - iws->winsys.printf = intel_printf; iws->winsys.get_name = intel_get_name; iws->winsys.surface_alloc = intel_i915_surface_alloc; iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 7459756279..9a20bdfb69 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -303,16 +303,6 @@ xm_flush_frontbuffer(struct pipe_winsys *pws, -static void -xm_printf(struct pipe_winsys *pws, const char *fmtString, ...) -{ - va_list args; - va_start( args, fmtString ); - vfprintf(stderr, fmtString, args); - va_end( args ); -} - - static const char * xm_get_name(struct pipe_winsys *pws) { @@ -635,7 +625,6 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) ws->base.fence_finish = xm_fence_finish; ws->base.flush_frontbuffer = xm_flush_frontbuffer; - ws->base.printf = xm_printf; ws->base.get_name = xm_get_name; } diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index d55d8c39eb..f42f7fcc5f 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -311,15 +311,6 @@ aub_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -static void -aub_printf( struct pipe_winsys *winsys, const char *fmtString, ... ) -{ - va_list args; - va_start( args, fmtString ); - vfprintf(stderr, fmtString, args); - va_end( args ); -} - static const char * aub_get_name( struct pipe_winsys *winsys ) { @@ -344,7 +335,6 @@ xmesa_create_pipe_winsys_aub( void ) iws->winsys.buffer_unmap = aub_buffer_unmap; iws->winsys.buffer_destroy = aub_buffer_destroy; iws->winsys.flush_frontbuffer = aub_flush_frontbuffer; - iws->winsys.printf = aub_printf; iws->winsys.get_name = aub_get_name; iws->winsys.surface_alloc = aub_i915_surface_alloc; -- cgit v1.2.3 From 2df9941368c807fb677d3d95a5c1dfffe719c26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 1 Apr 2008 13:00:51 +0100 Subject: scons: Fix test for building dri/intel winsys. --- src/gallium/winsys/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index f18d3bd2f8..e8a581adb2 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -1,6 +1,6 @@ Import('*') -if dri: +if 'intel' in env['winsys'] and dri: SConscript([ 'dri/SConscript', ]) -- cgit v1.2.3 From 71d7aec2b3bb299f1dff7cdb2e8e96164976113a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 2 Apr 2008 00:40:18 +1000 Subject: nouveau: winsys printf disappeared :) --- src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index 453b3623f4..b1bf9c521a 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -20,15 +20,6 @@ nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, nouveau_copy_buffer(dPriv, surf, NULL); } -static void -nouveau_printf(struct pipe_winsys *pws, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); -} - static const char * nouveau_get_name(struct pipe_winsys *pws) { @@ -215,7 +206,6 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv) pws = &nvpws->pws; pws->flush_frontbuffer = nouveau_flush_frontbuffer; - pws->printf = nouveau_printf; pws->surface_alloc = nouveau_surface_alloc; pws->surface_alloc_storage = nouveau_surface_alloc_storage; -- cgit v1.2.3 From 333df9656a257507d5eb5a6a8e8f2d9fc7577f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 3 Apr 2008 13:19:38 +0100 Subject: gallium: Only build softpipe driver by default for xlib winsys with scons. --- src/gallium/winsys/xlib/SConscript | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index c38b5be52c..218b89285f 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -22,8 +22,6 @@ sources = [ drivers = [ softpipe, - i915simple, - i965simple, ] # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -- cgit v1.2.3 From fbb6cc7842ec8a59b60018233275babc4deb6765 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Apr 2008 12:39:45 +1000 Subject: nouveau: in some cases don't create the buffer in local mem initially. --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 11 ++++++++++- src/gallium/winsys/dri/nouveau/nouveau_context.h | 5 +++++ src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 2 ++ .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 22 ++++++++++++++++++++-- 4 files changed, 37 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index cf1d83b18f..aaeaebd271 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -7,6 +7,7 @@ #include "state_tracker/st_context.h" #include "pipe/p_defines.h" #include "pipe/p_context.h" +#include "pipe/p_screen.h" #include "nouveau_context.h" #include "nouveau_dri.h" @@ -133,7 +134,7 @@ nouveau_context_create(const __GLcontextModes *glVis, /* G80 */ break; default: - NOUVEAU_ERR("Unsupported chipset: NV%02x\n", nv->chipset); + NOUVEAU_ERR("Unsupported chipset: NV%02x\n", (int)nv->chipset); return GL_FALSE; } @@ -255,9 +256,17 @@ nouveau_context_create(const __GLcontextModes *glVis, } if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { + struct pipe_screen *pscreen; + pipe = nouveau_pipe_create(nv); if (!pipe) NOUVEAU_ERR("Couldn't create hw pipe\n"); + pscreen = nvc->pscreen; + + nv->cap.hw_vertex_buffer = + pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF); + nv->cap.hw_index_buffer = + pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF); } if (!pipe) { diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index 92f551855a..acb58fab44 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -56,6 +56,11 @@ struct nouveau_context { struct nouveau_screen *nv_screen; struct pipe_surface *frontbuffer; + struct { + int hw_vertex_buffer; + int hw_index_buffer; + } cap; + /* Hardware context */ struct nouveau_channel_context *nvc; int pctx_id; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c index 2e3ac5492f..78919bdee8 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -137,6 +137,8 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) if (nvpb->base.remaining == nvpb->size) return 0; + nouveau_fence_flush(chan); + nvpb->size -= nvpb->base.remaining; nvchan->dma->cur += nvpb->size; nvchan->dma->free -= nvpb->size; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index b1bf9c521a..849e38d22b 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -79,9 +79,10 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, unsigned usage, unsigned size) { struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; - struct nouveau_device *dev = nvpws->nv->nv_screen->device; + struct nouveau_context *nv = nvpws->nv; + struct nouveau_device *dev = nv->nv_screen->device; struct nouveau_pipe_buffer *nvbuf; - uint32_t flags = 0; + uint32_t flags; nvbuf = calloc(1, sizeof(*nvbuf)); if (!nvbuf) @@ -92,6 +93,23 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, nvbuf->base.size = size; flags = NOUVEAU_BO_LOCAL; + + if (usage & PIPE_BUFFER_USAGE_PIXEL) { + if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) + flags |= NOUVEAU_BO_GART; + flags |= NOUVEAU_BO_VRAM; + } + + if (usage & PIPE_BUFFER_USAGE_VERTEX) { + if (nv->cap.hw_vertex_buffer) + flags |= NOUVEAU_BO_GART; + } + + if (usage & PIPE_BUFFER_USAGE_INDEX) { + if (nv->cap.hw_index_buffer) + flags |= NOUVEAU_BO_GART; + } + if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) { free(nvbuf); return NULL; -- cgit v1.2.3 From bc67533f29abe578e2306be2a24db392a0c62fc4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Apr 2008 16:14:15 +1000 Subject: nouveau: create swizzled surface + scaled image objects --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 2 + src/gallium/winsys/dri/nouveau/nouveau_context.h | 7 +++- src/gallium/winsys/dri/nouveau/nv04_surface.c | 48 ++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index aaeaebd271..ff08a870db 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -32,6 +32,8 @@ nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) nouveau_grobj_free(&nvc->NvGdiRect); nouveau_grobj_free(&nvc->NvM2MF); nouveau_grobj_free(&nvc->Nv2D); + nouveau_grobj_free(&nvc->NvSwzSurf); + nouveau_grobj_free(&nvc->NvSIFM); nouveau_notifier_free(&nvc->sync_notifier); diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index acb58fab44..872ef93807 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -27,11 +27,16 @@ struct nouveau_channel_context { struct nouveau_notifier *sync_notifier; + /* Common */ struct nouveau_grobj *NvNull; + struct nouveau_grobj *NvM2MF; + /* NV04-NV40 */ struct nouveau_grobj *NvCtxSurf2D; + struct nouveau_grobj *NvSwzSurf; struct nouveau_grobj *NvImageBlit; struct nouveau_grobj *NvGdiRect; - struct nouveau_grobj *NvM2MF; + struct nouveau_grobj *NvSIFM; + /* G80 */ struct nouveau_grobj *Nv2D; uint32_t next_handle; diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index cdcd71eaad..f61bd1477f 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -237,6 +237,54 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + switch (nvc->chipset & 0xf0) { + case 0x00: + case 0x10: + class = NV04_SWIZZLED_SURFACE; + break; + case 0x20: + class = NV20_SWIZZLED_SURFACE; + break; + case 0x30: + class = NV30_SWIZZLED_SURFACE; + break; + case 0x40: + case 0x60: + class = NV40_SWIZZLED_SURFACE; + break; + default: + /* Famous last words: this really can't happen.. */ + assert(0); + break; + } + + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvSwzSurf); + if (ret) { + NOUVEAU_ERR("Error creating swizzled surface: %d\n", ret); + return 1; + } + + BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); + + if (nvc->chipset < 0x10) { + class = NV04_SCALED_IMAGE_FROM_MEMORY; + } else + if (nvc->chipset < 0x40) { + class = NV10_SCALED_IMAGE_FROM_MEMORY; + } else { + class = NV40_SCALED_IMAGE_FROM_MEMORY; + } + + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvSIFM); + if (ret) { + NOUVEAU_ERR("Error creating scaled image object: %d\n", ret); + return 1; + } + + BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); + return 0; } -- cgit v1.2.3 From d5d93a31580cf58744b4d186a4ab8fac09743a33 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Apr 2008 19:40:43 +0200 Subject: i915: Pulled in changes from i915tex --- src/gallium/winsys/dri/intel/Makefile | 7 +- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 488 ++++++----- src/gallium/winsys/dri/intel/intel_batchbuffer.h | 108 ++- src/gallium/winsys/dri/intel/intel_batchpool.c | 427 ---------- src/gallium/winsys/dri/intel/intel_batchpool.h | 37 - src/gallium/winsys/dri/intel/intel_context.c | 5 +- src/gallium/winsys/dri/intel/intel_context.h | 2 +- src/gallium/winsys/dri/intel/intel_ioctl.c | 138 ++++ src/gallium/winsys/dri/intel/intel_ioctl.h | 40 + src/gallium/winsys/dri/intel/intel_screen.c | 53 +- src/gallium/winsys/dri/intel/intel_screen.h | 9 +- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 4 +- src/gallium/winsys/dri/intel/intel_winsys.h | 2 +- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 30 +- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 55 +- src/gallium/winsys/dri/intel/server/i830_common.h | 46 +- src/gallium/winsys/dri/intel/ws_dri_bufmgr.c | 945 ++++++++++++++++++++++ src/gallium/winsys/dri/intel/ws_dri_bufmgr.h | 138 ++++ src/gallium/winsys/dri/intel/ws_dri_bufpool.h | 102 +++ src/gallium/winsys/dri/intel/ws_dri_drmpool.c | 268 ++++++ src/gallium/winsys/dri/intel/ws_dri_fencemgr.c | 372 +++++++++ src/gallium/winsys/dri/intel/ws_dri_fencemgr.h | 115 +++ src/gallium/winsys/dri/intel/ws_dri_mallocpool.c | 162 ++++ src/gallium/winsys/dri/intel/ws_dri_slabpool.c | 945 ++++++++++++++++++++++ 24 files changed, 3742 insertions(+), 756 deletions(-) delete mode 100644 src/gallium/winsys/dri/intel/intel_batchpool.c delete mode 100644 src/gallium/winsys/dri/intel/intel_batchpool.h create mode 100644 src/gallium/winsys/dri/intel/intel_ioctl.c create mode 100644 src/gallium/winsys/dri/intel/intel_ioctl.h create mode 100644 src/gallium/winsys/dri/intel/ws_dri_bufmgr.c create mode 100644 src/gallium/winsys/dri/intel/ws_dri_bufmgr.h create mode 100644 src/gallium/winsys/dri/intel/ws_dri_bufpool.h create mode 100644 src/gallium/winsys/dri/intel/ws_dri_drmpool.c create mode 100644 src/gallium/winsys/dri/intel/ws_dri_fencemgr.c create mode 100644 src/gallium/winsys/dri/intel/ws_dri_fencemgr.h create mode 100644 src/gallium/winsys/dri/intel/ws_dri_mallocpool.c create mode 100644 src/gallium/winsys/dri/intel/ws_dri_slabpool.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index 40654bb2ac..f140939248 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -19,11 +19,14 @@ DRIVER_SOURCES = \ intel_context.c \ intel_lock.c \ intel_screen.c \ - intel_batchpool.c + ws_dri_bufmgr.c \ + ws_dri_drmpool.c \ + ws_dri_fencemgr.c \ + ws_dri_mallocpool.c \ + ws_dri_slabpool.c C_SOURCES = \ $(COMMON_GALLIUM_SOURCES) \ - $(COMMON_BM_SOURCES) \ $(DRIVER_SOURCES) ASM_SOURCES = diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 5830b88b37..05223bf700 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -25,108 +25,95 @@ * **************************************************************************/ -#include -#include #include "intel_batchbuffer.h" -#include "intel_context.h" -#include "intel_screen.h" -#include "intel_reg.h" -#include "drm.h" - -/* Relocations in kernel space: - * - pass dma buffer seperately - * - memory manager knows how to patch - * - pass list of dependent buffers - * - pass relocation list - * - * Either: - * - get back an offset for buffer to fire - * - memory manager knows how to fire buffer - * - * Really want the buffer to be AGP and pinned. - * - */ - -/* Cliprect fence: The highest fence protecting a dma buffer - * containing explicit cliprect information. Like the old drawable - * lock but irq-driven. X server must wait for this fence to expire - * before changing cliprects [and then doing sw rendering?]. For - * other dma buffers, the scheduler will grab current cliprect info - * and mix into buffer. X server must hold the lock while changing - * cliprects??? Make per-drawable. Need cliprects in shared memory - * -- beats storing them with every cmd buffer in the queue. - * - * ==> X server must wait for this fence to expire before touching the - * framebuffer with new cliprects. - * - * ==> Cliprect-dependent buffers associated with a - * cliprect-timestamp. All of the buffers associated with a timestamp - * must go to hardware before any buffer with a newer timestamp. - * - * ==> Dma should be queued per-drawable for correct X/GL - * synchronization. Or can fences be used for this? - * - * Applies to: Blit operations, metaops, X server operations -- X - * server automatically waits on its own dma to complete before - * modifying cliprects ??? - */ +#include "intel_ioctl.h" +#include +#if 0 static void -intel_dump_batchbuffer(uint offset, uint * ptr, uint count) +intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) { int i; - printf("\n\n\nSTART BATCH (%d dwords):\n", count / 4); - for (i = 0; i < count / 4; i += 1) - printf("\t0x%08x\n", ptr[i]); - printf("END BATCH\n\n\n"); + fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); + for (i = 0; i < count / 4; i += 4) + fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", + offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); + fprintf(stderr, "END BATCH\n\n\n"); +} +#endif + +static void +intel_realloc_relocs(struct intel_batchbuffer *batch, int num_relocs) +{ + unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; + + size *= sizeof(uint32_t); + batch->reloc = realloc(batch->reloc, size); + batch->reloc_size = num_relocs; } void intel_batchbuffer_reset(struct intel_batchbuffer *batch) { - int i; - - if (batch->map) { - driBOUnmap(batch->buffer); - batch->map = NULL; - } - /* * Get a new, free batchbuffer. */ - batch->size = BATCH_SZ; - driBOData(batch->buffer, batch->size, NULL, 0); + drmBO *bo; + struct drm_bo_info_req *req; + + driBOUnrefUserList(batch->list); + driBOResetList(batch->list); - driBOResetList(&batch->list); + batch->size = 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize; + driBOData(batch->buffer, batch->size, NULL, NULL, 0); /* - * Unreference buffers previously on the relocation list. + * Add the batchbuffer to the validate list. */ - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - driBOUnReference(r->buf); - } - batch->list_count = 0; - batch->nr_relocs = 0; - batch->flags = 0; + driBOAddListItem(batch->list, batch->buffer, + DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, + &batch->dest_location, &batch->node); + + req = &batch->node->bo_arg.d.req.bo_req; /* - * We don't refcount the batchbuffer itself since we can't destroy it - * while it's on the list. + * Set up information needed for us to make relocations + * relative to the underlying drm buffer objects. */ - driBOAddListItem(&batch->list, batch->buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE); + driReadLockKernelBO(); + bo = driBOKernel(batch->buffer); + req->presumed_offset = (uint64_t) bo->offset; + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + batch->drmBOVirtual = (uint8_t *) bo->virtual; + driReadUnlockKernelBO(); + /* + * Adjust the relocation buffer size. + */ + + if (batch->reloc_size > INTEL_MAX_RELOCS || + batch->reloc == NULL) + intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); + + assert(batch->reloc != NULL); + batch->reloc[0] = 0; /* No relocs yet. */ + batch->reloc[1] = 1; /* Reloc type 1 */ + batch->reloc[2] = 0; /* Only a single relocation list. */ + batch->reloc[3] = 0; /* Only a single relocation list. */ batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->poolOffset = driBOPoolOffset(batch->buffer); batch->ptr = batch->map; + batch->dirty_state = ~0; + batch->nr_relocs = 0; + batch->flags = 0; + batch->id = 0;//batch->intel->intelScreen->batch_id++; } - /*====================================================================== * Public functions */ @@ -141,121 +128,253 @@ intel_batchbuffer_alloc(struct intel_context *intel) &batch->buffer, 4096, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); batch->last_fence = NULL; - driBOCreateList(20, &batch->list); + batch->list = driBOCreateList(20); + batch->reloc = NULL; intel_batchbuffer_reset(batch); return batch; } - void intel_batchbuffer_free(struct intel_batchbuffer *batch) { if (batch->last_fence) { driFenceFinish(batch->last_fence, - DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, - GL_FALSE); - driFenceUnReference(batch->last_fence); - batch->last_fence = NULL; + DRM_FENCE_TYPE_EXE, GL_FALSE); + driFenceUnReference(&batch->last_fence); } if (batch->map) { driBOUnmap(batch->buffer); batch->map = NULL; } driBOUnReference(batch->buffer); + driBOFreeList(batch->list); + if (batch->reloc) + free(batch->reloc); batch->buffer = NULL; free(batch); } +void +intel_offset_relocation(struct intel_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask) +{ + int itemLoc; + struct _drmBONode *node; + uint32_t *reloc; + struct drm_bo_info_req *req; + + driBOAddListItem(batch->list, driBO, val_flags, val_mask, + &itemLoc, &node); + req = &node->bo_arg.d.req.bo_req; + + if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { + + /* + * Stop other threads from tampering with the underlying + * drmBO while we're reading its offset. + */ + + driReadLockKernelBO(); + req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; + driReadUnlockKernelBO(); + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + } + + pre_add += driBOPoolOffset(driBO); + + if (batch->nr_relocs == batch->reloc_size) + intel_realloc_relocs(batch, batch->reloc_size * 2); + + reloc = batch->reloc + + (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); + + reloc[0] = ((uint8_t *)batch->ptr - batch->drmBOVirtual); + intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add); + reloc[1] = pre_add; + reloc[2] = itemLoc; + reloc[3] = batch->dest_location; + batch->nr_relocs++; +} static void -intel_batch_ioctl(struct intel_context *intel, - uint start_offset, uint used, boolean allow_unlock) +i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) { - drmI830BatchBuffer batch; - - batch.start = start_offset; - batch.used = used; - batch.cliprects = NULL; /* unused */ - batch.num_cliprects = 0; - batch.DR1 = 0; - batch.DR4 = 0; /* still need this ? */ - - DBG(IOCTL, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n", - __FUNCTION__, - batch.start, - batch.start + batch.used * 4, batch.DR4, batch.num_cliprects); - - if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch, - sizeof(batch))) { - printf("DRM_I830_BATCHBUFFER: %d\n", -errno); - UNLOCK_HARDWARE(intel); - exit(1); - } + buf->handle = rep->handle; + buf->flags = rep->flags; + buf->size = rep->size; + buf->offset = rep->offset; + buf->mapHandle = rep->arg_handle; + buf->proposedFlags = rep->proposed_flags; + buf->start = rep->buffer_start; + buf->fenceFlags = rep->fence_flags; + buf->replyFlags = rep->rep_flags; + buf->pageAlignment = rep->page_alignment; } +static int +i915_execbuf(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, + drmBOList *list, + struct drm_i915_execbuffer *ea) +{ + struct intel_context *intel = batch->intel; + drmBONode *node; + drmMMListHead *l; + struct drm_i915_op_arg *arg, *first; + struct drm_bo_op_req *req; + struct drm_bo_info_rep *rep; + uint64_t *prevNext = NULL; + drmBO *buf; + int ret = 0; + uint32_t count = 0; + + first = NULL; + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + + arg = &node->bo_arg; + req = &arg->d.req; + + if (!first) + first = arg; + + if (prevNext) + *prevNext = (unsigned long)arg; + + prevNext = &arg->next; + req->bo_req.handle = node->buf->handle; + req->op = drm_bo_validate; + req->bo_req.flags = node->arg0; + req->bo_req.mask = node->arg1; + req->bo_req.hint |= 0; + count++; + } + + memset(ea, 0, sizeof(*ea)); + ea->num_buffers = count; + ea->batch.start = batch->poolOffset; + ea->batch.used = used; +#if 0 /* ZZZ JB: no cliprects used */ + ea->batch.cliprects = intel->pClipRects; + ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); +#else + ea->batch.cliprects = NULL; + ea->batch.num_cliprects = 0; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0; +#endif + ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; + ea->ops_list = (unsigned long) first; + first->reloc_ptr = (unsigned long) batch->reloc; + batch->reloc[0] = batch->nr_relocs; + + //return -EFAULT; + do { + ret = drmCommandWriteRead(intel->driFd, DRM_I915_EXECBUFFER, ea, + sizeof(*ea)); + } while (ret == -EAGAIN); + + if (ret != 0) + return ret; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + arg = &node->bo_arg; + rep = &arg->d.rep.bo_info; + + if (!arg->handled) { + return -EFAULT; + } + if (arg->d.rep.ret) + return arg->d.rep.ret; + + buf = node->buf; + i915_drm_copy_reply(rep, buf); + } + return 0; +} /* TODO: Push this whole function into bufmgr. */ -static void +static struct _DriFenceObject * do_flush_locked(struct intel_batchbuffer *batch, - uint used, boolean allow_unlock) + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) { - uint *ptr; - uint i, fenceFlags; + struct intel_context *intel = batch->intel; struct _DriFenceObject *fo; + drmFence fence; + drmBOList *boList; + struct drm_i915_execbuffer ea; + int ret = 0; + + driBOValidateUserList(batch->list); + boList = driGetdrmBOList(batch->list); + +#if 0 /* ZZZ JB Allways run */ + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { +#else + if (1) { +#endif + ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); + } else { + driPutdrmBOList(batch->list); + fo = NULL; + goto out; + } + driPutdrmBOList(batch->list); + if (ret) + abort(); - driBOValidateList(batch->intel->driFd, &batch->list); - - /* Apply the relocations. This nasty map indicates to me that the - * whole task should be done internally by the memory manager, and - * that dma buffers probably need to be pinned within agp space. - */ - ptr = (uint *) driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_ALLOW_UNFENCED_MAP); + if (ea.fence_arg.error != 0) { - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; + /* + * The hardware has been idled by the kernel. + * Don't fence the driBOs. + */ - ptr[r->offset / 4] = driBOOffset(r->buf) + r->delta; + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); +#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ + _mesa_printf("fence error\n"); +#endif + batch->last_fence = NULL; + fo = NULL; + goto out; } - if (0) - intel_dump_batchbuffer(0, ptr, used); + fence.handle = ea.fence_arg.handle; + fence.fence_class = ea.fence_arg.fence_class; + fence.type = ea.fence_arg.type; + fence.flags = ea.fence_arg.flags; + fence.signaled = ea.fence_arg.signaled; - driBOUnmap(batch->buffer); - batch->map = NULL; - - intel_batch_ioctl(batch->intel, - driBOOffset(batch->buffer), - used, allow_unlock); - - /* - * Kernel fencing. The flags tells the kernel that we've - * programmed an MI_FLUSH. - */ - fenceFlags = DRM_I915_FENCE_FLAG_FLUSHED; - fo = driFenceBuffers(batch->intel->driFd, "Batch fence", fenceFlags); + fo = driBOFenceUserList(batch->intel->intelScreen->mgr, batch->list, + "SuperFence", &fence); + if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); /* - * User space fencing. - */ - driBOFence(batch->buffer, fo); - - if (driFenceType(fo) == DRM_FENCE_TYPE_EXE) { - /* - * Oops. We only validated a batch buffer. This means we - * didn't do any proper rendering. Discard this fence object. - */ - driFenceUnReference(fo); - } - else { - driFenceUnReference(batch->last_fence); - batch->last_fence = fo; - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - driBOFence(r->buf, fo); - } - } + * FIXME: Context last fence?? + */ + batch->last_fence = fo; + driFenceReference(fo); + } + out: +#if 0 /* ZZZ JB: fix this */ + intel->vtbl.lost_hardware(intel); +#else + (void)intel; +#endif + return fo; } @@ -263,29 +382,41 @@ struct _DriFenceObject * intel_batchbuffer_flush(struct intel_batchbuffer *batch) { struct intel_context *intel = batch->intel; - uint used = batch->ptr - batch->map; - const boolean was_locked = intel->locked; + GLuint used = batch->ptr - batch->map; + GLboolean was_locked = intel->locked; + struct _DriFenceObject *fence; if (used == 0) return batch->last_fence; -#define MI_FLUSH ((0 << 29) | (4 << 23)) - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a * performance drain that we would like to avoid. */ +#if 0 /* ZZZ JB: what should we do here? */ if (used & 4) { - ((int *) batch->ptr)[0] = MI_FLUSH; + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); ((int *) batch->ptr)[1] = 0; ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; used += 12; } else { - ((int *) batch->ptr)[0] = MI_FLUSH; + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; used += 8; } - +#else + if (used & 4) { + ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 8; + } +#endif driBOUnmap(batch->buffer); batch->ptr = NULL; batch->map = NULL; @@ -296,7 +427,8 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) if (!was_locked) LOCK_HARDWARE(intel); - do_flush_locked(batch, used, GL_FALSE); + fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + GL_FALSE); if (!was_locked) UNLOCK_HARDWARE(intel); @@ -304,52 +436,20 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) /* Reset the buffer: */ intel_batchbuffer_reset(batch); - return batch->last_fence; + return fence; } - void intel_batchbuffer_finish(struct intel_batchbuffer *batch) { struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); - if (fence) { - driFenceReference(fence); - driFenceFinish(fence, - DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, - GL_FALSE); - driFenceUnReference(fence); - } + driFenceFinish(fence, driFenceType(fence), GL_FALSE); + driFenceUnReference(&fence); } - -/* This is the only way buffers get added to the validate list. - */ -boolean -intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - struct _DriBufferObject *buffer, - uint flags, uint mask, uint delta) -{ - assert(batch->nr_relocs < MAX_RELOCS); - - driBOAddListItem(&batch->list, buffer, flags, mask); - - { - struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; - driBOReference(buffer); - r->buf = buffer; - r->offset = batch->ptr - batch->map; - r->delta = delta; - *(uint *) batch->ptr = 0x12345678; - } - - batch->ptr += 4; - return GL_TRUE; -} - - void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, uint bytes, uint flags) + const void *data, GLuint bytes, GLuint flags) { assert((bytes & 3) == 0); intel_batchbuffer_require_space(batch, bytes, flags); diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h index caf6870a3c..9e4b8043bf 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -1,54 +1,20 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - #ifndef INTEL_BATCHBUFFER_H #define INTEL_BATCHBUFFER_H -#include "pipe/p_debug.h" -#include "pipe/p_compiler.h" -#include "dri_bufmgr.h" +#include "mtypes.h" +#include "ws_dri_bufmgr.h" struct intel_context; #define BATCH_SZ 16384 #define BATCH_RESERVED 16 -#define MAX_RELOCS 4096 +#define INTEL_DEFAULT_RELOCS 100 +#define INTEL_MAX_RELOCS 400 #define INTEL_BATCH_NO_CLIPRECTS 0x1 #define INTEL_BATCH_CLIPRECTS 0x2 -struct buffer_reloc -{ - struct _DriBufferObject *buf; - uint offset; - uint delta; /* not needed? */ -}; - struct intel_batchbuffer { struct bufmgr *bm; @@ -56,19 +22,30 @@ struct intel_batchbuffer struct _DriBufferObject *buffer; struct _DriFenceObject *last_fence; - uint flags; + GLuint flags; - drmBOList list; - uint list_count; - ubyte *map; - ubyte *ptr; + struct _DriBufferList *list; + GLuint list_count; + GLubyte *map; + GLubyte *ptr; - struct buffer_reloc reloc[MAX_RELOCS]; - uint nr_relocs; - uint size; + uint32_t *reloc; + GLuint reloc_size; + GLuint nr_relocs; + + GLuint size; + + GLuint dirty_state; + GLuint id; + + uint32_t poolOffset; + uint8_t *drmBOVirtual; + struct _drmBONode *node; /* Validation list node for this buffer */ + int dest_location; /* Validation list sequence for this buffer */ }; -struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context *intel); +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context + *intel); void intel_batchbuffer_free(struct intel_batchbuffer *batch); @@ -82,26 +59,28 @@ void intel_batchbuffer_reset(struct intel_batchbuffer *batch); /* Unlike bmBufferData, this currently requires the buffer be mapped. - * Consider it a convenience function wrapping multiple + * Consider it a convenience function wrapping multple * intel_buffer_dword() calls. */ void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, uint bytes, uint flags); + const void *data, GLuint bytes, GLuint flags); void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, - uint bytes); + GLuint bytes); -boolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - struct _DriBufferObject *buffer, - uint flags, - uint mask, uint offset); +void +intel_offset_relocation(struct intel_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask); /* Inline functions - might actually be better off with these * non-inlined. Certainly better off switching all command packets to * be passed as structs rather than dwords, but that's a little bit of * work... */ -static INLINE uint +static INLINE GLuint intel_batchbuffer_space(struct intel_batchbuffer *batch) { return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); @@ -109,22 +88,26 @@ intel_batchbuffer_space(struct intel_batchbuffer *batch) static INLINE void -intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, uint dword) +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) { assert(batch->map); assert(intel_batchbuffer_space(batch) >= 4); - *(uint *) (batch->ptr) = dword; + *(GLuint *) (batch->ptr) = dword; batch->ptr += 4; } static INLINE void intel_batchbuffer_require_space(struct intel_batchbuffer *batch, - uint sz, uint flags) + GLuint sz, GLuint flags) { + struct _DriFenceObject *fence; + assert(sz < batch->size - 8); if (intel_batchbuffer_space(batch) < sz || - (batch->flags != 0 && flags != 0 && batch->flags != flags)) - intel_batchbuffer_flush(batch); + (batch->flags != 0 && flags != 0 && batch->flags != flags)) { + fence = intel_batchbuffer_flush(batch); + driFenceUnReference(&fence); + } batch->flags |= flags; } @@ -134,14 +117,15 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch, #define BATCH_LOCALS #define BEGIN_BATCH(n, flags) do { \ + assert(!intel->prim.flush); \ intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ } while (0) #define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) #define OUT_RELOC(buf,flags,mask,delta) do { \ - assert((delta) >= 0); \ - intel_batchbuffer_emit_reloc(intel->batch, buf, flags, mask, delta); \ + assert((delta) >= 0); \ + intel_offset_relocation(intel->batch, delta, buf, flags, mask); \ } while (0) #define ADVANCE_BATCH() do { } while(0) diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.c b/src/gallium/winsys/dri/intel/intel_batchpool.c deleted file mode 100644 index ce154c7b88..0000000000 --- a/src/gallium/winsys/dri/intel/intel_batchpool.c +++ /dev/null @@ -1,427 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - */ - -/** - * XXX NOTE: there are no intel dependencies in this file. - * Rename to dri_batchpool.c? - */ - -#include -#include -#include -#include - -#include "pipe/p_compiler.h" -#include "pipe/p_thread.h" - -#include "dri_bufpool.h" -#include "dri_bufmgr.h" -#include "intel_batchpool.h" - - -typedef struct -{ - drmMMListHead head; - struct _BPool *parent; - struct _DriFenceObject *fence; - unsigned long start; - int unfenced; - int mapped; -} BBuf; - -typedef struct _BPool -{ - _glthread_Mutex mutex; - unsigned long bufSize; - unsigned poolSize; - unsigned numFree; - unsigned numTot; - unsigned numDelayed; - unsigned checkDelayed; - drmMMListHead free; - drmMMListHead delayed; - drmMMListHead head; - drmBO kernelBO; - void *virtual; - BBuf *bufs; -} BPool; - - -static BPool * -createBPool(int fd, unsigned long bufSize, unsigned numBufs, unsigned flags, - unsigned checkDelayed) -{ - BPool *p = (BPool *) malloc(sizeof(*p)); - BBuf *buf; - int i; - - if (!p) - return NULL; - - p->bufs = (BBuf *) malloc(numBufs * sizeof(*p->bufs)); - if (!p->bufs) { - free(p); - return NULL; - } - - DRMINITLISTHEAD(&p->free); - DRMINITLISTHEAD(&p->head); - DRMINITLISTHEAD(&p->delayed); - - p->numTot = numBufs; - p->numFree = numBufs; - p->bufSize = bufSize; - p->numDelayed = 0; - p->checkDelayed = checkDelayed; - - _glthread_INIT_MUTEX(p->mutex); - - if (drmBOCreate(fd, 0, numBufs * bufSize, 0, NULL, drm_bo_type_dc, - flags, DRM_BO_HINT_DONT_FENCE, &p->kernelBO)) { - free(p->bufs); - free(p); - return NULL; - } - if (drmBOMap(fd, &p->kernelBO, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, - &p->virtual)) { - drmBODestroy(fd, &p->kernelBO); - free(p->bufs); - free(p); - return NULL; - } - - /* - * We unmap the buffer so that we can validate it later. Note that this is - * just a synchronizing operation. The buffer will have a virtual mapping - * until it is destroyed. - */ - - drmBOUnmap(fd, &p->kernelBO); - - buf = p->bufs; - for (i = 0; i < numBufs; ++i) { - buf->parent = p; - buf->fence = NULL; - buf->start = i * bufSize; - buf->mapped = 0; - buf->unfenced = 0; - DRMLISTADDTAIL(&buf->head, &p->free); - buf++; - } - - return p; -} - - -static void -pool_checkFree(BPool * p, int wait) -{ - drmMMListHead *list, *prev; - BBuf *buf; - int signaled = 0; - int i; - - list = p->delayed.next; - - if (p->numDelayed > 3) { - for (i = 0; i < p->numDelayed; i += 3) { - list = list->next; - } - } - - prev = list->prev; - for (; list != &p->delayed; list = prev, prev = list->prev) { - - buf = DRMLISTENTRY(BBuf, list, head); - - if (!signaled) { - if (wait) { - driFenceFinish(buf->fence, DRM_FENCE_TYPE_EXE, 1); - signaled = 1; - } - else { - signaled = driFenceSignaled(buf->fence, DRM_FENCE_TYPE_EXE); - } - } - - if (!signaled) - break; - - driFenceUnReference(buf->fence); - buf->fence = NULL; - DRMLISTDEL(list); - p->numDelayed--; - DRMLISTADD(list, &p->free); - p->numFree++; - } -} - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, unsigned flags, unsigned hint, - unsigned alignment) -{ - BPool *p = (BPool *) pool->data; - - drmMMListHead *item; - - if (alignment && (alignment != 4096)) - return NULL; - - _glthread_LOCK_MUTEX(p->mutex); - - if (p->numFree == 0) - pool_checkFree(p, TRUE); - - if (p->numFree == 0) { - fprintf(stderr, "Out of fixed size buffer objects\n"); - BM_CKFATAL(-ENOMEM); - } - - item = p->free.next; - - if (item == &p->free) { - fprintf(stderr, "Fixed size buffer pool corruption\n"); - } - - DRMLISTDEL(item); - --p->numFree; - - _glthread_UNLOCK_MUTEX(p->mutex); - return (void *) DRMLISTENTRY(BBuf, item, head); -} - - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - - if (buf->fence) { - DRMLISTADDTAIL(&buf->head, &p->delayed); - p->numDelayed++; - } - else { - buf->unfenced = 0; - DRMLISTADD(&buf->head, &p->free); - p->numFree++; - } - - if ((p->numDelayed % p->checkDelayed) == 0) - pool_checkFree(p, 0); - - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, void **virtual) -{ - - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - - /* - * Currently Mesa doesn't have any condition variables to resolve this - * cleanly in a multithreading environment. - * We bail out instead. - */ - - if (buf->mapped) { - fprintf(stderr, "Trying to map already mapped buffer object\n"); - BM_CKFATAL(-EINVAL); - } - -#if 0 - if (buf->unfenced && !(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) { - fprintf(stderr, "Trying to map an unfenced buffer object 0x%08x" - " 0x%08x %d\n", hint, flags, buf->start); - BM_CKFATAL(-EINVAL); - } - -#endif - - if (buf->fence) { - _glthread_UNLOCK_MUTEX(p->mutex); - return -EBUSY; - } - - buf->mapped = TRUE; - *virtual = (unsigned char *) p->virtual + buf->start; - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) -{ - BBuf *buf = (BBuf *) private; - driFenceFinish(buf->fence, 0x0, lazy); - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - - buf->mapped = 0; - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - return p->kernelBO.offset + buf->start; -} - -static unsigned -pool_flags(struct _DriBufferPool *pool, void *private) -{ - BPool *p = (BPool *) pool->data; - - return p->kernelBO.flags; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - BPool *p = (BPool *) pool->data; - - return p->bufSize; -} - - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - if (buf->fence) { - driFenceUnReference(buf->fence); - } - buf->fence = fence; - buf->unfenced = 0; - driFenceReference(buf->fence); - _glthread_UNLOCK_MUTEX(p->mutex); - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - return &p->kernelBO; -} - -static int -pool_validate(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - _glthread_LOCK_MUTEX(p->mutex); - buf->unfenced = TRUE; - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - BPool *p = (BPool *) pool->data; - - /* - * Wait on outstanding fences. - */ - - _glthread_LOCK_MUTEX(p->mutex); - while ((p->numFree < p->numTot) && p->numDelayed) { - _glthread_UNLOCK_MUTEX(p->mutex); - sched_yield(); - pool_checkFree(p, TRUE); - _glthread_LOCK_MUTEX(p->mutex); - } - - drmBODestroy(pool->fd, &p->kernelBO); - free(p->bufs); - _glthread_UNLOCK_MUTEX(p->mutex); - free(p); - free(pool); -} - - -struct _DriBufferPool * -driBatchPoolInit(int fd, unsigned flags, - unsigned long bufSize, - unsigned numBufs, unsigned checkDelayed) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - if (!pool) - return NULL; - - pool->data = createBPool(fd, bufSize, numBufs, flags, checkDelayed); - if (!pool->data) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = &pool_validate; - pool->waitIdle = &pool_waitIdle; - pool->setstatic = NULL; - pool->takeDown = &pool_takedown; - return pool; -} diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.h b/src/gallium/winsys/dri/intel/intel_batchpool.h deleted file mode 100644 index f6a95723bc..0000000000 --- a/src/gallium/winsys/dri/intel/intel_batchpool.h +++ /dev/null @@ -1,37 +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. - * - **************************************************************************/ - -#ifndef INTEL_BATCHPOOL_H -#define INTEL_BATCHPOOL_H - -extern struct _DriBufferPool *driBatchPoolInit(int fd, unsigned flags, - unsigned long bufSize, - unsigned numBufs, - unsigned checkDelayed); - - -#endif /* INTEL_BATCHPOOL_H */ diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 8eba33c313..cc2fc11c5e 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -162,6 +162,7 @@ intelCreateContext(const __GLcontextModes * visual, * memory pools */ DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + // ZZZ JB should be per screen and not be done per context havePools = intelCreatePools(sPriv); DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); if (!havePools) @@ -234,12 +235,12 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) if (intel->last_swap_fence) { driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(intel->last_swap_fence); + driFenceUnReference(&intel->last_swap_fence); intel->last_swap_fence = NULL; } if (intel->first_swap_fence) { driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(intel->first_swap_fence); + driFenceUnReference(&intel->first_swap_fence); intel->first_swap_fence = NULL; } diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h index 45430984d8..597dc13830 100644 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -28,7 +28,7 @@ #ifndef INTEL_CONTEXT_H #define INTEL_CONTEXT_H - +#include #include "drm.h" #include "pipe/p_debug.h" diff --git a/src/gallium/winsys/dri/intel/intel_ioctl.c b/src/gallium/winsys/dri/intel/intel_ioctl.c new file mode 100644 index 0000000000..3250c6b3a9 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_ioctl.c @@ -0,0 +1,138 @@ +/************************************************************************** + * + * 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 +#include +#include +#include + +#include "mtypes.h" +#include "context.h" +#include "swrast/swrast.h" + +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "drm.h" + +#define FILE_DEBUG_FLAG DEBUG_IOCTL + +int +intelEmitIrqLocked(struct intel_context *intel) +{ + drmI830IrqEmit ie; + int ret, seq; + + assert(((*(int *) intel->driHwLock) & ~DRM_LOCK_CONT) == + (DRM_LOCK_HELD | intel->hHWContext)); + + ie.irq_seq = &seq; + + ret = drmCommandWriteRead(intel->driFd, DRM_I830_IRQ_EMIT, + &ie, sizeof(ie)); + if (ret) { + fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret); + exit(1); + } + + DBG("%s --> %d\n", __FUNCTION__, seq); + + return seq; +} + +void +intelWaitIrq(struct intel_context *intel, int seq) +{ + int ret; + + DBG("%s %d\n", __FUNCTION__, seq); + + intel->iw.irq_seq = seq; + + do { + ret = + drmCommandWrite(intel->driFd, DRM_I830_IRQ_WAIT, &intel->iw, + sizeof(intel->iw)); + } while (ret == -EAGAIN || ret == -EINTR); + + if (ret) { + fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret); + exit(1); + } +} + + +void +intel_batch_ioctl(struct intel_context *intel, + GLuint start_offset, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + drmI830BatchBuffer batch; + + assert(intel->locked); + assert(used); + + DBG("%s used %d offset %x..%x ignore_cliprects %d\n", + __FUNCTION__, + used, start_offset, start_offset + used, ignore_cliprects); + + /* Throw away non-effective packets. Won't work once we have + * hardware contexts which would preserve statechanges beyond a + * single buffer. + */ + + + + batch.start = start_offset; + batch.used = used; + batch.cliprects = intel->pClipRects; + batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + batch.DR1 = 0; + batch.DR4 = ((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); + + DBG("%s: 0x%x..0x%x DR4: %x cliprects: %d\n", + __FUNCTION__, + batch.start, + batch.start + batch.used * 4, batch.DR4, batch.num_cliprects); + + if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch, + sizeof(batch))) { + fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); + UNLOCK_HARDWARE(intel); + exit(1); + } + + /* FIXME: use hardware contexts to avoid 'losing' hardware after + * each buffer flush. + */ + intel->vtbl.lost_hardware(intel); +} diff --git a/src/gallium/winsys/dri/intel/intel_ioctl.h b/src/gallium/winsys/dri/intel/intel_ioctl.h new file mode 100644 index 0000000000..e8d07de893 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_ioctl.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef INTEL_IOCTL_H +#define INTEL_IOCTL_H + +#include "intel_context.h" + +void intelWaitIrq(struct intel_context *intel, int seq); +int intelEmitIrqLocked(struct intel_context *intel); + +void intel_batch_ioctl(struct intel_context *intel, + GLuint start_offset, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock); +#endif diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 9e31c013a9..a3fc6d7344 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -32,12 +32,12 @@ #include "intel_context.h" #include "intel_screen.h" #include "intel_batchbuffer.h" -#include "intel_batchpool.h" +//#include "intel_batchpool.h" #include "intel_swapbuffers.h" #include "intel_winsys.h" #include "i830_dri.h" -#include "dri_bufpool.h" +#include "ws_dri_bufpool.h" #include "pipe/p_context.h" #include "state_tracker/st_public.h" @@ -132,6 +132,7 @@ intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) assert( sarea->front_size >= intelScreen->front.pitch * intelScreen->front.height ); +#if 0 /* JB not important */ if (!sarea->front_handle) return; @@ -142,30 +143,41 @@ intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) fprintf(stderr, "drmMap(frontbuffer) failed!\n"); return; } +#endif +#if 0 /* JB */ if (intelScreen->staticPool) { driGenBuffers(intelScreen->staticPool, "static region", 1, &intelScreen->front.buffer, 64, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - + driBOSetStatic(intelScreen->front.buffer, intelScreen->front.offset, intelScreen->front.pitch * intelScreen->front.height, intelScreen->front.map, 0); } +#else + if (intelScreen->staticPool) { + if (intelScreen->front.buffer) + driBOUnReference(intelScreen->front.buffer); + driGenBuffers(intelScreen->staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); + driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle); + } +#endif } boolean intelCreatePools(__DRIscreenPrivate * sPriv) { - unsigned batchPoolSize = 1024*1024; + //unsigned batchPoolSize = 1024*1024; struct intel_screen *intelScreen = intel_screen(sPriv); if (intelScreen->havePools) return GL_TRUE; +#if 0 /* ZZZ JB fix this */ intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); if (!intelScreen->staticPool) return GL_FALSE; @@ -181,7 +193,17 @@ intelCreatePools(__DRIscreenPrivate * sPriv) fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); return GL_FALSE; } - +#else + intelScreen->staticPool = driDRMPoolInit(sPriv->fd); + intelScreen->batchPool = driSlabPoolInit(sPriv->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + 4096, //intelScreen->maxBatchSize, + 1, 40, 16*16384, 0, + intelScreen->fMan); +#endif intelScreen->havePools = GL_TRUE; intelUpdateScreenRotation(sPriv, intelScreen->sarea); @@ -240,7 +262,26 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd); + + +#if 1 // ZZZ JB + intelScreen->mgr = driFenceMgrTTMInit(sPriv->fd); + if (!intelScreen->mgr) { + fprintf(stderr, "Failed to create fence manager.\n"); + return GL_FALSE; + } + + intelScreen->fMan = driInitFreeSlabManager(10, 10); + if (!intelScreen->fMan) { + fprintf(stderr, "Failed to create free slab manager.\n"); + return GL_FALSE; + } + + if (!intelCreatePools(sPriv)) + return GL_FALSE; +#endif + + intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd, intelScreen->fMan); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index 3396f9e564..c17f0202e4 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -31,7 +31,7 @@ #include "dri_util.h" #include "i830_common.h" #include "xmlconfig.h" -#include "dri_bufpool.h" +#include "ws_dri_bufpool.h" #include "pipe/p_compiler.h" @@ -74,6 +74,13 @@ struct intel_screen */ struct intel_context *dummyContext; + /* + * New stuff form the i915tex integration + */ + struct _DriFenceMgr *mgr; + struct _DriFreeSlabManager *fMan; + unsigned batch_id; + struct pipe_winsys *winsys; }; diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 56b86d6a63..1a42389169 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -63,7 +63,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, if (intel->last_swap_fence) { driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); - driFenceUnReference(intel->last_swap_fence); + driFenceUnReference(&intel->last_swap_fence); intel->last_swap_fence = NULL; } intel->last_swap_fence = intel->first_swap_fence; @@ -178,7 +178,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, } if (intel->first_swap_fence) - driFenceUnReference(intel->first_swap_fence); + driFenceUnReference(&intel->first_swap_fence); intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); driFenceReference(intel->first_swap_fence); } diff --git a/src/gallium/winsys/dri/intel/intel_winsys.h b/src/gallium/winsys/dri/intel/intel_winsys.h index ffc40782be..d0a319f9a4 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys.h +++ b/src/gallium/winsys/dri/intel/intel_winsys.h @@ -37,7 +37,7 @@ struct pipe_buffer; struct _DriBufferObject; struct pipe_winsys * -intel_create_pipe_winsys( int fd ); +intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ); void intel_destroy_pipe_winsys( struct pipe_winsys *winsys ); diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index 4d183db7c3..ae3e9654d3 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -31,8 +31,8 @@ #include #include -#include "dri_bufpool.h" -#include "dri_bufmgr.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" #include "intel_context.h" #include "intel_batchbuffer.h" @@ -106,10 +106,18 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws, mask |= DRM_BO_FLAG_READ; } - intel_batchbuffer_emit_reloc( intel->batch, +#if 0 /* JB old */ + intel_batchbuffer_emit_reloc( intel->batch, dri_bo( buf ), - flags, mask, + flags, mask, delta ); +#else /* new */ + intel_offset_relocation( intel->batch, + delta, + dri_bo( buf ), + flags, + mask ); +#endif } @@ -126,8 +134,18 @@ static void intel_i915_batch_flush( struct i915_winsys *sws, fu.dri = intel_batchbuffer_flush( intel->batch ); - if (fu.dri) - iws->pws->fence_reference(iws->pws, fence, fu.pipe); + if (!fu.dri && fence) { + *fence = NULL; + return; + } + + if (fu.dri) { + if (fence) + *fence = fu.pipe; + else + iws->pws->fence_reference(iws->pws, &fu.dri, NULL); + } + // if (0) intel_i915_batch_wait_idle( sws ); } diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 77dec9488d..59729a0245 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -31,8 +31,8 @@ #include #include -#include "dri_bufpool.h" -#include "dri_bufmgr.h" +//#include "dri_bufpool.h" +//#include "dri_bufmgr.h" #include "intel_context.h" #include "intel_winsys.h" @@ -50,6 +50,7 @@ struct intel_pipe_winsys { struct pipe_winsys winsys; struct _DriBufferPool *regionPool; + struct _DriFreeSlabManager *fMan; }; @@ -142,7 +143,7 @@ intel_buffer_create(struct pipe_winsys *winsys, driGenBuffers( iws->regionPool, "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); - driBOData( buffer->driBO, size, NULL, 0 ); + driBOData( buffer->driBO, size, NULL, iws->regionPool, 0 ); return &buffer->base; } @@ -155,7 +156,7 @@ intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); driGenUserBuffer( iws->regionPool, - "pipe user buffer", &buffer->driBO, ptr, bytes); + "pipe user buffer", &buffer->driBO, ptr, bytes ); return &buffer->base; } @@ -209,7 +210,7 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned flags) { const unsigned alignment = 64; - int ret; + //int ret; surf->width = width; surf->height = height; @@ -249,9 +250,37 @@ intel_get_name( struct pipe_winsys *winsys ) return "Intel/DRI/ttm"; } +static void +intel_fence_reference( struct pipe_winsys *sws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence ) +{ + if (*ptr) + driFenceUnReference((struct _DriFenceObject **)ptr); + + if (fence) + *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); +} + +static int +intel_fence_signalled( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + return driFenceSignaled((struct _DriFenceObject *)fence, flag); +} + +static int +intel_fence_finish( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + /* JB: Lets allways lazy wait */ + return driFenceFinish((struct _DriFenceObject *)fence, flag, 1); +} struct pipe_winsys * -intel_create_pipe_winsys( int fd ) +intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) { struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys ); @@ -273,8 +302,20 @@ intel_create_pipe_winsys( int fd ) iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; iws->winsys.surface_release = intel_i915_surface_release; + iws->winsys.fence_reference = intel_fence_reference; + iws->winsys.fence_signalled = intel_fence_signalled; + iws->winsys.fence_finish = intel_fence_finish; + if (fd) - iws->regionPool = driDRMPoolInit(fd); + iws->regionPool = driSlabPoolInit(fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + 64, 6, 16, 4096, 0, + fMan); return &iws->winsys; } diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h index d4d58886ce..f1fd3939ab 100644 --- a/src/gallium/winsys/dri/intel/server/i830_common.h +++ b/src/gallium/winsys/dri/intel/server/i830_common.h @@ -54,6 +54,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRM_I830_DESTROY_HEAP 0x0c #define DRM_I830_SET_VBLANK_PIPE 0x0d #define DRM_I830_GET_VBLANK_PIPE 0x0e +#define DRM_I830_MMIO 0x10 typedef struct { enum { @@ -85,6 +86,7 @@ typedef struct { int last_enqueue; /* last time a buffer was enqueued */ int last_dispatch; /* age of the most recently dispatched buffer */ int ctxOwner; /* last context to upload state */ + /** Last context that used the buffer manager. */ int texAge; int pf_enabled; /* is pageflipping allowed? */ int pf_active; @@ -121,20 +123,29 @@ typedef struct { unsigned int rotated_tiled; unsigned int rotated2_tiled; - int pipeA_x; - int pipeA_y; - int pipeA_w; - int pipeA_h; - int pipeB_x; - int pipeB_y; - int pipeB_w; - int pipeB_h; + int planeA_x; + int planeA_y; + int planeA_w; + int planeA_h; + int planeB_x; + int planeB_y; + int planeB_w; + int planeB_h; /* Triple buffering */ drm_handle_t third_handle; int third_offset; int third_size; unsigned int third_tiled; + + /* buffer object handles for the static buffers. May change + * over the lifetime of the client, though it doesn't in our current + * implementation. + */ + unsigned int front_bo_handle; + unsigned int back_bo_handle; + unsigned int third_bo_handle; + unsigned int depth_bo_handle; } drmI830Sarea; /* Flags for perf_boxes @@ -223,4 +234,23 @@ typedef struct { int pipe; } drmI830VBlankPipe; +#define MMIO_READ 0 +#define MMIO_WRITE 1 + +#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 +#define MMIO_REGS_IA_VERTICES_COUNT 1 +#define MMIO_REGS_VS_INVOCATION_COUNT 2 +#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 +#define MMIO_REGS_GS_INVOCATION_COUNT 4 +#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 +#define MMIO_REGS_CL_INVOCATION_COUNT 6 +#define MMIO_REGS_PS_INVOCATION_COUNT 7 +#define MMIO_REGS_PS_DEPTH_COUNT 8 + +typedef struct { + unsigned int read_write:1; + unsigned int reg:31; + void __user *data; +} drmI830MMIO; + #endif /* _I830_DRM_H_ */ diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c new file mode 100644 index 0000000000..eb5216cb37 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c @@ -0,0 +1,945 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + * Keith Whitwell + */ + +#include +#include +#include "glthread.h" +#include "errno.h" +#include "ws_dri_bufmgr.h" +#include "string.h" +#include "imports.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" + +/* + * This lock is here to protect drmBO structs changing underneath us during a + * validate list call, since validatelist cannot take individiual locks for + * each drmBO. Validatelist takes this lock in write mode. Any access to an + * individual drmBO should take this lock in read mode, since in that case, the + * driBufferObject mutex will protect the access. Locking order is + * driBufferObject mutex - > this rw lock. + */ + +_glthread_DECLARE_STATIC_MUTEX(bmMutex); +_glthread_DECLARE_STATIC_COND(bmCond); + +static int kernelReaders = 0; + +static drmBO *drmBOListBuf(void *iterator) +{ + drmBONode *node; + drmMMListHead *l = (drmMMListHead *) iterator; + node = DRMLISTENTRY(drmBONode, l, head); + return node->buf; +} + +static void *drmBOListIterator(drmBOList *list) +{ + void *ret = list->list.next; + + if (ret == &list->list) + return NULL; + return ret; +} + +static void *drmBOListNext(drmBOList *list, void *iterator) +{ + void *ret; + + drmMMListHead *l = (drmMMListHead *) iterator; + ret = l->next; + if (ret == &list->list) + return NULL; + return ret; +} + +static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, + uint64_t arg0, + uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } + else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADD(&node->head, &list->list); + list->numOnList++; + return node; +} + +static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, + uint64_t mask, int *newItem) +{ + drmBONode *node, *cur; + drmMMListHead *l; + + *newItem = 0; + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + } + if (!cur) { + cur = drmAddListItem(list, buf, flags, mask); + if (!cur) { + return -ENOMEM; + } + *newItem = 1; + cur->arg0 = flags; + cur->arg1 = mask; + } + else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + return 0; +} + +static void drmBOFreeList(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->list.next; + while(l != &list->list) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->list.next; + list->numCurrent--; + list->numOnList--; + } + + l = list->free.next; + while(l != &list->free) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->free.next; + list->numCurrent--; + } +} + +static int drmAdjustListNodes(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + int ret = 0; + + while(list->numCurrent < list->numTarget) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + ret = -ENOMEM; + break; + } + list->numCurrent++; + DRMLISTADD(&node->head, &list->free); + } + + while(list->numCurrent > list->numTarget) { + l = list->free.next; + if (l == &list->free) + break; + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + list->numCurrent--; + } + return ret; +} + +static int drmBOCreateList(int numTarget, drmBOList *list) +{ + DRMINITLISTHEAD(&list->list); + DRMINITLISTHEAD(&list->free); + list->numTarget = numTarget; + list->numCurrent = 0; + list->numOnList = 0; + return drmAdjustListNodes(list); +} + +static int drmBOResetList(drmBOList *list) +{ + drmMMListHead *l; + int ret; + + ret = drmAdjustListNodes(list); + if (ret) + return ret; + + l = list->list.next; + while (l != &list->list) { + DRMLISTDEL(l); + DRMLISTADD(l, &list->free); + list->numOnList--; + l = list->list.next; + } + return drmAdjustListNodes(list); +} + +void driWriteLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + while(kernelReaders != 0) + _glthread_COND_WAIT(bmCond, bmMutex); +} + +void driWriteUnlockKernelBO(void) +{ + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + kernelReaders++; + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadUnlockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + if (--kernelReaders == 0) + _glthread_COND_BROADCAST(bmCond); + _glthread_UNLOCK_MUTEX(bmMutex); +} + + + + +/* + * TODO: Introduce fence pools in the same way as + * buffer object pools. + */ + +typedef struct _DriBufferObject +{ + DriBufferPool *pool; + _glthread_Mutex mutex; + int refCount; + const char *name; + uint64_t flags; + unsigned hint; + unsigned alignment; + unsigned createdByReference; + void *private; + /* user-space buffer: */ + unsigned userBuffer; + void *userData; + unsigned userSize; +} DriBufferObject; + +typedef struct _DriBufferList { + drmBOList drmBuffers; /* List of kernel buffers needing validation */ + drmBOList driBuffers; /* List of user-space buffers needing validation */ +} DriBufferList; + + +void +bmError(int val, const char *file, const char *function, int line) +{ + _mesa_printf("Fatal video memory manager error \"%s\".\n" + "Check kernel logs or set the LIBGL_DEBUG\n" + "environment variable to \"verbose\" for more info.\n" + "Detected in file %s, line %d, function %s.\n", + strerror(-val), file, line, function); +#ifndef NDEBUG + abort(); +#else + abort(); +#endif +} + +extern drmBO * +driBOKernel(struct _DriBufferObject *buf) +{ + drmBO *ret; + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + ret = buf->pool->kernel(buf->pool, buf->private); + if (!ret) + BM_CKFATAL(-EINVAL); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + + return ret; +} + +void +driBOWaitIdle(struct _DriBufferObject *buf, int lazy) +{ + + /* + * This function may block. Is it sane to keep the mutex held during + * that time?? + */ + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void * +driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) +{ + void *virtual; + int retval; + + if (buf->userBuffer) { + return buf->userData; + } + + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + retval = buf->pool->map(buf->pool, buf->private, flags, hint, + &buf->mutex, &virtual); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval == 0 ? virtual : NULL; +} + +void +driBOUnmap(struct _DriBufferObject *buf) +{ + if (buf->userBuffer) + return; + + assert(buf->private != NULL); + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +unsigned long +driBOOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->offset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +unsigned long +driBOPoolOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->poolOffset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +uint64_t +driBOFlags(struct _DriBufferObject *buf) +{ + uint64_t ret; + + assert(buf->private != NULL); + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->flags(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + return ret; +} + +struct _DriBufferObject * +driBOReference(struct _DriBufferObject *buf) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (++buf->refCount == 1) { + _glthread_UNLOCK_MUTEX(buf->mutex); + BM_CKFATAL(-EINVAL); + } + _glthread_UNLOCK_MUTEX(buf->mutex); + return buf; +} + +void +driBOUnReference(struct _DriBufferObject *buf) +{ + int tmp; + + if (!buf) + return; + + + _glthread_LOCK_MUTEX(buf->mutex); + tmp = --buf->refCount; + if (!tmp) { + _glthread_UNLOCK_MUTEX(buf->mutex); + if (buf->private) { + if (buf->createdByReference) + buf->pool->unreference(buf->pool, buf->private); + else + buf->pool->destroy(buf->pool, buf->private); + } + free(buf); + } else + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + + +int +driBOData(struct _DriBufferObject *buf, + unsigned size, const void *data, + DriBufferPool *newPool, + uint64_t flags) +{ + void *virtual = NULL; + int newBuffer; + int retval = 0; + struct _DriBufferPool *pool; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + pool = buf->pool; + + if (pool == NULL && newPool != NULL) { + buf->pool = newPool; + pool = newPool; + } + if (newPool == NULL) + newPool = pool; + + if (!pool->create) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "driBOData called on invalid buffer\n"); + BM_CKFATAL(-EINVAL); + } + + newBuffer = (!buf->private || pool != newPool || + pool->size(pool, buf->private) < size); + + if (!flags) + flags = buf->flags; + + if (newBuffer) { + + if (buf->createdByReference) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "driBOData requiring resizing called on " + "shared buffer.\n"); + BM_CKFATAL(-EINVAL); + } + + if (buf->private) + buf->pool->destroy(buf->pool, buf->private); + + pool = newPool; + buf->pool = newPool; + buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (!buf->private) + retval = -ENOMEM; + + if (retval == 0) + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); + } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { + /* + * Buffer is busy. need to create a new one. + */ + + void *newBuf; + + newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (newBuf) { + buf->pool->destroy(buf->pool, buf->private); + buf->private = newBuf; + } + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } else { + uint64_t flag_diff = flags ^ buf->flags; + + /* + * We might need to change buffer flags. + */ + + if (flag_diff){ + assert(pool->setStatus != NULL); + BM_CKFATAL(pool->unmap(pool, buf->private)); + BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, + buf->flags)); + if (!data) + goto out; + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } + } + + if (retval == 0) { + if (data) + memcpy(virtual, data, size); + + BM_CKFATAL(pool->unmap(pool, buf->private)); + } + + out: + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval; +} + +void +driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, const void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, + &virtual)); + memcpy((unsigned char *) virtual + offset, data, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); + memcpy(data, (unsigned char *) virtual + offset, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->private != NULL) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "Invalid buffer for setReferenced\n"); + BM_CKFATAL(-EINVAL); + + } + if (buf->pool->reference == NULL) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "Invalid buffer pool for setReferenced\n"); + BM_CKFATAL(-EINVAL); + } + buf->private = buf->pool->reference(buf->pool, handle); + if (!buf->private) { + _mesa_error(NULL, GL_OUT_OF_MEMORY, + "Invalid buffer pool for setStatic\n"); + BM_CKFATAL(-ENOMEM); + } + buf->createdByReference = GL_TRUE; + buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +int +driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint) +{ + struct _DriBufferObject *buf; + int i; + + flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + + assert(pool); + + for (i = 0; i < n; ++i) { + buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); + if (!buf) + return -ENOMEM; + + _glthread_INIT_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(buf->mutex); + buf->refCount = 1; + buf->flags = flags; + buf->hint = hint; + buf->name = name; + buf->alignment = alignment; + buf->pool = pool; + buf->createdByReference = 0; + _glthread_UNLOCK_MUTEX(buf->mutex); + buffers[i] = buf; + } + return 0; +} + +void +driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject **buffers, + void *ptr, unsigned bytes) +{ + const unsigned alignment = 1, flags = 0, hint = 0; + + driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); + + (*buffers)->userBuffer = 1; + (*buffers)->userData = ptr; + (*buffers)->userSize = bytes; +} + +void +driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) +{ + int i; + + for (i = 0; i < n; ++i) { + driBOUnReference(buffers[i]); + } +} + + +void +driInitBufMgr(int fd) +{ + ; +} + +/* + * Note that lists are per-context and don't need mutex protection. + */ + +struct _DriBufferList * +driBOCreateList(int target) +{ + struct _DriBufferList *list = calloc(sizeof(*list), 1); + + BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); + BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); + return list; +} + +int +driBOResetList(struct _DriBufferList * list) +{ + int ret; + ret = drmBOResetList(&list->drmBuffers); + if (ret) + return ret; + ret = drmBOResetList(&list->driBuffers); + return ret; +} + +void +driBOFreeList(struct _DriBufferList * list) +{ + drmBOFreeList(&list->drmBuffers); + drmBOFreeList(&list->driBuffers); + free(list); +} + + +/* + * Copied from libdrm, because it is needed by driAddValidateItem. + */ + +static drmBONode * +driAddListItem(drmBOList * list, drmBO * item, + uint64_t arg0, uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + memset(&node->bo_arg, 0, sizeof(node->bo_arg)); + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADDTAIL(&node->head, &list->list); + list->numOnList++; + return node; +} + +/* + * Slightly modified version compared to the libdrm version. + * This one returns the list index of the buffer put on the list. + */ + +static int +driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, + uint64_t mask, int *itemLoc, + struct _drmBONode **pnode) +{ + drmBONode *node, *cur; + drmMMListHead *l; + int count = 0; + + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + count++; + } + if (!cur) { + cur = driAddListItem(list, buf, flags, mask); + if (!cur) + return -ENOMEM; + + cur->arg0 = flags; + cur->arg1 = mask; + } else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + *itemLoc = count; + *pnode = cur; + return 0; +} + + +void +driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node) +{ + int newItem; + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(driAddValidateItem(&list->drmBuffers, + buf->pool->kernel(buf->pool, buf->private), + flags, mask, itemLoc, node)); + BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, + flags, mask, &newItem)); + if (newItem) + buf->refCount++; + + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +drmBOList *driGetdrmBOList(struct _DriBufferList *list) +{ + driWriteLockKernelBO(); + return &list->drmBuffers; +} + +void driPutdrmBOList(struct _DriBufferList *list) +{ + driWriteUnlockKernelBO(); +} + + +void +driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->fence) + BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + +void +driBOUnrefUserList(struct _DriBufferList *list) +{ + struct _DriBufferObject *buf; + void *curBuf; + + curBuf = drmBOListIterator(&list->driBuffers); + while (curBuf) { + buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + +struct _DriFenceObject * +driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, const char *name, + drmFence *kFence) +{ + struct _DriFenceObject *fence; + struct _DriBufferObject *buf; + void *curBuf; + + fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, + kFence, sizeof(*kFence)); + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space fencing callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + driBOFence(buf, fence); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } + + driBOResetList(list); + return fence; +} + +void +driBOValidateUserList(struct _DriBufferList * list) +{ + void *curBuf; + struct _DriBufferObject *buf; + + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space validation callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->validate) + BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); + _glthread_UNLOCK_MUTEX(buf->mutex); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + + +void +driPoolTakeDown(struct _DriBufferPool *pool) +{ + pool->takeDown(pool); + +} + +unsigned long +driBOSize(struct _DriBufferObject *buf) +{ + unsigned long size; + + _glthread_LOCK_MUTEX(buf->mutex); + size = buf->pool->size(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return size; + +} + +drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) +{ + return &list->drmBuffers; +} + +drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) +{ + return &list->driBuffers; +} + diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h new file mode 100644 index 0000000000..fdaf5ee93a --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + * Keith Whitwell + */ + +#ifndef _PSB_BUFMGR_H_ +#define _PSB_BUFMGR_H_ +#include +#include "i915_drm.h" +#include "ws_dri_fencemgr.h" + +typedef struct _drmBONode +{ + drmMMListHead head; + drmBO *buf; + struct drm_i915_op_arg bo_arg; + uint64_t arg0; + uint64_t arg1; +} drmBONode; + +typedef struct _drmBOList { + unsigned numTarget; + unsigned numCurrent; + unsigned numOnList; + drmMMListHead list; + drmMMListHead free; +} drmBOList; + + +struct _DriFenceObject; +struct _DriBufferObject; +struct _DriBufferPool; +struct _DriBufferList; + +/* + * Return a pointer to the libdrm buffer object this DriBufferObject + * uses. + */ + +extern drmBO *driBOKernel(struct _DriBufferObject *buf); +extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, + unsigned hint); +extern void driBOUnmap(struct _DriBufferObject *buf); +extern unsigned long driBOOffset(struct _DriBufferObject *buf); +extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); + +extern uint64_t driBOFlags(struct _DriBufferObject *buf); +extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); +extern void driBOUnReference(struct _DriBufferObject *buf); + +extern int driBOData(struct _DriBufferObject *r_buf, + unsigned size, const void *data, + struct _DriBufferPool *pool, uint64_t flags); + +extern void driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + const void *data); +extern void driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + void *data); +extern int driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint); +extern void driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject *buffers[], + void *ptr, unsigned bytes); +extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); +extern void driInitBufMgr(int fd); +extern struct _DriBufferList *driBOCreateList(int target); +extern int driBOResetList(struct _DriBufferList * list); +extern void driBOAddListItem(struct _DriBufferList * list, + struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node); + +extern void driBOValidateList(int fd, struct _DriBufferList * list); +extern void driBOFreeList(struct _DriBufferList * list); +extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, + const char *name, + drmFence *kFence); +extern void driBOUnrefUserList(struct _DriBufferList *list); +extern void driBOValidateUserList(struct _DriBufferList * list); +extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); +extern void driPutdrmBOList(struct _DriBufferList *list); + +extern void driBOFence(struct _DriBufferObject *buf, + struct _DriFenceObject *fence); + +extern void driPoolTakeDown(struct _DriBufferPool *pool); +extern void driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle); +unsigned long driBOSize(struct _DriBufferObject *buf); +extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); +extern void driPoolTakeDown(struct _DriBufferPool *pool); + +extern void driReadLockKernelBO(void); +extern void driReadUnlockKernelBO(void); +extern void driWriteLockKernelBO(void); +extern void driWriteUnlockKernelBO(void); + +/* + * For debugging purposes. + */ + +extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); +extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); +#endif diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufpool.h b/src/gallium/winsys/dri/intel/ws_dri_bufpool.h new file mode 100644 index 0000000000..3a302e13d3 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_bufpool.h @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +#ifndef _PSB_BUFPOOL_H_ +#define _PSB_BUFPOOL_H_ + +#include +#include +struct _DriFenceObject; + +typedef struct _DriBufferPool +{ + int fd; + int (*map) (struct _DriBufferPool * pool, void *private, + unsigned flags, int hint, _glthread_Mutex *mutex, + void **virtual); + int (*unmap) (struct _DriBufferPool * pool, void *private); + int (*destroy) (struct _DriBufferPool * pool, void *private); + unsigned long (*offset) (struct _DriBufferPool * pool, void *private); + unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); + uint64_t (*flags) (struct _DriBufferPool * pool, void *private); + unsigned long (*size) (struct _DriBufferPool * pool, void *private); + void *(*create) (struct _DriBufferPool * pool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment); + void *(*reference) (struct _DriBufferPool * pool, unsigned handle); + int (*unreference) (struct _DriBufferPool * pool, void *private); + int (*fence) (struct _DriBufferPool * pool, void *private, + struct _DriFenceObject * fence); + drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); + int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy); + int (*setStatus) (struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags); + void (*takeDown) (struct _DriBufferPool * pool); + void *data; +} DriBufferPool; + +extern void bmError(int val, const char *file, const char *function, + int line); +#define BM_CKFATAL(val) \ + do{ \ + int tstVal = (val); \ + if (tstVal) \ + bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ + } while(0); + + +/* + * Builtin pools. + */ + +/* + * Kernel buffer objects. Size in multiples of page size. Page size aligned. + */ + +extern struct _DriBufferPool *driDRMPoolInit(int fd); +extern struct _DriBufferPool *driMallocPoolInit(void); + +struct _DriFreeSlabManager; +extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan); +extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); +extern struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); + + +#endif diff --git a/src/gallium/winsys/dri/intel/ws_dri_drmpool.c b/src/gallium/winsys/dri/intel/ws_dri_drmpool.c new file mode 100644 index 0000000000..7c55dbc674 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_drmpool.c @@ -0,0 +1,268 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" +#include "assert.h" + +/* + * Buffer pool implementation using DRM buffer objects as DRI buffer objects. + */ + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + unsigned pageSize = getpagesize(); + + if (!buf) + return NULL; + + if ((alignment > pageSize) && (alignment % pageSize)) { + free(buf); + return NULL; + } + + ret = drmBOCreate(pool->fd, size, alignment / pageSize, + NULL, + flags, hint, buf); + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static void * +pool_reference(struct _DriBufferPool *pool, unsigned handle) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + + if (!buf) + return NULL; + + ret = drmBOReference(pool->fd, handle, buf); + + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unreference(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOMap(pool->fd, buf, flags, hint, virtual); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOUnmap(pool->fd, buf); + driReadUnlockKernelBO(); + + return ret; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long offset; + + driReadLockKernelBO(); + assert(buf->flags & DRM_BO_FLAG_NO_MOVE); + offset = buf->offset; + driReadUnlockKernelBO(); + + return buf->offset; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + uint64_t flags; + + driReadLockKernelBO(); + flags = buf->flags; + driReadUnlockKernelBO(); + + return flags; +} + + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long size; + + driReadLockKernelBO(); + size = buf->size; + driReadUnlockKernelBO(); + + return buf->size; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + /* + * Noop. The kernel handles all fencing. + */ + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + return (drmBO *) private; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); + driReadUnlockKernelBO(); + + return ret; +} + + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + +/*static int +pool_setStatus(struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags) +{ + drmBO *buf = (drmBO *) private; + uint64_t new_flags = old_flags ^ flag_diff; + int ret; + + driReadLockKernelBO(); + ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, + 0, 0, 0); + driReadUnlockKernelBO(); + return ret; +}*/ + +struct _DriBufferPool * +driDRMPoolInit(int fd) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + + if (!pool) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + pool->reference = &pool_reference; + pool->unreference = &pool_unreference; + pool->data = NULL; + return pool; +} diff --git a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c new file mode 100644 index 0000000000..8aaef1c620 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c @@ -0,0 +1,372 @@ +#include "ws_dri_fencemgr.h" +#include "glthread.h" +#include +#include +#include + +/* + * Note: Locking order is + * _DriFenceObject::mutex + * _DriFenceMgr::mutex + */ + +struct _DriFenceMgr { + /* + * Constant members. Need no mutex protection. + */ + struct _DriFenceMgrCreateInfo info; + void *private; + + /* + * These members are protected by this->mutex + */ + _glthread_Mutex mutex; + int refCount; + drmMMListHead *heads; +}; + +struct _DriFenceObject { + + /* + * These members are constant and need no mutex protection. + */ + struct _DriFenceMgr *mgr; + uint32_t fence_class; + uint32_t fence_type; + + /* + * These members are protected by mgr->mutex. + */ + drmMMListHead head; + int refCount; + + /* + * These members are protected by this->mutex. + */ + _glthread_Mutex mutex; + uint32_t signaled_type; + void *private; +}; + +uint32_t +driFenceType(struct _DriFenceObject *fence) +{ + return fence->fence_type; +} + +struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) +{ + struct _DriFenceMgr *tmp; + uint32_t i; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->refCount = 1; + tmp->info = *info; + tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); + if (!tmp->heads) + goto out_err; + + for (i=0; iinfo.num_classes; ++i) { + DRMINITLISTHEAD(&tmp->heads[i]); + } + _glthread_UNLOCK_MUTEX(tmp->mutex); + return tmp; + + out_err: + if (tmp) + free(tmp); + return NULL; +} + +static void +driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) +{ + struct _DriFenceMgr *mgr = *pMgr; + + *pMgr = NULL; + if (--mgr->refCount == 0) + free(mgr); + else + _glthread_UNLOCK_MUTEX(mgr->mutex); +} + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr) +{ + _glthread_LOCK_MUTEX((*pMgr)->mutex); + driFenceMgrUnrefUnlock(pMgr); +} + +static void +driFenceUnReferenceLocked(struct _DriFenceObject **pFence) +{ + struct _DriFenceObject *fence = *pFence; + struct _DriFenceMgr *mgr = fence->mgr; + + *pFence = NULL; + if (--fence->refCount == 0) { + DRMLISTDELINIT(&fence->head); + if (fence->private) + mgr->info.unreference(mgr, &fence->private); + fence->mgr = NULL; + --mgr->refCount; + free(fence); + } +} + + +static void +driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, + drmMMListHead *list, + uint32_t fence_class, + uint32_t fence_type) +{ + struct _DriFenceObject *entry; + drmMMListHead *prev; + + while(list != &mgr->heads[fence_class]) { + entry = DRMLISTENTRY(struct _DriFenceObject, list, head); + + /* + * Up refcount so that entry doesn't disappear from under us + * when we unlock-relock mgr to get the correct locking order. + */ + + ++entry->refCount; + _glthread_UNLOCK_MUTEX(mgr->mutex); + _glthread_LOCK_MUTEX(entry->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + + prev = list->prev; + + + + if (list->prev == list) { + + /* + * Somebody else removed the entry from the list. + */ + + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + return; + } + + entry->signaled_type |= (fence_type & entry->fence_type); + if (entry->signaled_type == entry->fence_type) { + DRMLISTDELINIT(list); + mgr->info.unreference(mgr, &entry->private); + } + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + list = prev; + } +} + + +int +driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint) +{ + struct _DriFenceMgr *mgr = fence->mgr; + int ret = 0; + + _glthread_LOCK_MUTEX(fence->mutex); + + if ((fence->signaled_type & fence_type) == fence_type) + goto out0; + + ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); + if (ret) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + fence_type); + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) +{ + uint32_t ret; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = fence->signaled_type; + _glthread_UNLOCK_MUTEX(fence->mutex); + + return ret; +} + +int +driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, + uint32_t *signaled) +{ + int ret = 0; + struct _DriFenceMgr *mgr; + + _glthread_LOCK_MUTEX(fence->mutex); + mgr = fence->mgr; + *signaled = fence->signaled_type; + if ((fence->signaled_type & flush_type) == flush_type) + goto out0; + + ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); + if (ret) { + *signaled = fence->signaled_type; + goto out0; + } + + if ((fence->signaled_type | *signaled) == fence->signaled_type) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + *signaled); + + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +struct _DriFenceObject * +driFenceReference(struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(fence->mgr->mutex); + ++fence->refCount; + _glthread_UNLOCK_MUTEX(fence->mgr->mutex); + return fence; +} + +void +driFenceUnReference(struct _DriFenceObject **pFence) +{ + struct _DriFenceMgr *mgr; + + if (*pFence == NULL) + return; + + mgr = (*pFence)->mgr; + _glthread_LOCK_MUTEX(mgr->mutex); + ++mgr->refCount; + driFenceUnReferenceLocked(pFence); + driFenceMgrUnrefUnlock(&mgr); +} + +struct _DriFenceObject +*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, + uint32_t fence_type, void *private, size_t private_size) +{ + struct _DriFenceObject *fence; + size_t fence_size = sizeof(*fence); + + if (private_size) + fence_size = ((fence_size + 15) & ~15); + + fence = calloc(1, fence_size + private_size); + + if (!fence) { + int ret = mgr->info.finish(mgr, private, fence_type, 0); + + if (ret) + usleep(10000000); + + return NULL; + } + + _glthread_INIT_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + fence->refCount = 1; + DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); + fence->mgr = mgr; + ++mgr->refCount; + _glthread_UNLOCK_MUTEX(mgr->mutex); + fence->fence_class = fence_class; + fence->fence_type = fence_type; + fence->signaled_type = 0; + fence->private = private; + if (private_size) { + fence->private = (void *)(((uint8_t *) fence) + fence_size); + memcpy(fence->private, private, private_size); + } + + _glthread_UNLOCK_MUTEX(fence->mutex); + return fence; +} + + +static int +tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type) +{ + long fd = (long) mgr->private; + int dummy; + drmFence *fence = (drmFence *) private; + int ret; + + *signaled_type = 0; + ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); + if (ret) + return ret; + + *signaled_type = fence->signaled; + + return 0; +} + +static int +tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, + int lazy_hint) +{ + long fd = (long) mgr->private; + unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; + + return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); +} + +static int +tUnref(struct _DriFenceMgr *mgr, void **private) +{ + long fd = (long) mgr->private; + drmFence *fence = (drmFence *) *private; + *private = NULL; + + return drmFenceUnreference(fd, fence); +} + +struct _DriFenceMgr *driFenceMgrTTMInit(int fd) +{ + struct _DriFenceMgrCreateInfo info; + struct _DriFenceMgr *mgr; + + info.flags = DRI_FENCE_CLASS_ORDERED; + info.num_classes = 4; + info.signaled = tSignaled; + info.finish = tFinish; + info.unreference = tUnref; + + mgr = driFenceMgrCreate(&info); + if (mgr == NULL) + return NULL; + + mgr->private = (void *) (long) fd; + return mgr; +} + diff --git a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h new file mode 100644 index 0000000000..4ea58dfe18 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h @@ -0,0 +1,115 @@ +#ifndef DRI_FENCEMGR_H +#define DRI_FENCEMGR_H + +#include +#include + +struct _DriFenceObject; +struct _DriFenceMgr; + +/* + * Do a quick check to see if the fence manager has registered the fence + * object as signaled. Note that this function may return a false negative + * answer. + */ +extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); + +/* + * Check if the fence object is signaled. This function can be substantially + * more expensive to call than the above function, but will not return a false + * negative answer. The argument "flush_type" sets the types that the + * underlying mechanism must make sure will eventually signal. + */ +extern int driFenceSignaledType(struct _DriFenceObject *fence, + uint32_t flush_type, uint32_t *signaled); + +/* + * Convenience functions. + */ + +static inline int driFenceSignaled(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types; + int ret = driFenceSignaledType(fence, flush_type, &signaled_types); + if (ret) + return 0; + return ((signaled_types & flush_type) == flush_type); +} + +static inline int driFenceSignaledCached(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types = + driFenceSignaledTypeCached(fence); + + return ((signaled_types & flush_type) == flush_type); +} + +/* + * Reference a fence object. + */ +extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); + +/* + * Unreference a fence object. The fence object pointer will be reset to NULL. + */ + +extern void driFenceUnReference(struct _DriFenceObject **pFence); + + +/* + * Wait for a fence to signal the indicated fence_type. + * If "lazy_hint" is true, it indicates that the wait may sleep to avoid + * busy-wait polling. + */ +extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint); + +/* + * Create a DriFenceObject for manager "mgr". + * + * "private" is a pointer that should be used for the callbacks in + * struct _DriFenceMgrCreateInfo. + * + * if private_size is nonzero, then the info stored at *private, with size + * private size will be copied and the fence manager will instead use a + * pointer to the copied data for the callbacks in + * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by + * "private" may be destroyed after the call to driFenceCreate. + */ +extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, + uint32_t fence_class, + uint32_t fence_type, + void *private, + size_t private_size); + +extern uint32_t driFenceType(struct _DriFenceObject *fence); + +/* + * Fence creations are ordered. If a fence signals a fence_type, + * it is safe to assume that all fences of the same class that was + * created before that fence has signaled the same type. + */ + +#define DRI_FENCE_CLASS_ORDERED (1 << 0) + +struct _DriFenceMgrCreateInfo { + uint32_t flags; + uint32_t num_classes; + int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type); + int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); + int (*unreference) (struct _DriFenceMgr *mgr, void **private); +}; + +extern struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr); + +extern struct _DriFenceMgr * +driFenceMgrTTMInit(int fd); + +#endif diff --git a/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c b/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c new file mode 100644 index 0000000000..bf97d7e440 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c @@ -0,0 +1,162 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +#include +#include +#include +#include "imports.h" +#include "glthread.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" +#include "intel_screen.h" + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + unsigned long *private = malloc(size + 2*sizeof(unsigned long)); + if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) + abort(); + + *private = size; + return (void *)private; +} + + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + free(private); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + *virtual = (void *)((unsigned long *)private + 2); + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); + return 0UL; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + return *(unsigned long *) private; +} + + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + abort(); + return 0UL; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + abort(); + return NULL; +} + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + + +struct _DriBufferPool * +driMallocPoolInit(void) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + if (!pool) + return NULL; + + pool->data = NULL; + pool->fd = -1; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + return pool; +} diff --git a/src/gallium/winsys/dri/intel/ws_dri_slabpool.c b/src/gallium/winsys/dri/intel/ws_dri_slabpool.c new file mode 100644 index 0000000000..235f0ac972 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_slabpool.c @@ -0,0 +1,945 @@ +/************************************************************************** + * + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#include +#include +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" +#include "ws_dri_bufmgr.h" +#include "glthread.h" + +#define DRI_SLABPOOL_ALLOC_RETRIES 100 + +struct _DriSlab; + +struct _DriSlabBuffer { + int isSlabBuffer; + drmBO *bo; + struct _DriFenceObject *fence; + struct _DriSlab *parent; + drmMMListHead head; + uint32_t mapCount; + uint32_t start; + uint32_t fenceType; + int unFenced; + _glthread_Cond event; +}; + +struct _DriKernelBO { + int fd; + drmBO bo; + drmMMListHead timeoutHead; + drmMMListHead head; + struct timeval timeFreed; + uint32_t pageAlignment; + void *virtual; +}; + +struct _DriSlab{ + drmMMListHead head; + drmMMListHead freeBuffers; + uint32_t numBuffers; + uint32_t numFree; + struct _DriSlabBuffer *buffers; + struct _DriSlabSizeHeader *header; + struct _DriKernelBO *kbo; +}; + + +struct _DriSlabSizeHeader { + drmMMListHead slabs; + drmMMListHead freeSlabs; + drmMMListHead delayedBuffers; + uint32_t numDelayed; + struct _DriSlabPool *slabPool; + uint32_t bufSize; + _glthread_Mutex mutex; +}; + +struct _DriFreeSlabManager { + struct timeval slabTimeout; + struct timeval checkInterval; + struct timeval nextCheck; + drmMMListHead timeoutList; + drmMMListHead unCached; + drmMMListHead cached; + _glthread_Mutex mutex; +}; + + +struct _DriSlabPool { + + /* + * The data of this structure remains constant after + * initialization and thus needs no mutex protection. + */ + + struct _DriFreeSlabManager *fMan; + uint64_t proposedFlags; + uint64_t validMask; + uint32_t *bucketSizes; + uint32_t numBuckets; + uint32_t pageSize; + int fd; + int pageAlignment; + int maxSlabSize; + int desiredNumBuffers; + struct _DriSlabSizeHeader *headers; +}; + +/* + * FIXME: Perhaps arrange timeout slabs in size buckets for fast + * retreival?? + */ + + +static inline int +driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) +{ + return ((arg1->tv_sec > arg2->tv_sec) || + ((arg1->tv_sec == arg2->tv_sec) && + (arg1->tv_usec > arg2->tv_usec))); +} + +static inline void +driTimeAdd(struct timeval *arg, struct timeval *add) +{ + unsigned int sec; + + arg->tv_sec += add->tv_sec; + arg->tv_usec += add->tv_usec; + sec = arg->tv_usec / 1000000; + arg->tv_sec += sec; + arg->tv_usec -= sec*1000000; +} + +static void +driFreeKernelBO(struct _DriKernelBO *kbo) +{ + if (!kbo) + return; + + (void) drmBOUnreference(kbo->fd, &kbo->bo); + free(kbo); +} + + +static void +driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, + struct timeval *time) +{ + drmMMListHead *list, *next; + struct _DriKernelBO *kbo; + + if (!driTimeAfterEq(time, &fMan->nextCheck)) + return; + + for (list = fMan->timeoutList.next, next = list->next; + list != &fMan->timeoutList; + list = next, next = list->next) { + + kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); + + if (!driTimeAfterEq(time, &kbo->timeFreed)) + break; + + DRMLISTDELINIT(&kbo->timeoutHead); + DRMLISTDELINIT(&kbo->head); + driFreeKernelBO(kbo); + } + + fMan->nextCheck = *time; + driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); +} + + +/* + * Add a _DriKernelBO to the free slab manager. + * This means that it is available for reuse, but if it's not + * reused in a while, it will be freed. + */ + +static void +driSetKernelBOFree(struct _DriFreeSlabManager *fMan, + struct _DriKernelBO *kbo) +{ + struct timeval time; + + _glthread_LOCK_MUTEX(fMan->mutex); + gettimeofday(&time, NULL); + driTimeAdd(&time, &fMan->slabTimeout); + + kbo->timeFreed = time; + + if (kbo->bo.flags & DRM_BO_FLAG_CACHED) + DRMLISTADD(&kbo->head, &fMan->cached); + else + DRMLISTADD(&kbo->head, &fMan->unCached); + + DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); + driFreeTimeoutKBOsLocked(fMan, &time); + + _glthread_UNLOCK_MUTEX(fMan->mutex); +} + +/* + * Get a _DriKernelBO for us to use as storage for a slab. + * + */ + +static struct _DriKernelBO * +driAllocKernelBO(struct _DriSlabSizeHeader *header) + +{ + struct _DriSlabPool *slabPool = header->slabPool; + struct _DriFreeSlabManager *fMan = slabPool->fMan; + drmMMListHead *list, *next, *head; + uint32_t size = header->bufSize * slabPool->desiredNumBuffers; + struct _DriKernelBO *kbo; + int ret; + + /* + * FIXME: We should perhaps allow some variation in slabsize in order + * to efficiently reuse slabs. + */ + + size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; + size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); + _glthread_LOCK_MUTEX(fMan->mutex); + + kbo = NULL; + + retry: + head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? + &fMan->cached : &fMan->unCached; + + for (list = head->next, next = list->next; + list != head; + list = next, next = list->next) { + + kbo = DRMLISTENTRY(struct _DriKernelBO, list, head); + + if ((kbo->bo.size == size) && + (slabPool->pageAlignment == 0 || + (kbo->pageAlignment % slabPool->pageAlignment) == 0)) { + + DRMLISTDELINIT(&kbo->head); + DRMLISTDELINIT(&kbo->timeoutHead); + break; + } + + kbo = NULL; + } + + _glthread_UNLOCK_MUTEX(fMan->mutex); + + if (kbo) { + ret = 0; + ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, + (slabPool->proposedFlags ^ kbo->bo.flags), + DRM_BO_HINT_DONT_FENCE, 0, 0); + if (ret == 0) + return kbo; + + driFreeKernelBO(kbo); + kbo = NULL; + goto retry; + } + + kbo = calloc(1, sizeof(struct _DriKernelBO)); + if (!kbo) + return NULL; + + kbo->fd = slabPool->fd; + DRMINITLISTHEAD(&kbo->head); + DRMINITLISTHEAD(&kbo->timeoutHead); + + ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, + slabPool->proposedFlags, + DRM_BO_HINT_DONT_FENCE, &kbo->bo); + if (ret) + goto out_err0; + + ret = drmBOMap(kbo->fd, &kbo->bo, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &kbo->virtual); + + if (ret) + goto out_err1; + + ret = drmBOUnmap(kbo->fd, &kbo->bo); + if (ret) + goto out_err1; + + return kbo; + + out_err1: + drmBOUnreference(kbo->fd, &kbo->bo); + out_err0: + free(kbo); + return NULL; +} + + +static int +driAllocSlab(struct _DriSlabSizeHeader *header) +{ + struct _DriSlab *slab; + struct _DriSlabBuffer *buf; + uint32_t numBuffers; + int ret; + int i; + + slab = calloc(1, sizeof(*slab)); + if (!slab) + return -ENOMEM; + + slab->kbo = driAllocKernelBO(header); + if (!slab->kbo) { + ret = -ENOMEM; + goto out_err0; + } + + numBuffers = slab->kbo->bo.size / header->bufSize; + + slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); + if (!slab->buffers) { + ret = -ENOMEM; + goto out_err1; + } + + DRMINITLISTHEAD(&slab->head); + DRMINITLISTHEAD(&slab->freeBuffers); + slab->numBuffers = numBuffers; + slab->numFree = 0; + slab->header = header; + + buf = slab->buffers; + for (i=0; i < numBuffers; ++i) { + buf->parent = slab; + buf->start = i* header->bufSize; + buf->mapCount = 0; + buf->isSlabBuffer = 1; + _glthread_INIT_COND(buf->event); + DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); + slab->numFree++; + buf++; + } + + DRMLISTADDTAIL(&slab->head, &header->slabs); + + return 0; + + out_err1: + driSetKernelBOFree(header->slabPool->fMan, slab->kbo); + free(slab->buffers); + out_err0: + free(slab); + return ret; +} + +/* + * Delete a buffer from the slab header delayed list and put + * it on the slab free list. + */ + +static void +driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) +{ + struct _DriSlab *slab = buf->parent; + struct _DriSlabSizeHeader *header = slab->header; + drmMMListHead *list = &buf->head; + + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &slab->freeBuffers); + slab->numFree++; + + if (slab->head.next == &slab->head) + DRMLISTADDTAIL(&slab->head, &header->slabs); + + if (slab->numFree == slab->numBuffers) { + list = &slab->head; + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &header->freeSlabs); + } + + if (header->slabs.next == &header->slabs || + slab->numFree != slab->numBuffers) { + + drmMMListHead *next; + struct _DriFreeSlabManager *fMan = header->slabPool->fMan; + + for (list = header->freeSlabs.next, next = list->next; + list != &header->freeSlabs; + list = next, next = list->next) { + + slab = DRMLISTENTRY(struct _DriSlab, list, head); + + DRMLISTDELINIT(list); + driSetKernelBOFree(fMan, slab->kbo); + free(slab->buffers); + free(slab); + } + } +} + +static void +driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) +{ + drmMMListHead *list, *prev; + struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + + int signaled = 0; + int i; + int ret; + + list = header->delayedBuffers.next; + + /* Only examine the oldest 1/3 of delayed buffers: + */ + if (header->numDelayed > 3) { + for (i = 0; i < header->numDelayed; i += 3) { + list = list->next; + } + } + + prev = list->prev; + for (; list != &header->delayedBuffers; list = prev, prev = list->prev) { + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + slab = buf->parent; + + if (!signaled) { + if (wait) { + ret = driFenceFinish(buf->fence, buf->fenceType, 0); + if (ret) + break; + signaled = 1; + } else { + signaled = driFenceSignaled(buf->fence, buf->fenceType); + } + if (signaled) { + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } +} + + +static struct _DriSlabBuffer * +driSlabAllocBuffer(struct _DriSlabSizeHeader *header) +{ + static struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + drmMMListHead *list; + int count = DRI_SLABPOOL_ALLOC_RETRIES; + + _glthread_LOCK_MUTEX(header->mutex); + while(header->slabs.next == &header->slabs && count > 0) { + driSlabCheckFreeLocked(header, 0); + if (header->slabs.next != &header->slabs) + break; + + _glthread_UNLOCK_MUTEX(header->mutex); + if (count != DRI_SLABPOOL_ALLOC_RETRIES) + usleep(1); + (void) driAllocSlab(header); + _glthread_LOCK_MUTEX(header->mutex); + count--; + } + + list = header->slabs.next; + if (list == &header->slabs) { + _glthread_UNLOCK_MUTEX(header->mutex); + //assert(0, "no buffers in slab"); + return NULL; + } + slab = DRMLISTENTRY(struct _DriSlab, list, head); + if (--slab->numFree == 0) + DRMLISTDELINIT(list); + + list = slab->freeBuffers.next; + DRMLISTDELINIT(list); + + _glthread_UNLOCK_MUTEX(header->mutex); + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + return buf; +} + +static void * +pool_create(struct _DriBufferPool *driPool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment) +{ + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + struct _DriSlabSizeHeader *header; + struct _DriSlabBuffer *buf; + void *dummy; + int i; + int ret; + + + /* + * FIXME: Check for compatibility. + */ + + header = pool->headers; + for (i=0; inumBuckets; ++i) { + if (header->bufSize >= size) + break; + header++; + } + + if (i < pool->numBuckets) + return driSlabAllocBuffer(header); + + + /* + * Fall back to allocate a buffer object directly from DRM. + * and wrap it in a driBO structure. + */ + + + buf = calloc(1, sizeof(*buf)); + + if (!buf) + return NULL; + + buf->bo = calloc(1, sizeof(*buf->bo)); + if (!buf->bo) + goto out_err0; + + if (alignment) { + if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) + goto out_err1; + if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) + goto out_err1; + } + + ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, + flags, hint, buf->bo); + if (ret) + goto out_err1; + + ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &dummy); + if (ret) + goto out_err2; + + ret = drmBOUnmap(pool->fd, buf->bo); + if (ret) + goto out_err2; + + return buf; + out_err2: + drmBOUnreference(pool->fd, buf->bo); + out_err1: + free(buf->bo); + out_err0: + free(buf); + return NULL; +} + +static int +pool_destroy(struct _DriBufferPool *driPool, void *private) +{ + struct _DriSlabBuffer *buf = + (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + int ret; + + ret = drmBOUnreference(pool->fd, buf->bo); + free(buf->bo); + free(buf); + return ret; + } + + slab = buf->parent; + header = slab->header; + + _glthread_LOCK_MUTEX(header->mutex); + buf->unFenced = 0; + buf->mapCount = 0; + + if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { + DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); + header->numDelayed++; + } else { + driSlabFreeBufferLocked(buf); + } + + _glthread_UNLOCK_MUTEX(header->mutex); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *driPool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + while(buf->unFenced) + _glthread_COND_WAIT(buf->event, *mutex); + + if (!buf->fence) + return 0; + + driFenceFinish(buf->fence, buf->fenceType, lazy); + driFenceUnReference(&buf->fence); + + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + int busy; + + if (buf->isSlabBuffer) + busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); + else + busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); + + + if (busy) { + if (hint & DRM_BO_HINT_DONT_BLOCK) + return -EBUSY; + else { + (void) pool_waitIdle(pool, private, mutex, 0); + } + } + + ++buf->mapCount; + *virtual = (buf->isSlabBuffer) ? + (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : + (void *) buf->bo->virtual; + + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + --buf->mapCount; + if (buf->mapCount == 0 && buf->isSlabBuffer) + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return buf->bo->offset; + } + + slab = buf->parent; + header = slab->header; + + (void) header; + assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return slab->kbo->bo.offset + buf->start; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return buf->start; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return buf->bo->flags; + + return buf->parent->kbo->bo.flags; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + if (!buf->isSlabBuffer) + return buf->bo->size; + + return buf->parent->header->bufSize; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + drmBO *bo; + + if (buf->fence) + driFenceUnReference(&buf->fence); + + buf->fence = driFenceReference(fence); + bo = (buf->isSlabBuffer) ? + &buf->parent->kbo->bo: + buf->bo; + buf->fenceType = bo->fenceFlags; + + buf->unFenced = 0; + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; +} + +static int +pool_validate(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return 0; + + while(buf->mapCount != 0) + _glthread_COND_WAIT(buf->event, *mutex); + + buf->unFenced = 1; + return 0; +} + + +struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) +{ + struct _DriFreeSlabManager *tmp; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; + tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; + tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; + + tmp->checkInterval.tv_usec = checkIntervalMsec*1000; + tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; + tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; + + gettimeofday(&tmp->nextCheck, NULL); + driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); + DRMINITLISTHEAD(&tmp->timeoutList); + DRMINITLISTHEAD(&tmp->unCached); + DRMINITLISTHEAD(&tmp->cached); + _glthread_UNLOCK_MUTEX(tmp->mutex); + + return tmp; +} + +void +driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) +{ + struct timeval time; + + time = fMan->nextCheck; + driTimeAdd(&time, &fMan->checkInterval); + + _glthread_LOCK_MUTEX(fMan->mutex); + driFreeTimeoutKBOsLocked(fMan, &time); + _glthread_UNLOCK_MUTEX(fMan->mutex); + + assert(fMan->timeoutList.next == &fMan->timeoutList); + assert(fMan->unCached.next == &fMan->unCached); + assert(fMan->cached.next == &fMan->cached); + + free(fMan); +} + +static void +driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, + struct _DriSlabSizeHeader *header) +{ + _glthread_INIT_MUTEX(header->mutex); + _glthread_LOCK_MUTEX(header->mutex); + + DRMINITLISTHEAD(&header->slabs); + DRMINITLISTHEAD(&header->freeSlabs); + DRMINITLISTHEAD(&header->delayedBuffers); + + header->numDelayed = 0; + header->slabPool = pool; + header->bufSize = size; + + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +driFinishSizeHeader(struct _DriSlabSizeHeader *header) +{ + drmMMListHead *list, *next; + struct _DriSlabBuffer *buf; + + _glthread_LOCK_MUTEX(header->mutex); + for (list = header->delayedBuffers.next, next = list->next; + list != &header->delayedBuffers; + list = next, next = list->next) { + + buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); + if (buf->fence) { + (void) driFenceFinish(buf->fence, buf->fenceType, 0); + driFenceUnReference(&buf->fence); + } + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +pool_takedown(struct _DriBufferPool *driPool) +{ + struct _DriSlabPool *pool = driPool->data; + int i; + + for (i=0; inumBuckets; ++i) { + driFinishSizeHeader(&pool->headers[i]); + } + + free(pool->headers); + free(pool->bucketSizes); + free(pool); + free(driPool); +} + +struct _DriBufferPool * +driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan) +{ + struct _DriBufferPool *driPool; + struct _DriSlabPool *pool; + uint32_t i; + + driPool = calloc(1, sizeof(*driPool)); + if (!driPool) + return NULL; + + pool = calloc(1, sizeof(*pool)); + if (!pool) + goto out_err0; + + pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); + if (!pool->bucketSizes) + goto out_err1; + + pool->headers = calloc(numSizes, sizeof(*pool->headers)); + if (!pool->headers) + goto out_err2; + + pool->fMan = fMan; + pool->proposedFlags = flags; + pool->validMask = validMask; + pool->numBuckets = numSizes; + pool->pageSize = getpagesize(); + pool->fd = fd; + pool->pageAlignment = pageAlignment; + pool->maxSlabSize = maxSlabSize; + pool->desiredNumBuffers = desiredNumBuffers; + + for (i=0; inumBuckets; ++i) { + pool->bucketSizes[i] = (smallestSize << i); + driInitSizeHeader(pool, pool->bucketSizes[i], + &pool->headers[i]); + } + + driPool->data = (void *) pool; + driPool->map = &pool_map; + driPool->unmap = &pool_unmap; + driPool->destroy = &pool_destroy; + driPool->offset = &pool_offset; + driPool->poolOffset = &pool_poolOffset; + driPool->flags = &pool_flags; + driPool->size = &pool_size; + driPool->create = &pool_create; + driPool->fence = &pool_fence; + driPool->kernel = &pool_kernel; + driPool->validate = &pool_validate; + driPool->waitIdle = &pool_waitIdle; + driPool->takeDown = &pool_takedown; + + return driPool; + + out_err2: + free(pool->bucketSizes); + out_err1: + free(pool); + out_err0: + free(driPool); + + return NULL; +} -- cgit v1.2.3 From 4c0f72432393e324d608474d24d20ebb465cb2ca Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Apr 2008 11:26:52 +0200 Subject: Fixed user_buffer memory leak --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 4 +++- src/gallium/winsys/dri/intel/ws_dri_bufmgr.c | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 59729a0245..40902197e1 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -156,7 +156,9 @@ intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); driGenUserBuffer( iws->regionPool, - "pipe user buffer", &buffer->driBO, ptr, bytes ); + "pipe user buffer", &buffer->driBO, ptr, bytes ); + + buffer->base.refcount = 1; return &buffer->base; } diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c index eb5216cb37..bf387f672b 100644 --- a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c +++ b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c @@ -431,7 +431,6 @@ driBOUnReference(struct _DriBufferObject *buf) if (!buf) return; - _glthread_LOCK_MUTEX(buf->mutex); tmp = --buf->refCount; if (!tmp) { -- cgit v1.2.3 From caa5b1736dd4c4ba85966fa7710c52da406b1dce Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Apr 2008 11:48:44 +0200 Subject: Added fence counter to fence manager --- src/gallium/winsys/dri/intel/ws_dri_fencemgr.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c index 8aaef1c620..1f893b47ce 100644 --- a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c +++ b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c @@ -23,6 +23,7 @@ struct _DriFenceMgr { _glthread_Mutex mutex; int refCount; drmMMListHead *heads; + int num_fences; }; struct _DriFenceObject { @@ -68,6 +69,7 @@ driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) _glthread_LOCK_MUTEX(tmp->mutex); tmp->refCount = 1; tmp->info = *info; + tmp->num_fences = 0; tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); if (!tmp->heads) goto out_err; @@ -114,9 +116,11 @@ driFenceUnReferenceLocked(struct _DriFenceObject **pFence) DRMLISTDELINIT(&fence->head); if (fence->private) mgr->info.unreference(mgr, &fence->private); + --mgr->num_fences; fence->mgr = NULL; --mgr->refCount; free(fence); + } } @@ -297,6 +301,7 @@ struct _DriFenceObject DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); fence->mgr = mgr; ++mgr->refCount; + ++mgr->num_fences; _glthread_UNLOCK_MUTEX(mgr->mutex); fence->fence_class = fence_class; fence->fence_type = fence_type; -- cgit v1.2.3 From 2dd6022e65972b0706011734b68da4e9177b05c3 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Apr 2008 15:01:16 +0200 Subject: i915: Fixed fence leak in intel_swapbuffers.c --- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 1a42389169..923b542771 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -180,7 +180,6 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, if (intel->first_swap_fence) driFenceUnReference(&intel->first_swap_fence); intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); - driFenceReference(intel->first_swap_fence); } UNLOCK_HARDWARE(intel); -- cgit v1.2.3 From 1d43a8b25513866d67b5b16ae1945d6e9d95743d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Apr 2008 17:24:33 +0200 Subject: i915: Fixed fence related problems --- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 4 +++- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 05223bf700..3a8ff5a4eb 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -386,8 +386,10 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) GLboolean was_locked = intel->locked; struct _DriFenceObject *fence; - if (used == 0) + if (used == 0) { + driFenceReference(batch->last_fence); return batch->last_fence; + } /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a * performance drain that we would like to avoid. diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index ae3e9654d3..a35825d36a 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -113,10 +113,10 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws, delta ); #else /* new */ intel_offset_relocation( intel->batch, - delta, - dri_bo( buf ), - flags, - mask ); + delta, + dri_bo( buf ), + flags, + mask ); #endif } @@ -132,9 +132,13 @@ static void intel_i915_batch_flush( struct i915_winsys *sws, struct pipe_fence_handle *pipe; } fu; + if (fence) + assert(!*fence); + fu.dri = intel_batchbuffer_flush( intel->batch ); - if (!fu.dri && fence) { + if (!fu.dri) { + assert(0); *fence = NULL; return; } @@ -143,11 +147,9 @@ static void intel_i915_batch_flush( struct i915_winsys *sws, if (fence) *fence = fu.pipe; else - iws->pws->fence_reference(iws->pws, &fu.dri, NULL); + driFenceUnReference(&fu.dri); } - -// if (0) intel_i915_batch_wait_idle( sws ); } -- cgit v1.2.3 From bd56b21adf5eafebe6df90eac12f0f9eaa9e225f Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Apr 2008 18:40:36 +0200 Subject: i915: Added debug counter to bufmgr --- src/gallium/winsys/dri/intel/ws_dri_bufmgr.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c index bf387f672b..1bc1089352 100644 --- a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c +++ b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c @@ -53,6 +53,8 @@ _glthread_DECLARE_STATIC_MUTEX(bmMutex); _glthread_DECLARE_STATIC_COND(bmCond); static int kernelReaders = 0; +static int num_buffers = 0; +static int num_user_buffers = 0; static drmBO *drmBOListBuf(void *iterator) { @@ -441,6 +443,10 @@ driBOUnReference(struct _DriBufferObject *buf) else buf->pool->destroy(buf->pool, buf->private); } + if (buf->userBuffer) + num_user_buffers--; + else + num_buffers--; free(buf); } else _glthread_UNLOCK_MUTEX(buf->mutex); @@ -633,6 +639,7 @@ driGenBuffers(struct _DriBufferPool *pool, flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + ++num_buffers; assert(pool); @@ -664,7 +671,9 @@ driGenUserBuffer(struct _DriBufferPool *pool, { const unsigned alignment = 1, flags = 0, hint = 0; + --num_buffers; /* JB: is inced in GenBuffes */ driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); + ++num_user_buffers; (*buffers)->userBuffer = 1; (*buffers)->userData = ptr; -- cgit v1.2.3 From a52faa9325db178601811f4bdad6d9747de5f238 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 9 Apr 2008 16:09:46 -0600 Subject: gallium: remove unneeded st->haveFramebufferSurfaces field. --- src/gallium/winsys/xlib/xm_api.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index a82d3c990e..0c248344b1 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -814,9 +814,6 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) mesaCtx->Const.CheckArrayBounds = GL_TRUE; #endif - /* finish up xmesa context initializations */ - c->st->haveFramebufferSurfaces = GL_TRUE; - return c; } -- cgit v1.2.3 From 5dcfc1f1b637aefbed631cc1265ce3808f2ff249 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sat, 12 Apr 2008 14:34:59 +0200 Subject: Fixed memory leak --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 40902197e1..44baa6d9fa 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -93,6 +93,7 @@ intel_buffer_destroy(struct pipe_winsys *winsys, struct pipe_buffer *buf) { driBOUnReference( dri_bo(buf) ); + FREE(buf); } -- cgit v1.2.3 From ca750dd045893ca5a9e1c33bd31528ade7bb1009 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 14 Apr 2008 17:02:02 +0200 Subject: Removed intel_ioctl it wasn't needed --- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 2 +- src/gallium/winsys/dri/intel/intel_ioctl.c | 138 ----------------------- src/gallium/winsys/dri/intel/intel_ioctl.h | 40 ------- 3 files changed, 1 insertion(+), 179 deletions(-) delete mode 100644 src/gallium/winsys/dri/intel/intel_ioctl.c delete mode 100644 src/gallium/winsys/dri/intel/intel_ioctl.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 3a8ff5a4eb..3a8591b580 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -26,7 +26,7 @@ **************************************************************************/ #include "intel_batchbuffer.h" -#include "intel_ioctl.h" +#include "intel_context.h" #include #if 0 diff --git a/src/gallium/winsys/dri/intel/intel_ioctl.c b/src/gallium/winsys/dri/intel/intel_ioctl.c deleted file mode 100644 index 3250c6b3a9..0000000000 --- a/src/gallium/winsys/dri/intel/intel_ioctl.c +++ /dev/null @@ -1,138 +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 -#include -#include -#include - -#include "mtypes.h" -#include "context.h" -#include "swrast/swrast.h" - -#include "intel_context.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_regions.h" -#include "drm.h" - -#define FILE_DEBUG_FLAG DEBUG_IOCTL - -int -intelEmitIrqLocked(struct intel_context *intel) -{ - drmI830IrqEmit ie; - int ret, seq; - - assert(((*(int *) intel->driHwLock) & ~DRM_LOCK_CONT) == - (DRM_LOCK_HELD | intel->hHWContext)); - - ie.irq_seq = &seq; - - ret = drmCommandWriteRead(intel->driFd, DRM_I830_IRQ_EMIT, - &ie, sizeof(ie)); - if (ret) { - fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret); - exit(1); - } - - DBG("%s --> %d\n", __FUNCTION__, seq); - - return seq; -} - -void -intelWaitIrq(struct intel_context *intel, int seq) -{ - int ret; - - DBG("%s %d\n", __FUNCTION__, seq); - - intel->iw.irq_seq = seq; - - do { - ret = - drmCommandWrite(intel->driFd, DRM_I830_IRQ_WAIT, &intel->iw, - sizeof(intel->iw)); - } while (ret == -EAGAIN || ret == -EINTR); - - if (ret) { - fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret); - exit(1); - } -} - - -void -intel_batch_ioctl(struct intel_context *intel, - GLuint start_offset, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock) -{ - drmI830BatchBuffer batch; - - assert(intel->locked); - assert(used); - - DBG("%s used %d offset %x..%x ignore_cliprects %d\n", - __FUNCTION__, - used, start_offset, start_offset + used, ignore_cliprects); - - /* Throw away non-effective packets. Won't work once we have - * hardware contexts which would preserve statechanges beyond a - * single buffer. - */ - - - - batch.start = start_offset; - batch.used = used; - batch.cliprects = intel->pClipRects; - batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; - batch.DR1 = 0; - batch.DR4 = ((((GLuint) intel->drawX) & 0xffff) | - (((GLuint) intel->drawY) << 16)); - - DBG("%s: 0x%x..0x%x DR4: %x cliprects: %d\n", - __FUNCTION__, - batch.start, - batch.start + batch.used * 4, batch.DR4, batch.num_cliprects); - - if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch, - sizeof(batch))) { - fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); - UNLOCK_HARDWARE(intel); - exit(1); - } - - /* FIXME: use hardware contexts to avoid 'losing' hardware after - * each buffer flush. - */ - intel->vtbl.lost_hardware(intel); -} diff --git a/src/gallium/winsys/dri/intel/intel_ioctl.h b/src/gallium/winsys/dri/intel/intel_ioctl.h deleted file mode 100644 index e8d07de893..0000000000 --- a/src/gallium/winsys/dri/intel/intel_ioctl.h +++ /dev/null @@ -1,40 +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. - * - **************************************************************************/ - -#ifndef INTEL_IOCTL_H -#define INTEL_IOCTL_H - -#include "intel_context.h" - -void intelWaitIrq(struct intel_context *intel, int seq); -int intelEmitIrqLocked(struct intel_context *intel); - -void intel_batch_ioctl(struct intel_context *intel, - GLuint start_offset, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock); -#endif -- cgit v1.2.3 From f2ee51e7d9a9bde8fd7de29b382d11fe0d58226d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 15 Apr 2008 12:08:36 +0200 Subject: i915: Changed name to i915_dri.so --- src/gallium/winsys/dri/intel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index f140939248..c0ce2f927b 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -2,7 +2,7 @@ TOP = ../../../../.. include $(TOP)/configs/current -LIBNAME = i915tex_dri.so +LIBNAME = i915_dri.so MINIGLX_SOURCES = server/intel_dri.c -- cgit v1.2.3 From d07ed9216cc7033fecb5bce661bbaf79189bb391 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 11:01:56 +0100 Subject: xlib: implement SP_NO_RAST env var --- src/gallium/winsys/xlib/xm_winsys.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 9a20bdfb69..5a424d0ac7 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -84,6 +84,7 @@ struct xmesa_surface struct pipe_surface surface; int tileSize; + boolean no_swap; }; @@ -252,6 +253,9 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) const struct xmesa_surface *xm_surf = xmesa_surface((struct pipe_surface *) surf); + if (xm_surf->no_swap) + return; + if (xm_surf->tileSize) { xmesa_display_surface_tiled(b, surf); return; @@ -529,6 +533,13 @@ static struct pipe_surface * xm_surface_alloc(struct pipe_winsys *ws) { struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface); + static boolean no_swap = 0; + static boolean firsttime = 1; + + if (firsttime) { + no_swap = getenv("SP_NO_RAST") != NULL; + firsttime = 0; + } assert(ws); @@ -540,7 +551,9 @@ xm_surface_alloc(struct pipe_winsys *ws) xms->tileSize = 32; /** probably temporary */ } #endif - + + xms->no_swap = no_swap; + return &xms->surface; } -- cgit v1.2.3 From 6a9f6625b38c3669769568d122958993f4a8d5b3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 11:15:51 +0100 Subject: xlib: shortcircuit no-op makecurrent --- src/gallium/winsys/xlib/fakeglx.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c index 902a755075..6e04cb4117 100644 --- a/src/gallium/winsys/xlib/fakeglx.c +++ b/src/gallium/winsys/xlib/fakeglx.c @@ -1504,6 +1504,13 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, #endif } + if (MakeCurrent_PrevContext == ctx && + MakeCurrent_PrevDrawable == draw && + MakeCurrent_PrevReadable == read && + MakeCurrent_PrevDrawBuffer == drawBuffer && + MakeCurrent_PrevReadBuffer == readBuffer) + return True; + MakeCurrent_PrevContext = ctx; MakeCurrent_PrevDrawable = draw; MakeCurrent_PrevReadable = read; -- cgit v1.2.3 From 6b4798b9068b58a3c4581a268727ce01680d08cd Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 22 Apr 2008 22:23:22 +0200 Subject: i915: Fixed weird fence leak when I915_VBUF=true --- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 923b542771..f029dd6a90 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -62,7 +62,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, } if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); + driFenceFinish(intel->last_swap_fence, driFenceType(intel->last_swap_fence), GL_FALSE); driFenceUnReference(&intel->last_swap_fence); intel->last_swap_fence = NULL; } -- cgit v1.2.3 From b0a58d526624485b98665b103fb5b507253b851b Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 23 Apr 2008 11:56:35 +0200 Subject: i915: Real fix for weird fence leak. Thanks Thomas --- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 2 +- src/gallium/winsys/dri/intel/ws_dri_slabpool.c | 109 ++++++++++++++--------- 2 files changed, 67 insertions(+), 44 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index f029dd6a90..923b542771 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -62,7 +62,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, } if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, driFenceType(intel->last_swap_fence), GL_FALSE); + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); driFenceUnReference(&intel->last_swap_fence); intel->last_swap_fence = NULL; } diff --git a/src/gallium/winsys/dri/intel/ws_dri_slabpool.c b/src/gallium/winsys/dri/intel/ws_dri_slabpool.c index 235f0ac972..62d82bbd94 100644 --- a/src/gallium/winsys/dri/intel/ws_dri_slabpool.c +++ b/src/gallium/winsys/dri/intel/ws_dri_slabpool.c @@ -227,6 +227,7 @@ driAllocKernelBO(struct _DriSlabSizeHeader *header) drmMMListHead *list, *next, *head; uint32_t size = header->bufSize * slabPool->desiredNumBuffers; struct _DriKernelBO *kbo; + struct _DriKernelBO *kboTmp; int ret; /* @@ -248,27 +249,36 @@ driAllocKernelBO(struct _DriSlabSizeHeader *header) list != head; list = next, next = list->next) { - kbo = DRMLISTENTRY(struct _DriKernelBO, list, head); + kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); - if ((kbo->bo.size == size) && + if ((kboTmp->bo.size == size) && (slabPool->pageAlignment == 0 || - (kbo->pageAlignment % slabPool->pageAlignment) == 0)) { + (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { + + if (!kbo) + kbo = kboTmp; + + if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) + break; - DRMLISTDELINIT(&kbo->head); - DRMLISTDELINIT(&kbo->timeoutHead); - break; } + } - kbo = NULL; + if (kbo) { + DRMLISTDELINIT(&kbo->head); + DRMLISTDELINIT(&kbo->timeoutHead); } _glthread_UNLOCK_MUTEX(fMan->mutex); if (kbo) { + uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; + ret = 0; - ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, - (slabPool->proposedFlags ^ kbo->bo.flags), - DRM_BO_HINT_DONT_FENCE, 0, 0); + if (new_mask) { + ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, + new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); + } if (ret == 0) return kbo; @@ -284,7 +294,6 @@ driAllocKernelBO(struct _DriSlabSizeHeader *header) kbo->fd = slabPool->fd; DRMINITLISTHEAD(&kbo->head); DRMINITLISTHEAD(&kbo->timeoutHead); - ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, slabPool->proposedFlags, DRM_BO_HINT_DONT_FENCE, &kbo->bo); @@ -417,47 +426,61 @@ driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) static void driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) { - drmMMListHead *list, *prev; + drmMMListHead *list, *prev, *first; struct _DriSlabBuffer *buf; struct _DriSlab *slab; - - int signaled = 0; + int firstWasSignaled = 1; + int signaled; int i; int ret; - list = header->delayedBuffers.next; - - /* Only examine the oldest 1/3 of delayed buffers: + /* + * Rerun the freeing test if the youngest tested buffer + * was signaled, since there might be more idle buffers + * in the delay list. */ - if (header->numDelayed > 3) { - for (i = 0; i < header->numDelayed; i += 3) { - list = list->next; - } - } - prev = list->prev; - for (; list != &header->delayedBuffers; list = prev, prev = list->prev) { - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - slab = buf->parent; - - if (!signaled) { - if (wait) { - ret = driFenceFinish(buf->fence, buf->fenceType, 0); - if (ret) - break; - signaled = 1; - } else { - signaled = driFenceSignaled(buf->fence, buf->fenceType); + while (firstWasSignaled) { + firstWasSignaled = 0; + signaled = 0; + first = header->delayedBuffers.next; + + /* Only examine the oldest 1/3 of delayed buffers: + */ + if (header->numDelayed > 3) { + for (i = 0; i < header->numDelayed; i += 3) { + first = first->next; } - if (signaled) { + } + + for (list = first, prev = list->prev; + list != &header->delayedBuffers; + list = prev, prev = list->prev) { + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + slab = buf->parent; + + if (!signaled) { + if (wait) { + ret = driFenceFinish(buf->fence, buf->fenceType, 0); + if (ret) + break; + signaled = 1; + wait = 0; + } else { + signaled = driFenceSignaled(buf->fence, buf->fenceType); + } + if (signaled) { + if (list == first) + firstWasSignaled = 1; + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { driFenceUnReference(&buf->fence); header->numDelayed--; driSlabFreeBufferLocked(buf); } - } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); } } } @@ -480,15 +503,14 @@ driSlabAllocBuffer(struct _DriSlabSizeHeader *header) _glthread_UNLOCK_MUTEX(header->mutex); if (count != DRI_SLABPOOL_ALLOC_RETRIES) usleep(1); - (void) driAllocSlab(header); _glthread_LOCK_MUTEX(header->mutex); + (void) driAllocSlab(header); count--; } list = header->slabs.next; if (list == &header->slabs) { _glthread_UNLOCK_MUTEX(header->mutex); - //assert(0, "no buffers in slab"); return NULL; } slab = DRMLISTENTRY(struct _DriSlab, list, head); @@ -514,7 +536,6 @@ pool_create(struct _DriBufferPool *driPool, unsigned long size, int i; int ret; - /* * FIXME: Check for compatibility. */ @@ -605,6 +626,8 @@ pool_destroy(struct _DriBufferPool *driPool, void *private) DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); header->numDelayed++; } else { + if (buf->fence) + driFenceUnReference(&buf->fence); driSlabFreeBufferLocked(buf); } -- cgit v1.2.3 From dddedd915afb58ab6b87492e850baeadc007fe47 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 24 Apr 2008 12:36:04 +0100 Subject: xlib: only shortcircuit makecurrent if NO_RAST set, otherwise window size updates fail --- src/gallium/winsys/xlib/fakeglx.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c index 6e04cb4117..ec77e81fed 100644 --- a/src/gallium/winsys/xlib/fakeglx.c +++ b/src/gallium/winsys/xlib/fakeglx.c @@ -1459,6 +1459,13 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx ) { struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + static boolean firsttime = 1, no_rast = 0; + + if (firsttime) { + no_rast = getenv("SP_NO_RAST") != NULL; + firsttime = 0; + } + if (ctx && draw && read) { XMesaBuffer drawBuffer, readBuffer; @@ -1504,7 +1511,8 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, #endif } - if (MakeCurrent_PrevContext == ctx && + if (no_rast && + MakeCurrent_PrevContext == ctx && MakeCurrent_PrevDrawable == draw && MakeCurrent_PrevReadable == read && MakeCurrent_PrevDrawBuffer == drawBuffer && -- cgit v1.2.3 From d0b2561c57763db196b45ab052a01a12fc37b06f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 25 Apr 2008 17:50:48 -0600 Subject: gallium: updated comment in xm_flush_frontbuffer() --- src/gallium/winsys/xlib/xm_winsys.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 5a424d0ac7..8a89278cde 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -296,10 +296,9 @@ xm_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, void *context_private) { - /* The Xlib driver's front color surfaces are actually X Windows so - * this flush is a no-op. - * If we instead did front buffer rendering to a temporary XImage, - * this would be the place to copy the Ximage to the on-screen Window. + /* + * The front color buffer is actually just another XImage buffer. + * This function copies that XImage to the actual X Window. */ XMesaContext xmctx = (XMesaContext) context_private; xmesa_display_surface(xmctx->xm_buffer, surf); -- cgit v1.2.3 From c9ed86a96483063f3d6789ed16645a3dca77d726 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 11:07:21 +0100 Subject: gallium: tex surface checkpoint --- src/gallium/winsys/xlib/xm_winsys.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 8a89278cde..fd2f56eff2 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -508,6 +508,7 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, surf->format = format; surf->cpp = pf_get_size(format); surf->pitch = round_up(width, alignment / surf->cpp); + surf->usage = flags; #ifdef GALLIUM_CELL /* XXX a bit of a hack */ height = round_up(height, TILE_SIZE); @@ -562,6 +563,7 @@ static void xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) { struct pipe_surface *surf = *s; + assert(!surf->texture); surf->refcount--; if (surf->refcount == 0) { if (surf->buffer) -- cgit v1.2.3 From c1abd758c51247ebaf3d4808a77513d7814205cd Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 1 May 2008 15:19:00 -0600 Subject: gallium: remove the unused softpipe_winsys code The struct is still there though until all winsys layers are updated --- src/gallium/winsys/xlib/xm_winsys.c | 81 +++++++++++-------------------------- 1 file changed, 23 insertions(+), 58 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 8a89278cde..71ba076bff 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -37,6 +37,7 @@ #include "xmesaP.h" #undef ASSERT +#undef Elements #include "pipe/p_winsys.h" #include "pipe/p_format.h" @@ -88,18 +89,6 @@ struct xmesa_surface }; -/** - * Derived from softpipe_winsys. - * We just need one extra field which indicates the pixel format to use for - * drawing surfaces so that we're compatible with the XVisual/window format. - */ -struct xmesa_softpipe_winsys -{ - struct softpipe_winsys spws; - enum pipe_format pixelformat; -}; - - struct xmesa_pipe_winsys { struct pipe_winsys base; @@ -119,12 +108,7 @@ xmesa_surface(struct pipe_surface *ps) return (struct xmesa_surface *) ps; } -/** cast wrapper */ -static INLINE struct xmesa_softpipe_winsys * -xmesa_softpipe_winsys(struct softpipe_winsys *spws) -{ - return (struct xmesa_softpipe_winsys *) spws; -} + /** * Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque @@ -525,8 +509,7 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, /** - * Called via pipe->surface_alloc() to create new surfaces (textures, - * renderbuffers, etc. + * Called via winsys->surface_alloc() to create new surfaces. */ static struct pipe_surface * xm_surface_alloc(struct pipe_winsys *ws) @@ -610,10 +593,19 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) { static struct xmesa_pipe_winsys *ws = NULL; - if (!ws && getenv("XM_AUB")) { + if (!ws) { ws = (struct xmesa_pipe_winsys *) xmesa_create_pipe_winsys_aub(); } - else if (!ws) { + return &ws->base; +} + + +struct pipe_winsys * +xmesa_get_pipe_winsys(struct xmesa_visual *xm_vis) +{ + static struct xmesa_pipe_winsys *ws = NULL; + + if (!ws) { ws = CALLOC_STRUCT(xmesa_pipe_winsys); ws->xm_visual = xm_vis; @@ -644,45 +636,19 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) } -/** - * Called via softpipe_winsys->is_format_supported(). - * This function is only called to test formats for front/back color surfaces. - * The winsys being queried will have been created at glXCreateContext - * time, with a pixel format corresponding to the context's visual. - */ -static boolean -xmesa_is_format_supported(struct softpipe_winsys *sws, - enum pipe_format format) -{ - struct xmesa_softpipe_winsys *xmws = xmesa_softpipe_winsys(sws); - return (format == xmws->pixelformat); -} - - -/** - * Return pointer to a softpipe_winsys object. - */ -static struct softpipe_winsys * -xmesa_get_softpipe_winsys(uint pixelformat) -{ - struct xmesa_softpipe_winsys *xmws - = CALLOC_STRUCT(xmesa_softpipe_winsys); - if (!xmws) - return NULL; - - xmws->spws.is_format_supported = xmesa_is_format_supported; - xmws->pixelformat = pixelformat; - - return &xmws->spws; -} - - struct pipe_context * xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) { - struct pipe_winsys *pws = xmesa_get_pipe_winsys_aub(xmesa->xm_visual); + struct pipe_winsys *pws; struct pipe_context *pipe; + if (getenv("XM_AUB")) { + pws = xmesa_get_pipe_winsys_aub(xmesa->xm_visual); + } + else { + pws = xmesa_get_pipe_winsys(xmesa->xm_visual); + } + #ifdef GALLIUM_CELL if (!getenv("GALLIUM_NOCELL")) { struct cell_winsys *cws = cell_get_winsys(pixelformat); @@ -693,10 +659,9 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) else #endif { - struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(pixelformat); struct pipe_screen *screen = softpipe_create_screen(pws); - pipe = softpipe_create(screen, pws, spws); + pipe = softpipe_create(screen, pws, NULL); } if (pipe) -- cgit v1.2.3 From 8a5bf456dcb84b315152b87e33c8736248ad0a46 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 1 May 2008 15:29:25 -0600 Subject: gallium: comments, clean-ups --- src/gallium/winsys/xlib/xm_winsys.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 71ba076bff..51b247ffc3 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -58,6 +58,7 @@ /** + * Subclass of pipe_buffer for Xlib winsys. * Low-level OS/window system memory buffer */ struct xm_buffer @@ -80,6 +81,10 @@ struct xm_buffer # define XSHM_ENABLED(b) 0 #endif + +/** + * Subclass of pipe_surface for Xlib winsys + */ struct xmesa_surface { struct pipe_surface surface; @@ -89,6 +94,9 @@ struct xmesa_surface }; +/** + * Subclass of pipe_winsys for Xlib winsys + */ struct xmesa_pipe_winsys { struct pipe_winsys base; @@ -100,11 +108,11 @@ struct xmesa_pipe_winsys static void alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, unsigned width, unsigned height); + /** Cast wrapper */ static INLINE struct xmesa_surface * xmesa_surface(struct pipe_surface *ps) { -// assert(0); return (struct xmesa_surface *) ps; } -- cgit v1.2.3 From e9513bd403c0ba0b004d2414fda6736b38cecfd5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 2 May 2008 07:54:11 -0600 Subject: gallium: code movement (XSHM code) --- src/gallium/winsys/xlib/xm_winsys.c | 252 ++++++++++++++++++------------------ 1 file changed, 125 insertions(+), 127 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 51b247ffc3..641ec11652 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -75,12 +75,6 @@ struct xm_buffer #endif }; -#if defined(USE_XSHM) && !defined(XFree86Server) -# define XSHM_ENABLED(b) ((b)->shm) -#else -# define XSHM_ENABLED(b) 0 -#endif - /** * Subclass of pipe_surface for Xlib winsys @@ -105,9 +99,6 @@ struct xmesa_pipe_winsys }; -static void alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, - unsigned width, unsigned height); - /** Cast wrapper */ static INLINE struct xmesa_surface * @@ -117,11 +108,7 @@ xmesa_surface(struct pipe_surface *ps) } - -/** - * Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque - * buffer pointer... - */ +/** Cast wrapper */ static INLINE struct xm_buffer * xm_buffer( struct pipe_buffer *buf ) { @@ -129,6 +116,130 @@ xm_buffer( struct pipe_buffer *buf ) } +/** + * X Shared Memory Image extension code + */ +#if defined(USE_XSHM) && !defined(XFree86Server) + +#define XSHM_ENABLED(b) ((b)->shm) + +static volatile int mesaXErrorFlag = 0; + +/** + * Catches potential Xlib errors. + */ +static int +mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event) +{ + (void) dpy; + (void) event; + mesaXErrorFlag = 1; + return 0; +} + + +static GLboolean alloc_shm(struct xm_buffer *buf, unsigned size) +{ + XShmSegmentInfo *const shminfo = & buf->shminfo; + + shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); + if (shminfo->shmid < 0) { + return GL_FALSE; + } + + shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); + if (shminfo->shmaddr == (char *) -1) { + shmctl(shminfo->shmid, IPC_RMID, 0); + return GL_FALSE; + } + + shminfo->readOnly = False; + return GL_TRUE; +} + + +/** + * Allocate a shared memory XImage back buffer for the given XMesaBuffer. + */ +static void +alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, + unsigned width, unsigned height) +{ + /* + * We have to do a _lot_ of error checking here to be sure we can + * really use the XSHM extension. It seems different servers trigger + * errors at different points if the extension won't work. Therefore + * we have to be very careful... + */ +#if 0 + GC gc; +#endif + int (*old_handler)(XMesaDisplay *, XErrorEvent *); + + b->tempImage = XShmCreateImage(xmb->xm_visual->display, + xmb->xm_visual->visinfo->visual, + xmb->xm_visual->visinfo->depth, + ZPixmap, + NULL, + &b->shminfo, + width, height); + if (b->tempImage == NULL) { + b->shm = 0; + return; + } + + + mesaXErrorFlag = 0; + old_handler = XSetErrorHandler(mesaHandleXError); + /* This may trigger the X protocol error we're ready to catch: */ + XShmAttach(xmb->xm_visual->display, &b->shminfo); + XSync(xmb->xm_visual->display, False); + + if (mesaXErrorFlag) { + /* we are on a remote display, this error is normal, don't print it */ + XFlush(xmb->xm_visual->display); + mesaXErrorFlag = 0; + XDestroyImage(b->tempImage); + b->tempImage = NULL; + b->shm = 0; + (void) XSetErrorHandler(old_handler); + return; + } + + + /* Finally, try an XShmPutImage to be really sure the extension works */ +#if 0 + gc = XCreateGC(xmb->xm_visual->display, xmb->drawable, 0, NULL); + XShmPutImage(xmb->xm_visual->display, xmb->drawable, gc, + b->tempImage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False); + XSync(xmb->xm_visual->display, False); + XFreeGC(xmb->xm_visual->display, gc); + (void) XSetErrorHandler(old_handler); + if (mesaXErrorFlag) { + XFlush(xmb->xm_visual->display); + mesaXErrorFlag = 0; + XDestroyImage(b->tempImage); + b->tempImage = NULL; + b->shm = 0; + return; + } +#endif +} + +#else + +#define XSHM_ENABLED(b) 0 + +static void +alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, + unsigned width, unsigned height) +{ + b->shm = 0; +} +#endif /* USE_XSHM */ + + + /* Most callbacks map direcly onto dri_bufmgr operations: */ @@ -305,119 +416,6 @@ xm_get_name(struct pipe_winsys *pws) } -#if defined(USE_XSHM) && !defined(XFree86Server) -static volatile int mesaXErrorFlag = 0; - -/** - * Catches potential Xlib errors. - */ -static int -mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event) -{ - (void) dpy; - (void) event; - mesaXErrorFlag = 1; - return 0; -} - - -static GLboolean alloc_shm(struct xm_buffer *buf, unsigned size) -{ - XShmSegmentInfo *const shminfo = & buf->shminfo; - - shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); - if (shminfo->shmid < 0) { - return GL_FALSE; - } - - shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); - if (shminfo->shmaddr == (char *) -1) { - shmctl(shminfo->shmid, IPC_RMID, 0); - return GL_FALSE; - } - - shminfo->readOnly = False; - return GL_TRUE; -} - - -/** - * Allocate a shared memory XImage back buffer for the given XMesaBuffer. - */ -static void -alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, - unsigned width, unsigned height) -{ - /* - * We have to do a _lot_ of error checking here to be sure we can - * really use the XSHM extension. It seems different servers trigger - * errors at different points if the extension won't work. Therefore - * we have to be very careful... - */ -#if 0 - GC gc; -#endif - int (*old_handler)(XMesaDisplay *, XErrorEvent *); - - b->tempImage = XShmCreateImage(xmb->xm_visual->display, - xmb->xm_visual->visinfo->visual, - xmb->xm_visual->visinfo->depth, - ZPixmap, - NULL, - &b->shminfo, - width, height); - if (b->tempImage == NULL) { - b->shm = 0; - return; - } - - - mesaXErrorFlag = 0; - old_handler = XSetErrorHandler(mesaHandleXError); - /* This may trigger the X protocol error we're ready to catch: */ - XShmAttach(xmb->xm_visual->display, &b->shminfo); - XSync(xmb->xm_visual->display, False); - - if (mesaXErrorFlag) { - /* we are on a remote display, this error is normal, don't print it */ - XFlush(xmb->xm_visual->display); - mesaXErrorFlag = 0; - XDestroyImage(b->tempImage); - b->tempImage = NULL; - b->shm = 0; - (void) XSetErrorHandler(old_handler); - return; - } - - - /* Finally, try an XShmPutImage to be really sure the extension works */ -#if 0 - gc = XCreateGC(xmb->xm_visual->display, xmb->drawable, 0, NULL); - XShmPutImage(xmb->xm_visual->display, xmb->drawable, gc, - b->tempImage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False); - XSync(xmb->xm_visual->display, False); - XFreeGC(xmb->xm_visual->display, gc); - (void) XSetErrorHandler(old_handler); - if (mesaXErrorFlag) { - XFlush(xmb->xm_visual->display); - mesaXErrorFlag = 0; - XDestroyImage(b->tempImage); - b->tempImage = NULL; - b->shm = 0; - return; - } -#endif -} -#else -static void -alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, - unsigned width, unsigned height) -{ - b->shm = 0; -} -#endif - - static struct pipe_buffer * xm_buffer_create(struct pipe_winsys *pws, unsigned alignment, -- cgit v1.2.3 From 736f535b4f1c5e6912b5b2fe9415a3b44a678844 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 3 May 2008 09:26:25 -0600 Subject: gallium: fix warnings --- src/gallium/winsys/xlib/xm_winsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 641ec11652..14c3892559 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -606,7 +606,7 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) } -struct pipe_winsys * +static struct pipe_winsys * xmesa_get_pipe_winsys(struct xmesa_visual *xm_vis) { static struct xmesa_pipe_winsys *ws = NULL; -- cgit v1.2.3 From c7ad942c54c3892a98d248a15af817f256260e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 7 May 2008 14:17:59 +0900 Subject: gallium: Propagate tex_usage flags down to winsys. --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 3 ++- src/gallium/winsys/xlib/xm_winsys.c | 3 ++- src/gallium/winsys/xlib/xm_winsys_aub.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 77dec9488d..d15143acfd 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -206,7 +206,8 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags) + unsigned flags, + unsigned tex_usage) { const unsigned alignment = 64; int ret; diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index a70752428a..b14758f333 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -489,7 +489,8 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags) + unsigned flags, + unsigned tex_usage) { const unsigned alignment = 64; diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index f42f7fcc5f..77376099f0 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -276,7 +276,8 @@ aub_i915_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags) + unsigned flags, + unsigned tex_usage) { const unsigned alignment = 64; -- cgit v1.2.3 From fec1d215f623221cb52f22c8f10e5de99ebc9cc2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 8 May 2008 22:10:15 +0100 Subject: xlib: more SP_NO_RAST support For some resaon normal (non-display-buffer) buffers are being allocated through Xshm... Bypass at least for SP_NO_RAST --- src/gallium/winsys/xlib/fakeglx.c | 9 +++++++++ src/gallium/winsys/xlib/xm_api.c | 3 +++ 2 files changed, 12 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c index ec77e81fed..2c0075e934 100644 --- a/src/gallium/winsys/xlib/fakeglx.c +++ b/src/gallium/winsys/xlib/fakeglx.c @@ -1689,6 +1689,15 @@ static void Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) { XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); + static boolean firsttime = 1, no_rast = 0; + + if (firsttime) { + no_rast = getenv("SP_NO_RAST") != NULL; + firsttime = 0; + } + + if (no_rast) + return; if (buffer) { XMesaSwapBuffers(buffer); diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 0c248344b1..26b722f343 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -110,6 +110,9 @@ int xmesa_check_for_xshm( XMesaDisplay *display ) int major, minor, ignore; Bool pixmaps; + if (getenv("SP_NO_RAST")) + return 0; + if (getenv("MESA_NOSHM")) { return 0; } -- cgit v1.2.3 From 2258f6b437705860912be300e728efbde60e2140 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 12 May 2008 14:09:50 +0100 Subject: xlib: add failure paths for context creation --- src/gallium/winsys/xlib/xm_api.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 26b722f343..8a32c54349 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -797,8 +797,14 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) pipe = xmesa_create_i965simple(xmesa_get_pipe_winsys_aub(v)); } + if (pipe == NULL) + goto fail; + c->st = st_create_context(pipe, &v->mesa_visual, share_list ? share_list->st : NULL); + if (c->st == NULL) + goto fail; + mesaCtx = c->st->ctx; c->st->ctx->DriverCtx = c; @@ -818,6 +824,14 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) #endif return c; + + fail: + if (c->st) + st_destroy_context(c->st); + if (pipe) + pipe->destroy(pipe); + FREE(c); + return NULL; } -- cgit v1.2.3 From 83e6df12ea31ef48d251fe7b38acd882145f8f14 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 May 2008 12:01:08 +1000 Subject: nouveau: chipset is a device property, remove from nv/nvc. --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 36 ++++++++++-------------- src/gallium/winsys/dri/nouveau/nouveau_context.h | 5 ---- src/gallium/winsys/dri/nouveau/nouveau_device.c | 13 +++++++++ src/gallium/winsys/dri/nouveau/nouveau_device.h | 1 + src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 8 ++++-- src/gallium/winsys/dri/nouveau/nv04_surface.c | 15 +++++----- 6 files changed, 41 insertions(+), 37 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index ff08a870db..e65b057335 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -43,7 +43,7 @@ nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) } static struct nouveau_channel_context * -nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) +nouveau_channel_context_create(struct nouveau_device *dev) { struct nouveau_channel_context *nvc; int ret; @@ -51,9 +51,8 @@ nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) nvc = CALLOC_STRUCT(nouveau_channel_context); if (!nvc) return NULL; - nvc->chipset = chipset; - if ((ret = nouveau_channel_alloc(nvdev, 0x8003d001, 0x8003d002, + if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002, &nvc->channel))) { NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); nouveau_channel_context_destroy(nvc); @@ -75,7 +74,7 @@ nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) return NULL; } - switch (chipset & 0xf0) { + switch (dev->chipset & 0xf0) { case 0x50: case 0x80: case 0x90: @@ -103,25 +102,17 @@ nouveau_context_create(const __GLcontextModes *glVis, __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv; struct nouveau_screen *nv_screen = driScrnPriv->private; struct nouveau_context *nv = CALLOC_STRUCT(nouveau_context); - struct nouveau_device_priv *nvdev; struct pipe_context *pipe = NULL; struct st_context *st_share = NULL; struct nouveau_channel_context *nvc = NULL; + struct nouveau_device *dev = nv_screen->device; int i, ret; if (sharedContextPrivate) { st_share = ((struct nouveau_context *)sharedContextPrivate)->st; } - /* Check for supported arch */ - if ((ret = nouveau_device_get_param(nv_screen->device, - NOUVEAU_GETPARAM_CHIPSET_ID, - &nv->chipset))) { - NOUVEAU_ERR("Error determining chipset id: %d\n", ret); - return GL_FALSE; - } - - switch (nv->chipset & 0xf0) { + switch (dev->chipset & 0xf0) { case 0x10: case 0x20: /* NV10 */ @@ -136,7 +127,7 @@ nouveau_context_create(const __GLcontextModes *glVis, /* G80 */ break; default: - NOUVEAU_ERR("Unsupported chipset: NV%02x\n", (int)nv->chipset); + NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset); return GL_FALSE; } @@ -144,9 +135,12 @@ nouveau_context_create(const __GLcontextModes *glVis, nv->nv_screen = nv_screen; nv->dri_screen = driScrnPriv; - nvdev = nouveau_device(nv_screen->device); - nvdev->ctx = driContextPriv->hHWContext; - nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock; + { + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + nvdev->ctx = driContextPriv->hHWContext; + nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock; + } driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, nv->dri_screen->myNum, "nouveau"); @@ -201,7 +195,7 @@ nouveau_context_create(const __GLcontextModes *glVis, } /*XXX: temporary - disable multi-context/single-channel on pre-NV4x */ - switch (nv->chipset & 0xf0) { + switch (dev->chipset & 0xf0) { case 0x40: case 0x60: /* NV40 class */ @@ -216,7 +210,7 @@ nouveau_context_create(const __GLcontextModes *glVis, } if (!nvc) { - nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset); + nvc = nouveau_channel_context_create(dev); if (!nvc) { NOUVEAU_ERR("Failed initialising GPU context\n"); return GL_FALSE; @@ -244,7 +238,7 @@ nouveau_context_create(const __GLcontextModes *glVis, } /* Create pipe */ - switch (nv->chipset & 0xf0) { + switch (dev->chipset & 0xf0) { case 0x50: case 0x80: case 0x90: diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index 872ef93807..9872d6b691 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -21,8 +21,6 @@ struct nouveau_channel_context { unsigned nr_pctx; struct pipe_context **pctx; - unsigned chipset; - struct nouveau_channel *channel; struct nouveau_notifier *sync_notifier; @@ -47,9 +45,6 @@ struct nouveau_channel_context { struct nouveau_context { struct st_context *st; - /* Misc HW info */ - uint64_t chipset; - /* DRI stuff */ __DRIscreenPrivate *dri_screen; __DRIdrawablePrivate *dri_drawable; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_device.c b/src/gallium/winsys/dri/nouveau/nouveau_device.c index 409e4415f7..0b452fcd02 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_device.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_device.c @@ -50,6 +50,19 @@ nouveau_device_open_existing(struct nouveau_device **dev, int close, return ret; } + { + uint64_t value; + + ret = nouveau_device_get_param(&nvdev->base, + NOUVEAU_GETPARAM_CHIPSET_ID, + &value); + if (ret) { + nouveau_device_close((void *)&nvdev); + return ret; + } + nvdev->base.chipset = value; + } + *dev = &nvdev->base; return 0; } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_device.h b/src/gallium/winsys/dri/nouveau/nouveau_device.h index 744a89f74b..e25e89fedd 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_device.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_device.h @@ -24,6 +24,7 @@ #define __NOUVEAU_DEVICE_H__ struct nouveau_device { + unsigned chipset; }; #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 60fdbb8dfd..635fd478a9 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -1,6 +1,7 @@ #include "pipe/p_util.h" #include "nouveau_context.h" +#include "nouveau_screen.h" #include "nouveau_winsys_pipe.h" #include "nouveau/nouveau_winsys.h" @@ -94,11 +95,12 @@ nouveau_pipe_create(struct nouveau_context *nv) unsigned chipset); struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); struct pipe_winsys *ws; + unsigned chipset = nv->nv_screen->device->chipset; if (!nvws) return NULL; - switch (nv->chipset & 0xf0) { + switch (chipset & 0xf0) { case 0x10: case 0x20: hws_create = nv10_screen_create; @@ -120,7 +122,7 @@ nouveau_pipe_create(struct nouveau_context *nv) hw_create = nv50_create; break; default: - NOUVEAU_ERR("Unknown chipset NV%02x\n", (int)nv->chipset); + NOUVEAU_ERR("Unknown chipset NV%02x\n", chipset); return NULL; } @@ -150,7 +152,7 @@ nouveau_pipe_create(struct nouveau_context *nv) ws = nouveau_create_pipe_winsys(nv); if (!nvc->pscreen) - nvc->pscreen = hws_create(ws, nvws, nv->chipset); + nvc->pscreen = hws_create(ws, nvws, chipset); nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id); return nvc->pctx[nv->pctx_id]; } diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index f61bd1477f..dc167e4acf 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -179,7 +179,7 @@ int nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) { struct nouveau_channel *chan = nvc->channel; - unsigned class; + unsigned chipset = nvc->channel->device->chipset, class; int ret; if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, 0x39, @@ -192,8 +192,8 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); OUT_RING (chan, nvc->sync_notifier->handle); - class = nvc->chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : - NV10_CONTEXT_SURFACES_2D; + class = chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : + NV10_CONTEXT_SURFACES_2D; if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, &nvc->NvCtxSurf2D))) { NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); @@ -205,8 +205,7 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) OUT_RING (chan, nvc->channel->vram->handle); OUT_RING (chan, nvc->channel->vram->handle); - class = nvc->chipset < 0x10 ? NV04_IMAGE_BLIT : - NV12_IMAGE_BLIT; + class = chipset < 0x10 ? NV04_IMAGE_BLIT : NV12_IMAGE_BLIT; if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, &nvc->NvImageBlit))) { NOUVEAU_ERR("Error creating blit object: %d\n", ret); @@ -237,7 +236,7 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); - switch (nvc->chipset & 0xf0) { + switch (chipset & 0xf0) { case 0x00: case 0x10: class = NV04_SWIZZLED_SURFACE; @@ -267,10 +266,10 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); - if (nvc->chipset < 0x10) { + if (chipset < 0x10) { class = NV04_SCALED_IMAGE_FROM_MEMORY; } else - if (nvc->chipset < 0x40) { + if (chipset < 0x40) { class = NV10_SCALED_IMAGE_FROM_MEMORY; } else { class = NV40_SCALED_IMAGE_FROM_MEMORY; -- cgit v1.2.3 From c962ad7cd5dbea12d13997b421a44b16af3c6662 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 May 2008 12:06:32 +1000 Subject: nouveau: create objnull during channel creation --- src/gallium/winsys/dri/nouveau/nouveau_channel.c | 8 ++++++++ src/gallium/winsys/dri/nouveau/nouveau_context.c | 7 ------- src/gallium/winsys/dri/nouveau/nouveau_context.h | 1 - src/gallium/winsys/dri/nouveau/nouveau_grobj.c | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_channel.c b/src/gallium/winsys/dri/nouveau/nouveau_channel.c index df80d04add..3b4dcd1ecf 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_channel.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_channel.c @@ -85,6 +85,13 @@ nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, return ret; } + ret = nouveau_grobj_alloc(&nvchan->base, 0x00000000, 0x0030, + &nvchan->base.nullobj); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + nouveau_dma_channel_init(&nvchan->base); nouveau_pushbuf_init(&nvchan->base); @@ -109,6 +116,7 @@ nouveau_channel_free(struct nouveau_channel **chan) nouveau_grobj_free(&nvchan->base.vram); nouveau_grobj_free(&nvchan->base.gart); + nouveau_grobj_free(&nvchan->base.nullobj); cf.channel = nvchan->drm.channel; drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf)); diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index e65b057335..d9fc3f6ce1 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -26,7 +26,6 @@ int __nouveau_debug = 0; static void nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) { - nouveau_grobj_free(&nvc->NvNull); nouveau_grobj_free(&nvc->NvCtxSurf2D); nouveau_grobj_free(&nvc->NvImageBlit); nouveau_grobj_free(&nvc->NvGdiRect); @@ -59,12 +58,6 @@ nouveau_channel_context_create(struct nouveau_device *dev) return NULL; } - if ((ret = nouveau_grobj_alloc(nvc->channel, 0x00000000, 0x30, - &nvc->NvNull))) { - NOUVEAU_ERR("Error creating NULL object: %d\n", ret); - nouveau_channel_context_destroy(nvc); - return NULL; - } nvc->next_handle = 0x80000000; if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index 9872d6b691..b20107a94c 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -26,7 +26,6 @@ struct nouveau_channel_context { struct nouveau_notifier *sync_notifier; /* Common */ - struct nouveau_grobj *NvNull; struct nouveau_grobj *NvM2MF; /* NV04-NV40 */ struct nouveau_grobj *NvCtxSurf2D; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_grobj.c b/src/gallium/winsys/dri/nouveau/nouveau_grobj.c index 55dfeb99aa..51523897d5 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_grobj.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_grobj.c @@ -50,7 +50,7 @@ nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle, ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GROBJ_ALLOC, &g, sizeof(g)); if (ret) { - nouveau_grobj_free((void *)&grobj); + nouveau_grobj_free((void *)&nvgrobj); return ret; } -- cgit v1.2.3 From 2f80d4d2a705835b272cf2274ea578fe5bbe1919 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 May 2008 12:09:04 +1000 Subject: nouveau: make nouveau_device.h part of public API --- src/gallium/winsys/dri/nouveau/nouveau_context.h | 1 - src/gallium/winsys/dri/nouveau/nouveau_device.h | 30 ---------------------- src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 2 +- src/gallium/winsys/dri/nouveau/nouveau_screen.c | 1 - src/gallium/winsys/dri/nouveau/nouveau_screen.h | 1 - .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 1 - 6 files changed, 1 insertion(+), 35 deletions(-) delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_device.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index b20107a94c..77e2147a2c 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -5,7 +5,6 @@ #include "xmlconfig.h" #include "nouveau/nouveau_winsys.h" -#include "nouveau_device.h" #include "nouveau_drmif.h" #include "nouveau_dma.h" diff --git a/src/gallium/winsys/dri/nouveau/nouveau_device.h b/src/gallium/winsys/dri/nouveau/nouveau_device.h deleted file mode 100644 index e25e89fedd..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_device.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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. - */ - -#ifndef __NOUVEAU_DEVICE_H__ -#define __NOUVEAU_DEVICE_H__ - -struct nouveau_device { - unsigned chipset; -}; - -#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h index d5a0e25b57..a31c9a514b 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -27,7 +27,7 @@ #include #include -#include "nouveau_device.h" +#include "nouveau/nouveau_device.h" #include "nouveau/nouveau_channel.h" #include "nouveau/nouveau_grobj.h" #include "nouveau/nouveau_notifier.h" diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c index f06e178483..9041275a88 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -7,7 +7,6 @@ #include "state_tracker/st_cb_fbo.h" #include "nouveau_context.h" -#include "nouveau_device.h" #include "nouveau_drm.h" #include "nouveau_dri.h" #include "nouveau_local.h" diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.h b/src/gallium/winsys/dri/nouveau/nouveau_screen.h index e9da202690..388d6be9bb 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.h @@ -2,7 +2,6 @@ #define __NOUVEAU_SCREEN_H__ #include "xmlconfig.h" -#include "nouveau_device.h" struct nouveau_screen { __DRIscreenPrivate *driScrnPriv; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index 849e38d22b..755c8b6997 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -4,7 +4,6 @@ #include "pipe/p_inlines.h" #include "nouveau_context.h" -#include "nouveau_device.h" #include "nouveau_local.h" #include "nouveau_screen.h" #include "nouveau_swapbuffers.h" -- cgit v1.2.3 From 1ef08564d2a201a422db772a6bb23d1129888304 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 May 2008 12:16:35 +1000 Subject: nouveau: remove chipset fields in all nv pipe driver context/screen structs. --- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 635fd478a9..5eabbc8893 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -91,8 +91,7 @@ nouveau_pipe_create(struct nouveau_context *nv) struct nouveau_channel_context *nvc = nv->nvc; struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); struct pipe_screen *(*hws_create)(struct pipe_winsys *, - struct nouveau_winsys *, - unsigned chipset); + struct nouveau_winsys *); struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); struct pipe_winsys *ws; unsigned chipset = nv->nv_screen->device->chipset; @@ -152,7 +151,7 @@ nouveau_pipe_create(struct nouveau_context *nv) ws = nouveau_create_pipe_winsys(nv); if (!nvc->pscreen) - nvc->pscreen = hws_create(ws, nvws, chipset); + nvc->pscreen = hws_create(ws, nvws); nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id); return nvc->pctx[nv->pctx_id]; } -- cgit v1.2.3 From 666ac923f016b1b231c5a8847cbe084321f697ca Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 14 May 2008 00:25:09 +1000 Subject: nouveau: remove winsys-related stuff from nouveau_local.h --- src/gallium/winsys/dri/nouveau/nouveau_local.h | 21 +++++++-------- src/gallium/winsys/dri/nouveau/nv04_surface.c | 36 ++++++++++++++------------ src/gallium/winsys/dri/nouveau/nv50_surface.c | 21 ++++++++------- 3 files changed, 42 insertions(+), 36 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_local.h b/src/gallium/winsys/dri/nouveau/nouveau_local.h index 8a52f26714..e878a40803 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_local.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_local.h @@ -74,45 +74,44 @@ BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc) } static INLINE void -OUT_RELOC(struct nouveau_channel *chan, struct pipe_buffer *buf, +OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo, unsigned data, unsigned flags, unsigned vor, unsigned tor) { - nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, - nouveau_buffer(buf)->bo, + nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, data, flags, vor, tor); } /* Raw data + flags depending on FB/TT buffer */ static INLINE void -OUT_RELOCd(struct nouveau_channel *chan, struct pipe_buffer *buf, +OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo, unsigned data, unsigned flags, unsigned vor, unsigned tor) { - OUT_RELOC(chan, buf, data, flags | NOUVEAU_BO_OR, vor, tor); + OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor); } /* FB/TT object handle */ static INLINE void -OUT_RELOCo(struct nouveau_channel *chan, struct pipe_buffer *buf, +OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo, unsigned flags) { - OUT_RELOC(chan, buf, 0, flags | NOUVEAU_BO_OR, + OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR, chan->vram->handle, chan->gart->handle); } /* Low 32-bits of offset */ static INLINE void -OUT_RELOCl(struct nouveau_channel *chan, struct pipe_buffer *buf, +OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo, unsigned delta, unsigned flags) { - OUT_RELOC(chan, buf, delta, flags | NOUVEAU_BO_LOW, 0, 0); + OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0); } /* High 32-bits of offset */ static INLINE void -OUT_RELOCh(struct nouveau_channel *chan, struct pipe_buffer *buf, +OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo, unsigned delta, unsigned flags) { - OUT_RELOC(chan, buf, delta, flags | NOUVEAU_BO_HIGH, 0, 0); + OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); } #endif diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index dc167e4acf..83c790db17 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -43,10 +43,10 @@ nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, BEGIN_RING(chan, nv->nvc->NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RELOCl(chan, src->buffer, src_offset, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(chan, dst->buffer, dst_offset, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART | NOUVEAU_BO_WR); + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src_offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst_offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); OUT_RING (chan, src->pitch * src->cpp); OUT_RING (chan, dst->pitch * dst->cpp); OUT_RING (chan, w * src->cpp); @@ -88,10 +88,10 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, if ((src->offset & 63) || (dst->offset & 63)) { BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); - OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_GART | - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_GART | - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); nv->surface_copy = nv04_surface_copy_m2mf; nv->surf_dst = dst; @@ -108,17 +108,19 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); OUT_RING (chan, format); OUT_RING (chan, ((dst->pitch * dst->cpp) << 16) | (src->pitch * src->cpp)); - OUT_RELOCl(chan, src->buffer, src->offset, + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, dst->buffer, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); return 0; @@ -151,15 +153,17 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, } BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); OUT_RING (chan, cs2d_format); OUT_RING (chan, ((dst->pitch * dst->cpp) << 16) | (dst->pitch * dst->cpp)); - OUT_RELOCl(chan, dst->buffer, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, dst->buffer, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c index 5c6733e44a..d6da116b77 100644 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -29,8 +29,10 @@ nv50_surface_copy_prep(struct nouveau_context *nv, assert(surf_format >= 0); BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2); - OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); OUT_RING (chan, surf_format); @@ -39,9 +41,9 @@ nv50_surface_copy_prep(struct nouveau_context *nv, OUT_RING (chan, dst->pitch * dst->cpp); OUT_RING (chan, dst->pitch); OUT_RING (chan, dst->height); - OUT_RELOCh(chan, dst->buffer, dst->offset, + OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, dst->buffer, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); OUT_RING (chan, 0); @@ -56,9 +58,9 @@ nv50_surface_copy_prep(struct nouveau_context *nv, OUT_RING (chan, src->pitch * src->cpp); OUT_RING (chan, src->pitch); OUT_RING (chan, src->height); - OUT_RELOCh(chan, src->buffer, src->offset, + OUT_RELOCh(chan, nouveau_buffer(src->buffer)->bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, src->buffer, src->offset, + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); return 0; @@ -112,7 +114,8 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, return 1; BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY1, 1); - OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); OUT_RING (chan, surf_format); OUT_RING (chan, 1); @@ -120,9 +123,9 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, OUT_RING (chan, dst->pitch * dst->cpp); OUT_RING (chan, dst->pitch); OUT_RING (chan, dst->height); - OUT_RELOCh(chan, dst->buffer, dst->offset, + OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, dst->buffer, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); OUT_RING (chan, 0); -- cgit v1.2.3 From d07fbdd93941d5027a1aa7f0726140c6648a1e27 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 14 May 2008 17:19:44 +0200 Subject: i915: Added EGL winsys --- src/gallium/winsys/egl_drm/Makefile | 38 + src/gallium/winsys/egl_drm/Makefile.template | 116 +++ src/gallium/winsys/egl_drm/intel/Makefile | 40 + src/gallium/winsys/egl_drm/intel/SConscript | 39 + .../winsys/egl_drm/intel/intel_batchbuffer.c | 465 ++++++++++ .../winsys/egl_drm/intel/intel_batchbuffer.h | 133 +++ src/gallium/winsys/egl_drm/intel/intel_context.c | 366 ++++++++ src/gallium/winsys/egl_drm/intel/intel_context.h | 162 ++++ src/gallium/winsys/egl_drm/intel/intel_egl.c | 605 +++++++++++++ src/gallium/winsys/egl_drm/intel/intel_egl.h | 42 + src/gallium/winsys/egl_drm/intel/intel_lock.c | 102 +++ src/gallium/winsys/egl_drm/intel/intel_reg.h | 53 ++ src/gallium/winsys/egl_drm/intel/intel_screen.c | 680 +++++++++++++++ src/gallium/winsys/egl_drm/intel/intel_screen.h | 133 +++ .../winsys/egl_drm/intel/intel_swapbuffers.c | 327 +++++++ .../winsys/egl_drm/intel/intel_swapbuffers.h | 47 + src/gallium/winsys/egl_drm/intel/intel_winsys.h | 73 ++ .../winsys/egl_drm/intel/intel_winsys_i915.c | 184 ++++ .../winsys/egl_drm/intel/intel_winsys_pipe.c | 338 +++++++ .../winsys/egl_drm/intel/intel_winsys_softpipe.c | 82 ++ src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c | 953 ++++++++++++++++++++ src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h | 138 +++ src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h | 102 +++ src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c | 268 ++++++ src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c | 377 ++++++++ src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h | 115 +++ .../winsys/egl_drm/intel/ws_dri_mallocpool.c | 162 ++++ src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c | 970 +++++++++++++++++++++ 28 files changed, 7110 insertions(+) create mode 100644 src/gallium/winsys/egl_drm/Makefile create mode 100644 src/gallium/winsys/egl_drm/Makefile.template create mode 100644 src/gallium/winsys/egl_drm/intel/Makefile create mode 100644 src/gallium/winsys/egl_drm/intel/SConscript create mode 100644 src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_context.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_context.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_egl.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_egl.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_lock.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_reg.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_screen.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_screen.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/Makefile b/src/gallium/winsys/egl_drm/Makefile new file mode 100644 index 0000000000..4139d9e71f --- /dev/null +++ b/src/gallium/winsys/egl_drm/Makefile @@ -0,0 +1,38 @@ +# src/mesa/drivers/egl_drm/Makefile + +TOP = ../../../.. + +include $(TOP)/configs/current + + + +default: $(TOP)/$(LIB_DIR) subdirs + + +$(TOP)/$(LIB_DIR): + -mkdir $(TOP)/$(LIB_DIR) + + +subdirs: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +install: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) install) || exit 1 ; \ + fi \ + done + + +clean: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) clean) ; \ + fi \ + done + -rm -f common/*.o diff --git a/src/gallium/winsys/egl_drm/Makefile.template b/src/gallium/winsys/egl_drm/Makefile.template new file mode 100644 index 0000000000..3bc1fdd4d4 --- /dev/null +++ b/src/gallium/winsys/egl_drm/Makefile.template @@ -0,0 +1,116 @@ +# -*-makefile-*- + +MESA_MODULES = \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + +COMMON_GALLIUM_SOURCES = \ + $(TOP)/src/mesa/drivers/dri/common/utils.c \ + $(TOP)/src/mesa/drivers/dri/common/vblank.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_util.c \ + $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c + +COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ + $(TOP)/src/mesa/drivers/common/driverfuncs.c \ + $(TOP)/src/mesa/drivers/dri/common/texmem.c \ + $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c + +COMMON_BM_SOURCES = \ + $(TOP)/src/mesa/drivers/dri/common/dri_bufmgr.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_drmpool.c + + +ifeq ($(WINDOW_SYSTEM),dri) +WINOBJ= +WINLIB= +INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) + +OBJECTS = \ + $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) + +else +# miniglx +WINOBJ= +WINLIB=-L$(MESA)/src/glx/mini +MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini +INCLUDES = $(MINIGLX_INCLUDES) \ + $(SHARED_INCLUDES) \ + $(PCIACCESS_CFLAGS) + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(MINIGLX_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) +endif + + +### Include directories +SHARED_INCLUDES = \ + -I. \ + -I$(TOP)/src/mesa/drivers/dri/common \ + -Iserver \ + -I$(TOP)/include \ + -I$(TOP)/include/GL/internal \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/mesa/glapi \ + -I$(TOP)/src/mesa/math \ + -I$(TOP)/src/mesa/transform \ + -I$(TOP)/src/mesa/shader \ + -I$(TOP)/src/mesa/swrast \ + -I$(TOP)/src/mesa/swrast_setup \ + -I$(TOP)/src/egl/main \ + -I$(TOP)/src/egl/drivers/dri \ + $(LIBDRM_CFLAGS) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) + + +$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template + $(TOP)/bin/mklib -noprefix -o $@ \ + $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) + + +$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) + $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) + + +depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +install: $(LIBNAME) + $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) + $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + + +include depend diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile new file mode 100644 index 0000000000..5778ba77c3 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/Makefile @@ -0,0 +1,40 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = EGL_i915.so + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a + +DRIVER_SOURCES = \ + intel_winsys_pipe.c \ + intel_winsys_softpipe.c \ + intel_winsys_i915.c \ + intel_batchbuffer.c \ + intel_swapbuffers.c \ + intel_context.c \ + intel_lock.c \ + intel_screen.c \ + ws_dri_bufmgr.c \ + ws_dri_drmpool.c \ + ws_dri_fencemgr.c \ + ws_dri_mallocpool.c \ + ws_dri_slabpool.c \ + intel_egl.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") + +include ../Makefile.template + +intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c + +symlinks: diff --git a/src/gallium/winsys/egl_drm/intel/SConscript b/src/gallium/winsys/egl_drm/intel/SConscript new file mode 100644 index 0000000000..0ad19d42a8 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/SConscript @@ -0,0 +1,39 @@ +Import('*') + +env = drienv.Clone() + +env.Append(CPPPATH = [ + '../intel', + 'server' +]) + +#MINIGLX_SOURCES = server/intel_dri.c + +DRIVER_SOURCES = [ + 'intel_winsys_pipe.c', + 'intel_winsys_softpipe.c', + 'intel_winsys_i915.c', + 'intel_batchbuffer.c', + 'intel_swapbuffers.c', + 'intel_context.c', + 'intel_lock.c', + 'intel_screen.c', + 'intel_batchpool.c', +] + +sources = \ + COMMON_GALLIUM_SOURCES + \ + COMMON_BM_SOURCES + \ + DRIVER_SOURCES + +drivers = [ + softpipe, + i915simple +] + +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions +env.SharedLibrary( + target ='i915tex_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], +) \ No newline at end of file diff --git a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c new file mode 100644 index 0000000000..7ffa05a6e6 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c @@ -0,0 +1,465 @@ +/************************************************************************** + * + * Copyright 2006 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 "intel_batchbuffer.h" +#include "intel_context.h" +#include "intel_egl.h" + +#include + +#if 0 +static void +intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) +{ + int i; + fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); + for (i = 0; i < count / 4; i += 4) + fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", + offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); + fprintf(stderr, "END BATCH\n\n\n"); +} +#endif + +static void +intel_realloc_relocs(struct intel_batchbuffer *batch, int num_relocs) +{ + unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; + + size *= sizeof(uint32_t); + batch->reloc = realloc(batch->reloc, size); + batch->reloc_size = num_relocs; +} + + +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) +{ + /* + * Get a new, free batchbuffer. + */ + drmBO *bo; + struct drm_bo_info_req *req; + int ret; + + driBOUnrefUserList(batch->list); + driBOResetList(batch->list); + + batch->size = 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize; + ret = driBOData(batch->buffer, batch->size, NULL, NULL, 0); + assert(!ret); + + /* + * Add the batchbuffer to the validate list. + */ + + driBOAddListItem(batch->list, batch->buffer, + DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, + &batch->dest_location, &batch->node); + + req = &batch->node->bo_arg.d.req.bo_req; + + /* + * Set up information needed for us to make relocations + * relative to the underlying drm buffer objects. + */ + + driReadLockKernelBO(); + bo = driBOKernel(batch->buffer); + req->presumed_offset = (uint64_t) bo->offset; + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + batch->drmBOVirtual = (uint8_t *) bo->virtual; + driReadUnlockKernelBO(); + + /* + * Adjust the relocation buffer size. + */ + + if (batch->reloc_size > INTEL_MAX_RELOCS || + batch->reloc == NULL) + intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); + + assert(batch->reloc != NULL); + batch->reloc[0] = 0; /* No relocs yet. */ + batch->reloc[1] = 1; /* Reloc type 1 */ + batch->reloc[2] = 0; /* Only a single relocation list. */ + batch->reloc[3] = 0; /* Only a single relocation list. */ + + batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->poolOffset = driBOPoolOffset(batch->buffer); + batch->ptr = batch->map; + batch->dirty_state = ~0; + batch->nr_relocs = 0; + batch->flags = 0; + batch->id = 0;//batch->intel->intelScreen->batch_id++; +} + +/*====================================================================== + * Public functions + */ +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_screen *intel_screen) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel_screen = intel_screen; + + driGenBuffers(intel_screen->batchPool, "batchbuffer", 1, + &batch->buffer, 4096, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); + batch->last_fence = NULL; + batch->list = driBOCreateList(20); + batch->reloc = NULL; + intel_batchbuffer_reset(batch); + return batch; +} + +void +intel_batchbuffer_free(struct intel_batchbuffer *batch) +{ + if (batch->last_fence) { + driFenceFinish(batch->last_fence, + DRM_FENCE_TYPE_EXE, GL_FALSE); + driFenceUnReference(&batch->last_fence); + } + if (batch->map) { + driBOUnmap(batch->buffer); + batch->map = NULL; + } + driBOUnReference(batch->buffer); + driBOFreeList(batch->list); + if (batch->reloc) + free(batch->reloc); + batch->buffer = NULL; + free(batch); +} + +void +intel_offset_relocation(struct intel_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask) +{ + int itemLoc; + struct _drmBONode *node; + uint32_t *reloc; + struct drm_bo_info_req *req; + + driBOAddListItem(batch->list, driBO, val_flags, val_mask, + &itemLoc, &node); + req = &node->bo_arg.d.req.bo_req; + + if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { + + /* + * Stop other threads from tampering with the underlying + * drmBO while we're reading its offset. + */ + + driReadLockKernelBO(); + req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; + driReadUnlockKernelBO(); + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + } + + pre_add += driBOPoolOffset(driBO); + + if (batch->nr_relocs == batch->reloc_size) + intel_realloc_relocs(batch, batch->reloc_size * 2); + + reloc = batch->reloc + + (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); + + reloc[0] = ((uint8_t *)batch->ptr - batch->drmBOVirtual); + intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add); + reloc[1] = pre_add; + reloc[2] = itemLoc; + reloc[3] = batch->dest_location; + batch->nr_relocs++; +} + +static void +i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) +{ + buf->handle = rep->handle; + buf->flags = rep->flags; + buf->size = rep->size; + buf->offset = rep->offset; + buf->mapHandle = rep->arg_handle; + buf->proposedFlags = rep->proposed_flags; + buf->start = rep->buffer_start; + buf->fenceFlags = rep->fence_flags; + buf->replyFlags = rep->rep_flags; + buf->pageAlignment = rep->page_alignment; +} + +static int +i915_execbuf(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, + drmBOList *list, + struct drm_i915_execbuffer *ea) +{ + struct intel_screen *intel_screen = batch->intel_screen; + drmBONode *node; + drmMMListHead *l; + struct drm_i915_op_arg *arg, *first; + struct drm_bo_op_req *req; + struct drm_bo_info_rep *rep; + uint64_t *prevNext = NULL; + drmBO *buf; + int ret = 0; + uint32_t count = 0; + + first = NULL; + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + + arg = &node->bo_arg; + req = &arg->d.req; + + if (!first) + first = arg; + + if (prevNext) + *prevNext = (unsigned long)arg; + + prevNext = &arg->next; + req->bo_req.handle = node->buf->handle; + req->op = drm_bo_validate; + req->bo_req.flags = node->arg0; + req->bo_req.mask = node->arg1; + req->bo_req.hint |= 0; + count++; + } + + memset(ea, 0, sizeof(*ea)); + ea->num_buffers = count; + ea->batch.start = batch->poolOffset; + ea->batch.used = used; +#if 0 /* ZZZ JB: no cliprects used */ + ea->batch.cliprects = intel->pClipRects; + ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); +#else + ea->batch.cliprects = NULL; + ea->batch.num_cliprects = 0; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0; +#endif + ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; + ea->ops_list = (unsigned long) first; + first->reloc_ptr = (unsigned long) batch->reloc; + batch->reloc[0] = batch->nr_relocs; + + //return -EFAULT; + do { + ret = drmCommandWriteRead(intel_screen->device->drmFD, DRM_I915_EXECBUFFER, ea, + sizeof(*ea)); + } while (ret == -EAGAIN); + + if (ret != 0) { + printf("%s somebody set us up the bomb\n", __FUNCTION__); + return ret; + } + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + arg = &node->bo_arg; + rep = &arg->d.rep.bo_info; + + if (!arg->handled) { + return -EFAULT; + } + if (arg->d.rep.ret) + return arg->d.rep.ret; + + buf = node->buf; + i915_drm_copy_reply(rep, buf); + } + return 0; +} + +/* TODO: Push this whole function into bufmgr. + */ +static struct _DriFenceObject * +do_flush_locked(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + struct intel_screen *intel_screen = batch->intel_screen; + struct _DriFenceObject *fo; + drmFence fence; + drmBOList *boList; + struct drm_i915_execbuffer ea; + int ret = 0; + + driBOValidateUserList(batch->list); + boList = driGetdrmBOList(batch->list); + +#if 0 /* ZZZ JB Allways run */ + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { +#else + if (1) { +#endif + ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); + } else { + driPutdrmBOList(batch->list); + fo = NULL; + goto out; + } + driPutdrmBOList(batch->list); + if (ret) + abort(); + + if (ea.fence_arg.error != 0) { + + /* + * The hardware has been idled by the kernel. + * Don't fence the driBOs. + */ + + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); +#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ + _mesa_printf("fence error\n"); +#endif + batch->last_fence = NULL; + fo = NULL; + goto out; + } + + fence.handle = ea.fence_arg.handle; + fence.fence_class = ea.fence_arg.fence_class; + fence.type = ea.fence_arg.type; + fence.flags = ea.fence_arg.flags; + fence.signaled = ea.fence_arg.signaled; + + fo = driBOFenceUserList(intel_screen->mgr, batch->list, + "SuperFence", &fence); + + if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); + /* + * FIXME: Context last fence?? + */ + batch->last_fence = fo; + driFenceReference(fo); + } + out: +#if 0 /* ZZZ JB: fix this */ + intel->vtbl.lost_hardware(intel); +#else +#endif + return fo; +} + + +struct _DriFenceObject * +intel_batchbuffer_flush(struct intel_batchbuffer *batch) +{ + //struct intel_context *intel = batch->intel; + GLuint used = batch->ptr - batch->map; + //GLboolean was_locked = 1; + struct _DriFenceObject *fence; + + if (used == 0) { + driFenceReference(batch->last_fence); + return batch->last_fence; + } + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ +#if 0 /* ZZZ JB: what should we do here? */ + if (used & 4) { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } +#else + if (used & 4) { + ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 8; + } +#endif + driBOUnmap(batch->buffer); + batch->ptr = NULL; + batch->map = NULL; + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ +/* if (!was_locked) + LOCK_HARDWARE(intel);*/ + + fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + GL_FALSE); + +/* if (!was_locked) + UNLOCK_HARDWARE(intel);*/ + + /* Reset the buffer: + */ + intel_batchbuffer_reset(batch); + return fence; +} + +void +intel_batchbuffer_finish(struct intel_batchbuffer *batch) +{ + struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); + driFenceFinish(fence, driFenceType(fence), GL_FALSE); + driFenceUnReference(&fence); +} + +void +intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; +} diff --git a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h new file mode 100644 index 0000000000..6d35cf8b96 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h @@ -0,0 +1,133 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "mtypes.h" +#include "ws_dri_bufmgr.h" + +struct intel_screen; + +#define BATCH_SZ 16384 +#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_batchbuffer +{ + struct bufmgr *bm; + struct intel_screen *intel_screen; + + struct _DriBufferObject *buffer; + struct _DriFenceObject *last_fence; + GLuint flags; + + struct _DriBufferList *list; + GLuint list_count; + GLubyte *map; + GLubyte *ptr; + + uint32_t *reloc; + GLuint reloc_size; + GLuint nr_relocs; + + GLuint size; + + GLuint dirty_state; + GLuint id; + + uint32_t poolOffset; + uint8_t *drmBOVirtual; + struct _drmBONode *node; /* Validation list node for this buffer */ + int dest_location; /* Validation list sequence for this buffer */ +}; + +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_screen + *intel); + +void intel_batchbuffer_free(struct intel_batchbuffer *batch); + + +void intel_batchbuffer_finish(struct intel_batchbuffer *batch); + +struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer + *batch); + +void intel_batchbuffer_reset(struct intel_batchbuffer *batch); + + +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multple + * intel_buffer_dword() calls. + */ +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags); + +void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, + GLuint bytes); + +void +intel_offset_relocation(struct intel_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask); + +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static INLINE GLuint +intel_batchbuffer_space(struct intel_batchbuffer *batch) +{ + return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); +} + + +static INLINE void +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) +{ + assert(batch->map); + assert(intel_batchbuffer_space(batch) >= 4); + *(GLuint *) (batch->ptr) = dword; + batch->ptr += 4; +} + +static INLINE void +intel_batchbuffer_require_space(struct intel_batchbuffer *batch, + GLuint sz, GLuint flags) +{ + struct _DriFenceObject *fence; + + assert(sz < batch->size - 8); + if (intel_batchbuffer_space(batch) < sz || + (batch->flags != 0 && flags != 0 && batch->flags != flags)) { + fence = intel_batchbuffer_flush(batch); + driFenceUnReference(&fence); + } + + batch->flags |= flags; +} + +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS + +#define BEGIN_BATCH(n, flags) do { \ + assert(!intel->prim.flush); \ + intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ +} while (0) + +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) + +#define OUT_RELOC(buf,flags,mask,delta) do { \ + assert((delta) >= 0); \ + intel_offset_relocation(intel->batch, delta, buf, flags, mask); \ +} while (0) + +#define ADVANCE_BATCH() do { } while(0) + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c new file mode 100644 index 0000000000..394a40d714 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -0,0 +1,366 @@ +/************************************************************************** + * + * 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 "intel_screen.h" +#include "intel_context.h" +#include "intel_swapbuffers.h" +#include "intel_winsys.h" +#include "intel_batchbuffer.h" + +#include "state_tracker/st_public.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "intel_egl.h" +#include "utils.h" + +#ifdef DEBUG +int __intel_debug = 0; +#endif + + +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_NV_vertex_program +#include "extension_helper.h" + + +/** + * Extension strings exported by the intel driver. + * + * \note + * It appears that ARB_texture_env_crossbar has "disappeared" compared to the + * old i830-specific driver. + */ +const struct dri_extension card_extensions[] = { + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, + {"GL_SGIS_generate_mipmap", NULL }, + {NULL, NULL} +}; + +int +intel_create_context(struct egl_drm_context *eglCon, const __GLcontextModes *visual, void *sharedContextPrivate) +{ + struct intel_context *iCon = CALLOC_STRUCT(intel_context); + struct intel_screen *iScrn = (struct intel_screen *)eglCon->device->priv; + struct pipe_context *pipe; + struct st_context *st_share = NULL; + + eglCon->priv = iCon; + + iCon->intel_screen = iScrn; + iCon->egl_context = eglCon; + iCon->egl_device = eglCon->device; + + iCon->batch = intel_batchbuffer_alloc(iScrn); + iCon->last_swap_fence = NULL; + iCon->first_swap_fence = NULL; + + pipe = intel_create_i915simple(iCon, iScrn->winsys); +// pipe = intel_create_softpipe(iCon, iScrn->winsys); + + pipe->priv = iCon; + + iCon->st = st_create_context(pipe, visual, st_share); + return TRUE; +} + +void +intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read) +{ + if (context) { + struct intel_context *intel = (struct intel_context *)context->priv; + struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; + struct intel_framebuffer *read_fb = (struct intel_framebuffer *)read->priv; + + assert(draw_fb->stfb); + assert(read_fb->stfb); + + st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); + + intel->egl_drawable = draw; + + st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); + + if (draw != read) + st_resize_framebuffer(read_fb->stfb, read->w, read->h); + + //intelUpdateWindowSize(driDrawPriv); + } else { + st_make_current(NULL, NULL, NULL); + } +} + +void +intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) +{ + struct intel_screen *intelScreen = (struct intel_screen *)draw->device->priv; + struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; + + driBOUnReference(draw_fb->front_buffer); + draw_fb->front_buffer = NULL; + draw_fb->front = NULL; + + /* to unbind just call this function with front == NULL */ + if (!front) + return; + + draw_fb->front = front; + + driGenBuffers(intelScreen->staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); + driBOSetReferenced(draw_fb->front_buffer, front->handle); + + st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); +} + +#if 0 +GLboolean +intelCreateContext(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + struct intel_context *intel = CALLOC_STRUCT(intel_context); + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + struct intel_screen *intelScreen = intel_screen(sPriv); + drmI830Sarea *saPriv = intelScreen->sarea; + int fthrottle_mode; + GLboolean havePools; + struct pipe_context *pipe; + struct st_context *st_share = NULL; + + if (sharedContextPrivate) { + st_share = ((struct intel_context *) sharedContextPrivate)->st; + } + + driContextPriv->driverPrivate = intel; + intel->intelScreen = intelScreen; + intel->driScreen = sPriv; + intel->sarea = saPriv; + + driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, "i915"); + + + /* + * memory pools + */ + DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + // ZZZ JB should be per screen and not be done per context + havePools = intelCreatePools(sPriv); + DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + if (!havePools) + return GL_FALSE; + + + /* Dri stuff */ + intel->hHWContext = driContextPriv->hHWContext; + intel->driFd = sPriv->fd; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + + fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); + intel->iw.irq_seq = -1; + intel->irqsEmitted = 0; + + intel->batch = intel_batchbuffer_alloc(intel); + intel->last_swap_fence = NULL; + intel->first_swap_fence = NULL; + +#ifdef DEBUG + __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); +#endif + + /* + * Pipe-related setup + */ + if (getenv("INTEL_SP")) { + /* use softpipe driver instead of hw */ + pipe = intel_create_softpipe( intel, intelScreen->winsys ); + } + else { + switch (intel->intelScreen->deviceID) { + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + case PCI_CHIP_I945_GME: + case PCI_CHIP_G33_G: + case PCI_CHIP_Q33_G: + case PCI_CHIP_Q35_G: + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + pipe = intel_create_i915simple( intel, intelScreen->winsys ); + break; + default: + fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", + intel->intelScreen->deviceID, __FUNCTION__); + + pipe = intel_create_softpipe( intel, intelScreen->winsys ); + break; + } + } + + pipe->priv = intel; + + intel->st = st_create_context(pipe, visual, st_share); + + return GL_TRUE; +} + + +void +intelDestroyContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = intel_context(driContextPriv); + + assert(intel); /* should never be null */ + if (intel) { + st_finish(intel->st); + + intel_batchbuffer_free(intel->batch); + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(&intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + if (intel->first_swap_fence) { + driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(&intel->first_swap_fence); + intel->first_swap_fence = NULL; + } + + if (intel->intelScreen->dummyContext == intel) + intel->intelScreen->dummyContext = NULL; + + st_destroy_context(intel->st); + free(intel); + } +} + + +GLboolean +intelUnbindContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = intel_context(driContextPriv); + st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL); + /* XXX make_current(NULL)? */ + return GL_TRUE; +} + + +GLboolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) +{ + if (driContextPriv) { + struct intel_context *intel = intel_context(driContextPriv); + struct intel_framebuffer *draw_fb = intel_framebuffer(driDrawPriv); + struct intel_framebuffer *read_fb = intel_framebuffer(driReadPriv); + + assert(draw_fb->stfb); + assert(read_fb->stfb); + + /* This is for situations in which we need a rendering context but + * there may not be any currently bound. + */ + intel->intelScreen->dummyContext = intel; + + st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); + + if ((intel->driDrawable != driDrawPriv) || + (intel->lastStamp != driDrawPriv->lastStamp)) { + intel->driDrawable = driDrawPriv; + intelUpdateWindowSize(driDrawPriv); + intel->lastStamp = driDrawPriv->lastStamp; + } + + /* The size of the draw buffer will have been updated above. + * If the readbuffer is a different window, check/update its size now. + */ + if (driReadPriv != driDrawPriv) { + intelUpdateWindowSize(driReadPriv); + } + + } + else { + st_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h new file mode 100644 index 0000000000..aa9903f274 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_context.h @@ -0,0 +1,162 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef INTEL_CONTEXT_H +#define INTEL_CONTEXT_H + +#include +#include "drm.h" + +#include "pipe/p_debug.h" + +#include "intel_screen.h" +#include "i915_drm.h" + + +struct pipe_context; +struct intel_context; +struct _DriBufferObject; +struct st_context; +struct egl_drm_device; +struct egl_drm_context; +struct egl_drm_frontbuffer; + + +#define INTEL_MAX_FIXUP 64 + +/** + * Intel rendering context, contains a state tracker and intel-specific info. + */ +struct intel_context +{ + struct st_context *st; + + struct _DriFenceObject *last_swap_fence; + struct _DriFenceObject *first_swap_fence; + + struct intel_batchbuffer *batch; + +#if 0 + boolean locked; + char *prevLockFile; + int prevLockLine; +#endif + + /* pick this up from the screen instead + int drmFd; + */ + + struct intel_screen *intel_screen; + + uint lastStamp; + /* new egl stuff */ + struct egl_drm_device *egl_device; + struct egl_drm_context *egl_context; + struct egl_drm_drawable *egl_drawable; +}; + + + +/** + * Intel framebuffer. + */ +struct intel_framebuffer +{ + struct st_framebuffer *stfb; + + /* other fields TBD */ + int other; + struct _DriBufferObject *front_buffer; + struct egl_drm_frontbuffer *front; +}; + + + + +/* These are functions now: + */ +void LOCK_HARDWARE( struct intel_context *intel ); +void UNLOCK_HARDWARE( struct intel_context *intel ); + +extern char *__progname; + + + +/* ================================================================ + * Debugging: + */ +#ifdef DEBUG +extern int __intel_debug; + +#define DEBUG_SWAP 0x1 +#define DEBUG_LOCK 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BATCH 0x8 + +#define DBG(flag, ...) do { \ + if (__intel_debug & (DEBUG_##flag)) \ + printf(__VA_ARGS__); \ +} while(0) + +#else +#define DBG(flag, ...) +#endif + + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_Q33_G 0x29D2 + + +#if 0 +/** Cast wrapper */ +static INLINE struct intel_context * +intel_context(__DRIcontextPrivate *driContextPriv) +{ + return (struct intel_context *) driContextPriv->driverPrivate; +} + + +/** Cast wrapper */ +static INLINE struct intel_framebuffer * +intel_framebuffer(__DRIdrawablePrivate * driDrawPriv) +{ + return (struct intel_framebuffer *) driDrawPriv->driverPrivate; +} +#endif + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c new file mode 100644 index 0000000000..a9c0218455 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -0,0 +1,605 @@ + +#include +#include +#include +#include + +#include "eglconfig.h" +#include "eglcontext.h" +#include "egldisplay.h" +#include "egldriver.h" +#include "eglglobals.h" +#include "eglmode.h" +#include "eglscreen.h" +#include "eglsurface.h" + +#include "glapi.h" +#include "intel_egl.h" + +#include "xf86drm.h" +#include "xf86drmMode.h" + +#include "intel_context.h" + +#include "ws_dri_bufmgr.h" + +#include "intel_winsys.h" +#include "state_tracker/st_public.h" + +struct egl_drm_device* egl_drm_create_device(int drmFD); + +struct egl_drm_device* +egl_drm_create_device(int drmFD) +{ + struct egl_drm_device *device = malloc(sizeof(*device)); + memset(device, 0, sizeof(*device)); + device->drmFD = drmFD; + + if (!intel_init_driver(device)) { + printf("EGL: failed to initalize device\n"); + free(device); + } + + return device; +} + +__GLcontextModes* _gl_context_modes_create( unsigned count, size_t minimum_size ); + +struct drm_driver +{ + _EGLDriver base; /* base class/object */ + + drmModeResPtr res; + struct egl_drm_device *device; +}; + +struct drm_surface +{ + _EGLSurface base; /* base class/object */ + + struct egl_drm_drawable *drawable; +}; + +struct drm_context +{ + _EGLContext base; /* base class/object */ + + struct egl_drm_context *context; +}; + +struct drm_screen +{ + _EGLScreen base; + + /* backing buffer and crtc */ + drmBO buffer; + drmModeFBPtr fb; + uint32_t fbID; + drmModeCrtcPtr crtc; + + /* currently only support one output */ + drmModeOutputPtr output; + uint32_t outputID; + + struct drm_mode_modeinfo *mode; + + /* geometry of the screen */ + struct egl_drm_frontbuffer front; +}; + +static void +drm_update_res(struct drm_driver *drm_drv) +{ + drmModeFreeResources(drm_drv->res); + drm_drv->res = drmModeGetResources(drm_drv->device->drmFD); +} + +static EGLBoolean +drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) +{ + _EGLDisplay *disp = _eglLookupDisplay(dpy); + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_screen *screen = NULL; + drmModeOutputPtr output = NULL; + drmModeResPtr res = NULL; + + EGLint i; + int fd; + + fd = drmOpen("i915", NULL); + if (fd < 0) { + return EGL_FALSE; + } + + drm_drv->device = egl_drm_create_device(fd); + if (!drm_drv->device) { + drmClose(fd); + return EGL_FALSE; + } + + drm_update_res(drm_drv); + res = drm_drv->res; + + for(i = 0; i < res->count_outputs; i++) { + output = drmModeGetOutput(fd, res->outputs[i]); + + if (!output) + continue; + + if (output->connection == DRM_MODE_DISCONNECTED) { + drmModeFreeOutput(output); + continue; + } + + screen = malloc(sizeof(struct drm_screen)); + memset(screen, 0, sizeof(*screen)); + screen->outputID = res->outputs[i]; + screen->output = output; + _eglInitScreen(&screen->base); + _eglAddScreen(disp, &screen->base); + _eglAddNewMode(&screen->base, 1024, 768, 60 * 1000, "1024x768-60"); + } + + /* for now we only have one config */ + _EGLConfig config; + _eglInitConfig(&config, i + 1); + _eglSetConfigAttrib(&config, EGL_RED_SIZE, 8); + _eglSetConfigAttrib(&config, EGL_GREEN_SIZE, 8); + _eglSetConfigAttrib(&config, EGL_BLUE_SIZE, 8); + _eglSetConfigAttrib(&config, EGL_ALPHA_SIZE, 8); + _eglSetConfigAttrib(&config, EGL_BUFFER_SIZE, 32); + _eglSetConfigAttrib(&config, EGL_DEPTH_SIZE, 24); + _eglSetConfigAttrib(&config, EGL_STENCIL_SIZE, 8); + _eglSetConfigAttrib(&config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); + _eglAddConfig(disp, &config); + + drv->Initialized = EGL_TRUE; + + *major = 1; + *minor = 0; + + return EGL_TRUE; +} + + +static EGLBoolean +drm_terminate(_EGLDriver *drv, EGLDisplay dpy) +{ + /* TODO: clean up */ + free(drv); + return EGL_TRUE; +} + + +static struct drm_context * +lookup_drm_context(EGLContext context) +{ + _EGLContext *c = _eglLookupContext(context); + return (struct drm_context *) c; +} + + +static struct drm_surface * +lookup_drm_surface(EGLSurface surface) +{ + _EGLSurface *s = _eglLookupSurface(surface); + return (struct drm_surface *) s; +} + +static struct drm_screen * +lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen) +{ + _EGLScreen *s = _eglLookupScreen(dpy, screen); + return (struct drm_screen *) s; +} + +static __GLcontextModes* +visual_from_config(_EGLConfig *conf) +{ + __GLcontextModes *visual; + (void)conf; + + visual = _gl_context_modes_create(1, sizeof(*visual)); + visual->redBits = 8; + visual->greenBits = 8; + visual->blueBits = 8; + visual->alphaBits = 8; + + visual->rgbBits = 32; + visual->doubleBufferMode = 1; + + visual->depthBits = 24; + visual->stencilBits = 8; + + return visual; +} + + + +static EGLContext +drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_context *c; + struct drm_egl_context *share = NULL; + _EGLConfig *conf; + int i; + int ret; + __GLcontextModes *visual; + struct egl_drm_context *context; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreateContext"); + return EGL_NO_CONTEXT; + } + + for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { + switch (attrib_list[i]) { + /* no attribs defined for now */ + default: + _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); + return EGL_NO_CONTEXT; + } + } + + c = (struct drm_context *) calloc(1, sizeof(struct drm_context)); + if (!c) + return EGL_NO_CONTEXT; + + _eglInitContext(drv, dpy, &c->base, config, attrib_list); + + context = malloc(sizeof(*context)); + memset(context, 0, sizeof(*context)); + + if (!context) + goto err_c; + + context->device = drm_drv->device; + visual = visual_from_config(conf); + + ret = intel_create_context(context, visual, share); + free(visual); + + if (!ret) + goto err_gl; + + c->context = context; + + /* generate handle and insert into hash table */ + _eglSaveContext(&c->base); + assert(c->base.Handle); + + return c->base.Handle; +err_gl: + free(context); +err_c: + free(c); + return EGL_NO_CONTEXT; +} + +static EGLBoolean +drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) +{ + struct drm_context *fc = lookup_drm_context(context); + _eglRemoveContext(&fc->base); + if (fc->base.IsBound) { + fc->base.DeletePending = EGL_TRUE; + } else { + free(fc); + } + return EGL_TRUE; +} + + +static EGLSurface +drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) +{ + return EGL_NO_SURFACE; +} + + +static EGLSurface +drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) +{ + return EGL_NO_SURFACE; +} + +static EGLSurface +drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + const EGLint *attrib_list) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + int i; + int ret; + int width = -1; + int height = -1; + struct drm_surface *surf = NULL; + struct egl_drm_drawable *drawable = NULL; + __GLcontextModes *visual; + _EGLConfig *conf; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface"); + return EGL_NO_CONTEXT; + } + + for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { + switch (attrib_list[i]) { + case EGL_WIDTH: + width = attrib_list[++i]; + break; + case EGL_HEIGHT: + height = attrib_list[++i]; + break; + default: + _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); + return EGL_NO_SURFACE; + } + } + + if (width < 1 || height < 1) { + _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); + return EGL_NO_SURFACE; + } + + surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface)); + if (!surf) + goto err; + + if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list)) + goto err_surf; + + drawable = malloc(sizeof(*drawable)); + memset(drawable, 0, sizeof(*drawable)); + + drawable->w = width; + drawable->h = height; + + visual = visual_from_config(conf); + + drawable->device = drm_drv->device; + ret = intel_create_drawable(drawable, visual); + free(visual); + + if (!ret) + goto err_draw; + + surf->drawable = drawable; + + _eglSaveSurface(&surf->base); + return surf->base.Handle; + +err_draw: + free(drawable); +err_surf: + free(surf); +err: + return EGL_NO_SURFACE; +} + +static EGLSurface +drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, + const EGLint *attrib_list) +{ + EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list); + + return surf; +} + +static struct drm_mode_modeinfo * +drm_find_mode(drmModeOutputPtr output, _EGLMode *mode) +{ + int i; + struct drm_mode_modeinfo *m; + + for (i = 0; i < output->count_modes; i++) { + m = &output->modes[i]; + if (m->hdisplay == mode->Width && m->vdisplay == mode->Height) + break; + m = NULL; + } + + return m; +} +static void +draw(size_t x, size_t y, size_t w, size_t h, size_t pitch, size_t v, unsigned int *ptr) +{ + int i, j; + + for (i = x; i < x + w; i++) + for(j = y; j < y + h; j++) + ptr[(i * pitch / 4) + j] = v; + +} + +static void +prettyColors(int fd, unsigned int handle, size_t pitch) +{ + drmBO bo; + unsigned int *ptr; + int i; + + drmBOReference(fd, handle, &bo); + drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, (void**)&ptr); + + for (i = 0; i < (bo.size / 4); i++) + ptr[i] = 0xFFFFFFFF; + + for (i = 0; i < 4; i++) + draw(i * 40, i * 40, 40, 40, pitch, 0, ptr); + + + draw(200, 100, 40, 40, pitch, 0xff00ff, ptr); + draw(100, 200, 40, 40, pitch, 0xff00ff, ptr); + + drmBOUnmap(fd, &bo); +} + +static EGLBoolean +drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, + EGLScreenMESA screen, + EGLSurface surface, EGLModeMESA m) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_surface *surf = lookup_drm_surface(surface); + struct drm_screen *scrn = lookup_drm_screen(dpy, screen); + //struct intel_framebuffer *intel_fb = NULL; + //struct pipe_surface *front_surf = NULL; + _EGLMode *mode = _eglLookupMode(dpy, m); + size_t pitch = 2048 * 4; + size_t size = mode->Height * pitch; + int ret; + + /* TODO if allready shown take down */ + + printf("setting mode to %i x %i\n", mode->Width, mode->Height); + + ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_NO_EVICT, + DRM_BO_HINT_DONT_FENCE, &scrn->buffer); + + prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); + if (ret) { + printf("failed to create framebuffer (ret %d)\n", ret); + return EGL_FALSE; + } + + ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height, + 32, 32, pitch, + scrn->buffer.handle, + &scrn->fbID); + + if (ret) + goto err_bo; + + scrn->fb = drmModeGetFB(drm_drv->device->drmFD, scrn->fbID); + if (!scrn->fb) + goto err_bo; + + scrn->mode = drm_find_mode(scrn->output, mode); + if (!scrn->mode) { + printf("oh noes, no matching mode found\n"); + goto err_fb; + } + + ret = drmModeSetCrtc( + drm_drv->device->drmFD, + drm_drv->res->crtcs[1], + scrn->fbID, + 0, 0, + &scrn->outputID, 1, + scrn->mode); + + + scrn->front.handle = scrn->buffer.handle; + scrn->front.pitch = pitch; + scrn->front.width = mode->Width; + scrn->front.height = mode->Height; + + intel_bind_frontbuffer(surf->drawable, &scrn->front); + + return EGL_TRUE; + +err_fb: + /* TODO remove fb */ + +err_bo: + drmBOUnreference(drm_drv->device->drmFD, &scrn->buffer); + return EGL_FALSE; +} + +static EGLBoolean +drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +{ + struct drm_surface *fs = lookup_drm_surface(surface); + _eglRemoveSurface(&fs->base); + if (fs->base.IsBound) { + fs->base.DeletePending = EGL_TRUE; + } else { + free(fs); + } + return EGL_TRUE; +} + + + + +static EGLBoolean +drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) +{ + struct drm_surface *readSurf = lookup_drm_surface(read); + struct drm_surface *drawSurf = lookup_drm_surface(draw); + struct drm_context *ctx = lookup_drm_context(context); + EGLBoolean b; + + b = _eglMakeCurrent(drv, dpy, draw, read, context); + if (!b) + return EGL_FALSE; + + /* XXX this is where we'd do the hardware context switch */ + (void) drawSurf; + (void) readSurf; + (void) ctx; + + intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); + return EGL_TRUE; +} + +static EGLBoolean +drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) +{ + struct drm_surface *surf = lookup_drm_surface(draw); + if (!surf) + return EGL_FALSE; + + /* error checking */ + if (!_eglSwapBuffers(drv, dpy, draw)) + return EGL_FALSE; + + intel_swap_buffers(surf->drawable); + return EGL_TRUE; +} + + +/** + * The bootstrap function. Return a new drm_driver object and + * plug in API functions. + */ +_EGLDriver * +_eglMain(_EGLDisplay *dpy) +{ + struct drm_driver *drm; + + drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); + if (!drm) { + return NULL; + } + + /* First fill in the dispatch table with defaults */ + _eglInitDriverFallbacks(&drm->base); + /* then plug in our Drm-specific functions */ + drm->base.API.Initialize = drm_initialize; + drm->base.API.Terminate = drm_terminate; + drm->base.API.CreateContext = drm_create_context; + drm->base.API.MakeCurrent = drm_make_current; + drm->base.API.CreateWindowSurface = drm_create_window_surface; + drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface; + drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface; + drm->base.API.DestroySurface = drm_destroy_surface; + drm->base.API.DestroyContext = drm_destroy_context; + drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa; + drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; + drm->base.API.SwapBuffers = drm_swap_buffers; + + /* enable supported extensions */ + drm->base.Extensions.MESA_screen_surface = EGL_TRUE; + drm->base.Extensions.MESA_copy_context = EGL_TRUE; + + return &drm->base; +} diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h new file mode 100644 index 0000000000..18e84e8eea --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.h @@ -0,0 +1,42 @@ + +#ifndef _INTEL_EGL_H_ +#define _INTEL_EGL_H_ + +struct egl_drm_device +{ + void *priv; + int drmFD; +}; + +struct egl_drm_context +{ + void *priv; + struct egl_drm_device *device; +}; + +struct egl_drm_drawable +{ + void *priv; + struct egl_drm_device *device; + size_t h; + size_t w; +}; + +struct egl_drm_frontbuffer +{ + uint32_t handle; + uint32_t pitch; + uint32_t width; + uint32_t height; +}; + +#include "GL/internal/glcore.h" + +int intel_init_driver(struct egl_drm_device *device); +int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate); +int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual); +void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read); +void intel_swap_buffers(struct egl_drm_drawable *draw); +void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front); + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_lock.c b/src/gallium/winsys/egl_drm/intel/intel_lock.c new file mode 100644 index 0000000000..cec83c7585 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_lock.c @@ -0,0 +1,102 @@ +/************************************************************************** + * + * 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 "main/glheader.h" +#include "glapi/glthread.h" +#include +#include "state_tracker/st_public.h" +#include "intel_context.h" + +#if 0 + +_glthread_DECLARE_STATIC_MUTEX( lockMutex ); + + +static void +intelContendedLock(struct intel_context *intel, uint flags) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIscreenPrivate *sPriv = intel->driScreen; + struct intel_screen *intelScreen = intel_screen(sPriv); + drmI830Sarea *sarea = intel->sarea; + + drmGetLock(intel->driFd, intel->hHWContext, flags); + + DBG(LOCK, "%s - got contended lock\n", __progname); + + /* 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); + + if (sarea->width != intelScreen->front.width || + sarea->height != intelScreen->front.height) { + + intelUpdateScreenRotation(sPriv, sarea); + } +} + + +/* Lock the hardware and validate our state. + */ +void LOCK_HARDWARE( struct intel_context *intel ) +{ + char __ret = 0; + + _glthread_LOCK_MUTEX(lockMutex); + assert(!intel->locked); + + DRM_CAS(intel->driHwLock, intel->hHWContext, + (DRM_LOCK_HELD|intel->hHWContext), __ret); + + if (__ret) + intelContendedLock( intel, 0 ); + + DBG(LOCK, "%s - locked\n", __progname); + + intel->locked = 1; +} + + +/* Unlock the hardware using the global current context + */ +void UNLOCK_HARDWARE( struct intel_context *intel ) +{ + assert(intel->locked); + intel->locked = 0; + + DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); + + _glthread_UNLOCK_MUTEX(lockMutex); + + DBG(LOCK, "%s - unlocked\n", __progname); +} +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_reg.h b/src/gallium/winsys/egl_drm/intel/intel_reg.h new file mode 100644 index 0000000000..f37c24fda9 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_reg.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + + +#ifndef _INTEL_REG_H_ +#define _INTEL_REG_H_ + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) + +#define MI_BATCH_BUFFER_END (0xA<<23) + + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c new file mode 100644 index 0000000000..38c4098087 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.c @@ -0,0 +1,680 @@ +/************************************************************************** + * + * 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 "utils.h" +#include "vblank.h" +#include "xmlpool.h" + +#include "intel_context.h" +#include "intel_screen.h" +#include "intel_batchbuffer.h" +//#include "intel_batchpool.h" +#include "intel_swapbuffers.h" +#include "intel_winsys.h" + +#include "ws_dri_bufpool.h" + +#include "pipe/p_context.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_cb_fbo.h" +#include "intel_egl.h" + +static boolean +intel_create_pools(struct intel_screen *intel_screen) +{ + if (intel_screen->havePools) + return GL_TRUE; + + intel_screen->mgr = driFenceMgrTTMInit(intel_screen->device->drmFD); + if (!intel_screen->mgr) { + fprintf(stderr, "Failed to create fence manager.\n"); + return FALSE; + } + + intel_screen->fMan = driInitFreeSlabManager(10, 10); + if (!intel_screen->fMan) { + fprintf(stderr, "Failed to create free slab manager.\n"); + return FALSE; + } + + intel_screen->staticPool = driDRMPoolInit(intel_screen->device->drmFD); + intel_screen->batchPool = driSlabPoolInit(intel_screen->device->drmFD, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + 4096, //intelScreen->maxBatchSize, + 1, 40, 16*16384, 0, + intel_screen->fMan); + + intel_screen->havePools = GL_TRUE; + + return GL_TRUE; +} + +extern const struct dri_extension card_extensions[]; + +int +intel_init_driver(struct egl_drm_device *device) +{ + struct intel_screen *intel_screen; + + /* Allocate the private area */ + intel_screen = CALLOC_STRUCT(intel_screen); + if (!intel_screen) + return FALSE; + + device->priv = (void *)intel_screen; + intel_screen->device = device; + + if (!intel_create_pools(intel_screen)) + return FALSE; + + intel_screen->batch = intel_batchbuffer_alloc(intel_screen); + + intel_screen->winsys = intel_create_pipe_winsys(device->drmFD, intel_screen->fMan); + + /* hack */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + + return TRUE; +} + +int +intel_create_drawable(struct egl_drm_drawable *drawable, + const __GLcontextModes * visual) +{ + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + + if (!intelfb) + return GL_FALSE; + + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + drawable->w, + drawable->h, + (void*) intelfb); + + if (!intelfb->stfb) { + free(intelfb); + return GL_FALSE; + } + + drawable->priv = (void *) intelfb; + return GL_TRUE; +} + +#if 0 +PUBLIC const char __driConfigOptions[] = + DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY + DRI_CONF_FORCE_S3TC_ENABLE(false) + DRI_CONF_ALLOW_LARGE_TEXTURES(1) + DRI_CONF_SECTION_END DRI_CONF_END; + +const uint __driNConfigOptions = 4; + +#ifdef USE_NEW_INTERFACE +static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; +#endif /*USE_NEW_INTERFACE */ + +extern const struct dri_extension card_extensions[]; + + + + +static void +intelPrintDRIInfo(struct intel_screen * intelScreen, + __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) +{ + fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->front.size, intelScreen->front.offset, + intelScreen->front.pitch); + fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); +} + +static void +intelPrintSAREA(const drmI830Sarea * sarea) +{ + fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, + sarea->height); + fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); + fprintf(stderr, + "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->front_offset, sarea->front_size, + (unsigned) sarea->front_handle); + fprintf(stderr, + "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->back_offset, sarea->back_size, + (unsigned) sarea->back_handle); + fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->depth_offset, sarea->depth_size, + (unsigned) sarea->depth_handle); + fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); + fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); + fprintf(stderr, + "SAREA: rotated offset: 0x%08x size: 0x%x\n", + sarea->rotated_offset, sarea->rotated_size); + fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); +} + +/** + * Use the information in the sarea to update the screen parameters + * related to screen rotation. Needs to be called locked. + */ +void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) +{ + struct intel_screen *intelScreen = intel_screen(sPriv); + + if (intelScreen->front.map) { + drmUnmap(intelScreen->front.map, intelScreen->front.size); + intelScreen->front.map = NULL; + } + + if (intelScreen->front.buffer) + driDeleteBuffers(1, &intelScreen->front.buffer); + + intelScreen->front.width = sarea->width; + intelScreen->front.height = sarea->height; + intelScreen->front.offset = sarea->front_offset; + intelScreen->front.pitch = sarea->pitch * intelScreen->front.cpp; + intelScreen->front.size = sarea->front_size; + intelScreen->front.handle = sarea->front_handle; + + assert( sarea->front_size >= + intelScreen->front.pitch * intelScreen->front.height ); + +#if 0 /* JB not important */ + if (!sarea->front_handle) + return; + + if (drmMap(sPriv->fd, + sarea->front_handle, + intelScreen->front.size, + (drmAddress *) & intelScreen->front.map) != 0) { + fprintf(stderr, "drmMap(frontbuffer) failed!\n"); + return; + } +#endif + +#if 0 /* JB */ + if (intelScreen->staticPool) { + driGenBuffers(intelScreen->staticPool, "static region", 1, + &intelScreen->front.buffer, 64, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + + driBOSetStatic(intelScreen->front.buffer, + intelScreen->front.offset, + intelScreen->front.pitch * intelScreen->front.height, + intelScreen->front.map, 0); + } +#else + if (intelScreen->staticPool) { + if (intelScreen->front.buffer) + driBOUnReference(intelScreen->front.buffer); + driGenBuffers(intelScreen->staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); + driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle); + } +#endif +} + + +boolean +intelCreatePools(__DRIscreenPrivate * sPriv) +{ + //unsigned batchPoolSize = 1024*1024; + struct intel_screen *intelScreen = intel_screen(sPriv); + + if (intelScreen->havePools) + return GL_TRUE; + +#if 0 /* ZZZ JB fix this */ + intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); + if (!intelScreen->staticPool) + return GL_FALSE; + + batchPoolSize /= BATCH_SZ; + intelScreen->batchPool = driBatchPoolInit(sPriv->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_LOCAL, + BATCH_SZ, + batchPoolSize, 5); + if (!intelScreen->batchPool) { + fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); + return GL_FALSE; + } +#else + intelScreen->staticPool = driDRMPoolInit(sPriv->fd); + intelScreen->batchPool = driSlabPoolInit(sPriv->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + 4096, //intelScreen->maxBatchSize, + 1, 40, 16*16384, 0, + intelScreen->fMan); +#endif + intelScreen->havePools = GL_TRUE; + + //intelUpdateScreenRotation(sPriv, intelScreen->sarea); + + return GL_TRUE; +} + + +static boolean +intelInitDriver(__DRIscreenPrivate * sPriv) +{ + struct intel_screen *intelScreen; + I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; + + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> + getProcAddress("glxEnableExtension")); + void *const psc = sPriv->psc->screenConfigs; + + if (sPriv->devPrivSize != sizeof(I830DRIRec)) { + fprintf(stderr, + "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); + return GL_FALSE; + } + + /* Allocate the private area */ + intelScreen = CALLOC_STRUCT(intel_screen); + if (!intelScreen) + return GL_FALSE; + + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); + + sPriv->private = (void *) intelScreen; + + intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + + gDRIPriv->sarea_priv_offset); + intelScreen->deviceID = gDRIPriv->deviceID; + intelScreen->front.cpp = gDRIPriv->cpp; + intelScreen->drmMinor = sPriv->drmMinor; + + + assert(gDRIPriv->bitsPerPixel == 16 || + gDRIPriv->bitsPerPixel == 32); + + + intelUpdateScreenRotation(sPriv, intelScreen->sarea); + + if (0) + intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); + + if (glx_enable_extension != NULL) { + (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); + (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); + (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); + } + + + +#if 1 // ZZZ JB + intelScreen->mgr = driFenceMgrTTMInit(sPriv->fd); + if (!intelScreen->mgr) { + fprintf(stderr, "Failed to create fence manager.\n"); + return GL_FALSE; + } + + intelScreen->fMan = driInitFreeSlabManager(10, 10); + if (!intelScreen->fMan) { + fprintf(stderr, "Failed to create free slab manager.\n"); + return GL_FALSE; + } + + if (!intelCreatePools(sPriv)) + return GL_FALSE; +#endif + + intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd, intelScreen->fMan); + + return GL_TRUE; +} + + +static void +intelDestroyScreen(__DRIscreenPrivate * sPriv) +{ + struct intel_screen *intelScreen = intel_screen(sPriv); + + /* intelUnmapScreenRegions(intelScreen); */ + + if (intelScreen->havePools) { + driPoolTakeDown(intelScreen->staticPool); + driPoolTakeDown(intelScreen->batchPool); + } + FREE(intelScreen); + sPriv->private = NULL; +} + + +/** + * This is called when we need to set up GL rendering to a new X window. + */ +static boolean +intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, + __DRIdrawablePrivate * driDrawPriv, + const __GLcontextModes * visual, boolean isPixmap) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + + if (!intelfb) + return GL_FALSE; + + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + driDrawPriv->w, + driDrawPriv->h, + (void*) intelfb); + if (!intelfb->stfb) { + free(intelfb); + return GL_FALSE; + } + + driDrawPriv->driverPrivate = (void *) intelfb; + return GL_TRUE; + } +} + +static void +intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) +{ + struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv); + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); +} + + +/** + * Get information about previous buffer swaps. + */ +static int +intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) +{ + if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) + || (sInfo == NULL)) { + return -1; + } + + return 0; +} + + +static void +intelSetTexOffset(__DRIcontext *pDRICtx, int texname, + unsigned long long offset, int depth, uint pitch) +{ + abort(); +#if 0 + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct st_texture_object *stObj = st_texture_object(tObj); + + if (!stObj) + return; + + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); + + stObj->imageOverride = GL_TRUE; + stObj->depthOverride = depth; + stObj->pitchOverride = pitch; + + if (offset) + stObj->textureOffset = offset; +#endif +} + + +static const struct __DriverAPIRec intelAPI = { + .InitDriver = intelInitDriver, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = intelCopySubBuffer, + .setTexOffset = intelSetTexOffset, +}; + + +static __GLcontextModes * +intelFillInModes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, boolean have_back_buffer) +{ + __GLcontextModes *modes; + __GLcontextModes *m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + u_int8_t depth_bits_array[3]; + u_int8_t stencil_bits_array[3]; + + + 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; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + 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; + } + + modes = + (*dri_interface->createContextModes) (num_modes, + sizeof(__GLcontextModes)); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_DIRECT_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for (m = modes; m != NULL; m = m->next) { + if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, + __DRIscreen * psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 7, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 7, 0 }; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("i915", + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &intelAPI); + + if (psp != NULL) { + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + *driver_modes = intelFillInModes(dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create + * is called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + } + + return (void *) psp; +} +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_screen.h new file mode 100644 index 0000000000..e8c1cdfca4 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.h @@ -0,0 +1,133 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef _INTEL_SCREEN_H_ +#define _INTEL_SCREEN_H_ + +#include "ws_dri_bufpool.h" + +#include "pipe/p_compiler.h" + +struct egl_drm_device *device; + +struct intel_screen +{ +#if 0 + struct { + drm_handle_t handle; + + /* We create a static dri buffer for the frontbuffer. + */ + struct _DriBufferObject *buffer; + + char *map; /* memory map */ + int offset; /* from start of video mem, in bytes */ + int pitch; /* row stride, in bytes */ + int width; + int height; + int size; + int cpp; /* for front and back buffers */ + } front; +#endif + + int drmFB; + +#if 0 + int deviceID; + int drmMinor; + + + drmI830Sarea *sarea;*/ + + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; +#endif + + struct _DriBufferPool *batchPool; + struct _DriBufferPool *staticPool; /** for the X screen/framebuffer */ + boolean havePools; + +#if 0 + /** + * Temporary(?) context to use for SwapBuffers or other situations in + * which we need a rendering context, but none is currently bound. + */ + struct intel_context *dummyContext; +#endif + + /* + * New stuff form the i915tex integration + */ + struct _DriFenceMgr *mgr; + struct _DriFreeSlabManager *fMan; + unsigned batch_id; + + struct pipe_winsys *winsys; + struct egl_drm_device *device; + + /* batch buffer used for swap buffers */ + struct intel_batchbuffer *batch; +}; + + + +/** cast wrapper */ +#if 0 +static INLINE struct intel_screen * +intel_screen(__DRIscreenPrivate *sPriv) +{ + return (struct intel_screen *) sPriv->private; +} + + +extern void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); + + +extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); + +extern boolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); + +extern boolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + + +extern boolean +intelCreatePools(__DRIscreenPrivate *sPriv); + +extern boolean +intelCreateContext(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + +#endif +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c new file mode 100644 index 0000000000..1ce4b2754a --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c @@ -0,0 +1,327 @@ +/************************************************************************** + * + * 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 "intel_screen.h" +#include "intel_context.h" +#include "intel_swapbuffers.h" +#include "intel_batchbuffer.h" +#include "intel_reg.h" +#include "intel_winsys.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 "intel_egl.h" + + +static void +intel_display_surface(struct egl_drm_drawable *draw, + struct pipe_surface *surf); + +void intel_swap_buffers(struct egl_drm_drawable *draw) +{ + struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, ST_SURFACE_BACK_LEFT); + if (back_surf) { + st_notify_swapbuffers(intel_fb->stfb); + intel_display_surface(draw, back_surf); + st_notify_swapbuffers_complete(intel_fb->stfb); + } +} + +static void +intel_display_surface(struct egl_drm_drawable *draw, + struct pipe_surface *surf) +{ + struct intel_screen *intel = (struct intel_screen *)draw->device->priv; + struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; + struct _DriFenceObject *fence; + + //const int srcWidth = surf->width; + //const int srcHeight = surf->height; + const int srcPitch = surf->pitch; + + const int dstWidth = intel_fb->front->width; + const int dstHeight = intel_fb->front->height; + const int dstPitch = intel_fb->front->pitch / 4;//draw->front.cpp; + + const int cpp = 4;//intel_fb->front->cpp; + + int BR13, CMD; + //int i; + + + BR13 = (dstPitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + + printf("srcPitch: %u, dstWidth: %u, dstHeight: %u, dstPitch: %u, cpp: %u\n", srcPitch, dstWidth, dstHeight, dstPitch, cpp); + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((0 << 16) | 0); + OUT_BATCH((dstHeight << 16) | dstWidth); + + OUT_RELOC(intel_fb->front_buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + + OUT_BATCH((0 << 16) | 0); + OUT_BATCH((srcPitch * cpp) & 0xffff); + OUT_RELOC(dri_bo(surf->buffer), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + ADVANCE_BATCH(); + + fence = intel_batchbuffer_flush(intel->batch); + driFenceUnReference(&fence); + intel_batchbuffer_finish(intel->batch); +} + +#if 0 +/** + * Display a colorbuffer surface in an X window. + * Used for SwapBuffers and flushing front buffer rendering. + * + * \param dPriv the window/drawable to display into + * \param surf the surface to display + * \param rect optional subrect of surface to display (may be NULL). + */ +void +intelDisplaySurface(__DRIdrawablePrivate *dPriv, + struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + //struct intel_context *intel = intelScreen->dummyContext; + + DBG(SWAP, "%s\n", __FUNCTION__); + +#if 0 + if (!intel) { + /* XXX this is where some kind of extra/meta context could be useful */ + return; + } +#endif + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); + driFenceUnReference(&intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + /* if this drawable isn't currently bound the LOCK_HARDWARE done on the + * current context (which is what intelScreenContext should return) might + * not get a contended lock and thus cliprects not updated (tests/manywin) + */ + if (intel_context(dPriv->driContextPriv) != intel) + DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); + + + if (dPriv && dPriv->numClipRects) { + const int srcWidth = surf->width; + const int srcHeight = surf->height; + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; + const int cpp = intelScreen->front.cpp; + const int srcpitch = surf->pitch; + int BR13, CMD; + int i; + + ASSERT(surf->buffer); + ASSERT(surf->cpp == cpp); + + DBG(SWAP, "screen pitch %d src surface pitch %d\n", + pitch, surf->pitch); + + if (cpp == 2) { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + } + else { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + } + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + drm_clip_rect_t sbox; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->front.width || + pbox->y2 > intelScreen->front.height) { + /* invalid cliprect, skip it */ + continue; + } + + box = *pbox; + + if (rect) { + /* intersect cliprect with user-provided src rect */ + drm_clip_rect_t rrect; + + rrect.x1 = dPriv->x + rect->x1; + rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; + rrect.x2 = rect->x2 + rrect.x1; + rrect.y2 = rect->y2 + rrect.y1; + if (rrect.x1 > box.x1) + box.x1 = rrect.x1; + if (rrect.y1 > box.y1) + box.y1 = rrect.y1; + if (rrect.x2 < box.x2) + box.x2 = rrect.x2; + if (rrect.y2 < box.y2) + box.y2 = rrect.y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + /* restrict blit to size of actually rendered area */ + if (box.x2 - box.x1 > srcWidth) + box.x2 = srcWidth + box.x1; + if (box.y2 - box.y1 > srcHeight) + box.y2 = srcHeight + box.y1; + + DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", + box.x1, box.x2, box.y1, box.y2); + + sbox.x1 = box.x1 - dPriv->x; + sbox.y1 = box.y1 - dPriv->y; + + assert(box.x1 < box.x2); + assert(box.y1 < box.y2); + + /* XXX this could be done with pipe->surface_copy() */ + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((box.y1 << 16) | box.x1); + OUT_BATCH((box.y2 << 16) | box.x2); + + OUT_RELOC(intelScreen->front.buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + OUT_BATCH((sbox.y1 << 16) | sbox.x1); + OUT_BATCH((srcpitch * cpp) & 0xffff); + OUT_RELOC(dri_bo(surf->buffer), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + ADVANCE_BATCH(); + } + + if (intel->first_swap_fence) + driFenceUnReference(&intel->first_swap_fence); + intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); + } + + UNLOCK_HARDWARE(intel); + + if (intel->lastStamp != dPriv->lastStamp) { + intelUpdateWindowSize(dPriv); + intel->lastStamp = dPriv->lastStamp; + } +} + + + +/** + * This will be called whenever the currently bound window is moved/resized. + */ +void +intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) +{ + struct intel_framebuffer *intelfb = intel_framebuffer(dPriv); + assert(intelfb->stfb); + st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); +} + + + +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + st_notify_swapbuffers(intel_fb->stfb); + intelDisplaySurface(dPriv, back_surf, NULL); + st_notify_swapbuffers_complete(intel_fb->stfb); + } +} + + +/** + * Called via glXCopySubBufferMESA() to copy a subrect of the back + * buffer to the front buffer/screen. + */ +void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ + struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + drm_clip_rect_t rect; + rect.x1 = x; + rect.y1 = y; + rect.x2 = w; + rect.y2 = h; + + st_notify_swapbuffers(intel_fb->stfb); + intelDisplaySurface(dPriv, back_surf, &rect); + } +} +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h new file mode 100644 index 0000000000..904f26732e --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2006 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. + * + **************************************************************************/ + +#ifndef INTEL_SWAPBUFFERS_H +#define INTEL_SWAPBUFFERS_H + + +struct pipe_surface; + +#if 0 +extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, + struct pipe_surface *surf, + const drm_clip_rect_t * rect); + +extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, + int x, int y, int w, int h); + +extern void intelUpdateWindowSize(__DRIdrawablePrivate *dPriv); +#endif + +#endif /* INTEL_SWAPBUFFERS_H */ diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys.h b/src/gallium/winsys/egl_drm/intel/intel_winsys.h new file mode 100644 index 0000000000..d0a319f9a4 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_winsys.h @@ -0,0 +1,73 @@ +/************************************************************************** + * + * Copyright 2006 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. + * + **************************************************************************/ + +#ifndef INTEL_WINSYS_H +#define INTEL_WINSYS_H + +#include "pipe/p_state.h" + +struct intel_context; +struct pipe_context; +struct pipe_winsys; +struct pipe_buffer; +struct _DriBufferObject; + +struct pipe_winsys * +intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ); + +void +intel_destroy_pipe_winsys( struct pipe_winsys *winsys ); + +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ); + +struct pipe_context * +intel_create_i915simple( struct intel_context *intel, + struct pipe_winsys *winsys ); + + +struct intel_buffer { + struct pipe_buffer base; + struct _DriBufferObject *driBO; +}; + +static INLINE struct intel_buffer * +intel_buffer( struct pipe_buffer *buf ) +{ + return (struct intel_buffer *)buf; +} + +static INLINE struct _DriBufferObject * +dri_bo( struct pipe_buffer *buf ) +{ + return intel_buffer(buf)->driBO; +} + + + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c new file mode 100644 index 0000000000..8ec5c7e82a --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c @@ -0,0 +1,184 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" + +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_winsys.h" + +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "i915simple/i915_winsys.h" +#include "i915simple/i915_screen.h" + + +struct intel_i915_winsys { + struct i915_winsys winsys; /**< batch buffer funcs */ + struct pipe_winsys *pws; + struct intel_context *intel; +}; + + +/* Turn a i915simple winsys into an intel/i915simple winsys: + */ +static inline struct intel_i915_winsys * +intel_i915_winsys( struct i915_winsys *sws ) +{ + return (struct intel_i915_winsys *)sws; +} + + +/* Simple batchbuffer interface: + */ + +static unsigned *intel_i915_batch_start( struct i915_winsys *sws, + unsigned dwords, + unsigned relocs ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + + /* XXX: check relocs. + */ + if (intel_batchbuffer_space( intel->batch ) >= dwords * 4) { + /* XXX: Hmm, the driver can't really do much with this pointer: + */ + return (unsigned *)intel->batch->ptr; + } + else + return NULL; +} + +static void intel_i915_batch_dword( struct i915_winsys *sws, + unsigned dword ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + intel_batchbuffer_emit_dword( intel->batch, dword ); +} + +static void intel_i915_batch_reloc( struct i915_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + unsigned flags = DRM_BO_FLAG_MEM_TT; + unsigned mask = DRM_BO_MASK_MEM; + + if (access_flags & I915_BUFFER_ACCESS_WRITE) { + flags |= DRM_BO_FLAG_WRITE; + mask |= DRM_BO_FLAG_WRITE; + } + + if (access_flags & I915_BUFFER_ACCESS_READ) { + flags |= DRM_BO_FLAG_READ; + mask |= DRM_BO_FLAG_READ; + } + +#if 0 /* JB old */ + intel_batchbuffer_emit_reloc( intel->batch, + dri_bo( buf ), + flags, mask, + delta ); +#else /* new */ + intel_offset_relocation( intel->batch, + delta, + dri_bo( buf ), + flags, + mask ); +#endif +} + + + +static void intel_i915_batch_flush( struct i915_winsys *sws, + struct pipe_fence_handle **fence ) +{ + struct intel_i915_winsys *iws = intel_i915_winsys(sws); + struct intel_context *intel = iws->intel; + union { + struct _DriFenceObject *dri; + struct pipe_fence_handle *pipe; + } fu; + + if (fence) + assert(!*fence); + + fu.dri = intel_batchbuffer_flush( intel->batch ); + + if (!fu.dri) { + assert(0); + *fence = NULL; + return; + } + + if (fu.dri) { + if (fence) + *fence = fu.pipe; + else + driFenceUnReference(&fu.dri); + } + +} + + +/** + * Create i915 hardware rendering context. + */ +struct pipe_context * +intel_create_i915simple( struct intel_context *intel, + struct pipe_winsys *winsys ) +{ + struct intel_i915_winsys *iws = CALLOC_STRUCT( intel_i915_winsys ); + struct pipe_screen *screen; + + /* Fill in this struct with callbacks that i915simple will need to + * communicate with the window system, buffer manager, etc. + */ + iws->winsys.batch_start = intel_i915_batch_start; + iws->winsys.batch_dword = intel_i915_batch_dword; + iws->winsys.batch_reloc = intel_i915_batch_reloc; + iws->winsys.batch_flush = intel_i915_batch_flush; + iws->pws = winsys; + iws->intel = intel; + + screen = i915_create_screen(winsys, PCI_CHIP_I945_GM); + assert(screen); + + /* Create the i915simple context: + */ + return i915_create_context( screen, + winsys, + &iws->winsys ); +} diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c new file mode 100644 index 0000000000..8bf8c21439 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c @@ -0,0 +1,338 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include +#include +//#include "dri_bufpool.h" +//#include "dri_bufmgr.h" + +#include "intel_context.h" +#include "intel_winsys.h" +#include "intel_swapbuffers.h" +#include "intel_batchbuffer.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + + + +struct intel_pipe_winsys { + struct pipe_winsys winsys; + struct _DriBufferPool *regionPool; + struct _DriFreeSlabManager *fMan; +}; + + + +/* Turn a pipe winsys into an intel/pipe winsys: + */ +static inline struct intel_pipe_winsys * +intel_pipe_winsys( struct pipe_winsys *winsys ) +{ + return (struct intel_pipe_winsys *)winsys; +} + + +/* Most callbacks map direcly onto dri_bufmgr operations: + */ +static void *intel_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags ) +{ + unsigned drm_flags = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + drm_flags |= DRM_BO_FLAG_WRITE; + + if (flags & PIPE_BUFFER_USAGE_CPU_READ) + drm_flags |= DRM_BO_FLAG_READ; + + return driBOMap( dri_bo(buf), drm_flags, 0 ); +} + +static void intel_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnmap( dri_bo(buf) ); +} + + +static void +intel_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnReference( dri_bo(buf) ); + FREE(buf); +} + + +/* Pipe has no concept of pools. We choose the tex/region pool + * for all buffers. + * Grabs the hardware lock! + */ +static struct pipe_buffer * +intel_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size ) +{ + struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); + struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); + unsigned flags = 0; + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + if (usage & (PIPE_BUFFER_USAGE_VERTEX /*| IWS_BUFFER_USAGE_LOCAL*/)) { + flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; + } else { + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + } + + if (usage & PIPE_BUFFER_USAGE_GPU_READ) + flags |= DRM_BO_FLAG_READ; + + if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) + flags |= DRM_BO_FLAG_WRITE; + + /* drm complains if we don't set any read/write flags. + */ + if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) + flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + +#if 0 + if (flags & IWS_BUFFER_USAGE_EXE) + flags |= DRM_BO_FLAG_EXE; + + if (usage & IWS_BUFFER_USAGE_CACHED) + flags |= DRM_BO_FLAG_CACHED; +#endif + + driGenBuffers( iws->regionPool, + "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); + + driBOData( buffer->driBO, size, NULL, iws->regionPool, 0 ); + + return &buffer->base; +} + + +static struct pipe_buffer * +intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) +{ + struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); + struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); + + driGenUserBuffer( iws->regionPool, + "pipe user buffer", &buffer->driBO, ptr, bytes ); + + buffer->base.refcount = 1; + + return &buffer->base; +} + + +/* The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +intel_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ +#if 0 + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + intelDisplaySurface(dPriv, surf, NULL); +#endif +} + + +static struct pipe_surface * +intel_i915_surface_alloc(struct pipe_winsys *winsys) +{ + struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); + if (surf) { + surf->refcount = 1; + surf->winsys = winsys; + } + return surf; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +/** + * Copied from xm_winsys.c + */ +static int +intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags) +{ + const unsigned alignment = 64; + //int ret; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if(!surf->buffer) + return -1; + + return 0; +} + + +static void +intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + + +static const char * +intel_get_name( struct pipe_winsys *winsys ) +{ + return "Intel/EGL/ttm"; +} + +static void +intel_fence_reference( struct pipe_winsys *sws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence ) +{ + if (*ptr) + driFenceUnReference((struct _DriFenceObject **)ptr); + + if (fence) + *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); +} + +static int +intel_fence_signalled( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + return driFenceSignaled((struct _DriFenceObject *)fence, flag); +} + +static int +intel_fence_finish( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + /* JB: Lets allways lazy wait */ + return driFenceFinish((struct _DriFenceObject *)fence, flag, 1); +} + +struct pipe_winsys * +intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) +{ + struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys ); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + * + * Pipe would be happy with a malloc based memory manager, but + * the SwapBuffers implementation in this winsys driver requires + * that rendering be done to an appropriate _DriBufferObject. + */ + iws->winsys.buffer_create = intel_buffer_create; + iws->winsys.user_buffer_create = intel_user_buffer_create; + iws->winsys.buffer_map = intel_buffer_map; + iws->winsys.buffer_unmap = intel_buffer_unmap; + iws->winsys.buffer_destroy = intel_buffer_destroy; + iws->winsys.flush_frontbuffer = intel_flush_frontbuffer; + iws->winsys.get_name = intel_get_name; + iws->winsys.surface_alloc = intel_i915_surface_alloc; + iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; + iws->winsys.surface_release = intel_i915_surface_release; + + iws->winsys.fence_reference = intel_fence_reference; + iws->winsys.fence_signalled = intel_fence_signalled; + iws->winsys.fence_finish = intel_fence_finish; + + if (fd) + iws->regionPool = driSlabPoolInit(fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + 64, 6, 16, 4096, 0, + fMan); + + return &iws->winsys; +} + + +void +intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) +{ + struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); + if (iws->regionPool) { + driPoolTakeDown(iws->regionPool); + } + free(iws); +} + diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c new file mode 100644 index 0000000000..0bc2dc4002 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c @@ -0,0 +1,82 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include "intel_context.h" +#include "intel_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_format.h" +#include "softpipe/sp_winsys.h" + + +struct intel_softpipe_winsys { + struct softpipe_winsys sws; + struct intel_context *intel; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean +intel_is_format_supported(struct softpipe_winsys *sws, + enum pipe_format format) +{ + switch(format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: + return TRUE; + default: + return FALSE; + } +} + + +/** + * Create rendering context which uses software rendering. + */ +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ) +{ + struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); + struct pipe_screen *screen = softpipe_create_screen(winsys); + + /* Fill in this struct with callbacks that softpipe will need to + * communicate with the window system, buffer manager, etc. + */ + isws->sws.is_format_supported = intel_is_format_supported; + isws->intel = intel; + + /* Create the softpipe context: + */ + return softpipe_create( screen, winsys, &isws->sws ); +} diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c new file mode 100644 index 0000000000..1bc1089352 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c @@ -0,0 +1,953 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + * Keith Whitwell + */ + +#include +#include +#include "glthread.h" +#include "errno.h" +#include "ws_dri_bufmgr.h" +#include "string.h" +#include "imports.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" + +/* + * This lock is here to protect drmBO structs changing underneath us during a + * validate list call, since validatelist cannot take individiual locks for + * each drmBO. Validatelist takes this lock in write mode. Any access to an + * individual drmBO should take this lock in read mode, since in that case, the + * driBufferObject mutex will protect the access. Locking order is + * driBufferObject mutex - > this rw lock. + */ + +_glthread_DECLARE_STATIC_MUTEX(bmMutex); +_glthread_DECLARE_STATIC_COND(bmCond); + +static int kernelReaders = 0; +static int num_buffers = 0; +static int num_user_buffers = 0; + +static drmBO *drmBOListBuf(void *iterator) +{ + drmBONode *node; + drmMMListHead *l = (drmMMListHead *) iterator; + node = DRMLISTENTRY(drmBONode, l, head); + return node->buf; +} + +static void *drmBOListIterator(drmBOList *list) +{ + void *ret = list->list.next; + + if (ret == &list->list) + return NULL; + return ret; +} + +static void *drmBOListNext(drmBOList *list, void *iterator) +{ + void *ret; + + drmMMListHead *l = (drmMMListHead *) iterator; + ret = l->next; + if (ret == &list->list) + return NULL; + return ret; +} + +static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, + uint64_t arg0, + uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } + else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADD(&node->head, &list->list); + list->numOnList++; + return node; +} + +static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, + uint64_t mask, int *newItem) +{ + drmBONode *node, *cur; + drmMMListHead *l; + + *newItem = 0; + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + } + if (!cur) { + cur = drmAddListItem(list, buf, flags, mask); + if (!cur) { + return -ENOMEM; + } + *newItem = 1; + cur->arg0 = flags; + cur->arg1 = mask; + } + else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + return 0; +} + +static void drmBOFreeList(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->list.next; + while(l != &list->list) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->list.next; + list->numCurrent--; + list->numOnList--; + } + + l = list->free.next; + while(l != &list->free) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->free.next; + list->numCurrent--; + } +} + +static int drmAdjustListNodes(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + int ret = 0; + + while(list->numCurrent < list->numTarget) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + ret = -ENOMEM; + break; + } + list->numCurrent++; + DRMLISTADD(&node->head, &list->free); + } + + while(list->numCurrent > list->numTarget) { + l = list->free.next; + if (l == &list->free) + break; + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + list->numCurrent--; + } + return ret; +} + +static int drmBOCreateList(int numTarget, drmBOList *list) +{ + DRMINITLISTHEAD(&list->list); + DRMINITLISTHEAD(&list->free); + list->numTarget = numTarget; + list->numCurrent = 0; + list->numOnList = 0; + return drmAdjustListNodes(list); +} + +static int drmBOResetList(drmBOList *list) +{ + drmMMListHead *l; + int ret; + + ret = drmAdjustListNodes(list); + if (ret) + return ret; + + l = list->list.next; + while (l != &list->list) { + DRMLISTDEL(l); + DRMLISTADD(l, &list->free); + list->numOnList--; + l = list->list.next; + } + return drmAdjustListNodes(list); +} + +void driWriteLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + while(kernelReaders != 0) + _glthread_COND_WAIT(bmCond, bmMutex); +} + +void driWriteUnlockKernelBO(void) +{ + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + kernelReaders++; + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadUnlockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + if (--kernelReaders == 0) + _glthread_COND_BROADCAST(bmCond); + _glthread_UNLOCK_MUTEX(bmMutex); +} + + + + +/* + * TODO: Introduce fence pools in the same way as + * buffer object pools. + */ + +typedef struct _DriBufferObject +{ + DriBufferPool *pool; + _glthread_Mutex mutex; + int refCount; + const char *name; + uint64_t flags; + unsigned hint; + unsigned alignment; + unsigned createdByReference; + void *private; + /* user-space buffer: */ + unsigned userBuffer; + void *userData; + unsigned userSize; +} DriBufferObject; + +typedef struct _DriBufferList { + drmBOList drmBuffers; /* List of kernel buffers needing validation */ + drmBOList driBuffers; /* List of user-space buffers needing validation */ +} DriBufferList; + + +void +bmError(int val, const char *file, const char *function, int line) +{ + _mesa_printf("Fatal video memory manager error \"%s\".\n" + "Check kernel logs or set the LIBGL_DEBUG\n" + "environment variable to \"verbose\" for more info.\n" + "Detected in file %s, line %d, function %s.\n", + strerror(-val), file, line, function); +#ifndef NDEBUG + abort(); +#else + abort(); +#endif +} + +extern drmBO * +driBOKernel(struct _DriBufferObject *buf) +{ + drmBO *ret; + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + ret = buf->pool->kernel(buf->pool, buf->private); + if (!ret) + BM_CKFATAL(-EINVAL); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + + return ret; +} + +void +driBOWaitIdle(struct _DriBufferObject *buf, int lazy) +{ + + /* + * This function may block. Is it sane to keep the mutex held during + * that time?? + */ + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void * +driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) +{ + void *virtual; + int retval; + + if (buf->userBuffer) { + return buf->userData; + } + + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + retval = buf->pool->map(buf->pool, buf->private, flags, hint, + &buf->mutex, &virtual); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval == 0 ? virtual : NULL; +} + +void +driBOUnmap(struct _DriBufferObject *buf) +{ + if (buf->userBuffer) + return; + + assert(buf->private != NULL); + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +unsigned long +driBOOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->offset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +unsigned long +driBOPoolOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->poolOffset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +uint64_t +driBOFlags(struct _DriBufferObject *buf) +{ + uint64_t ret; + + assert(buf->private != NULL); + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->flags(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + return ret; +} + +struct _DriBufferObject * +driBOReference(struct _DriBufferObject *buf) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (++buf->refCount == 1) { + _glthread_UNLOCK_MUTEX(buf->mutex); + BM_CKFATAL(-EINVAL); + } + _glthread_UNLOCK_MUTEX(buf->mutex); + return buf; +} + +void +driBOUnReference(struct _DriBufferObject *buf) +{ + int tmp; + + if (!buf) + return; + + _glthread_LOCK_MUTEX(buf->mutex); + tmp = --buf->refCount; + if (!tmp) { + _glthread_UNLOCK_MUTEX(buf->mutex); + if (buf->private) { + if (buf->createdByReference) + buf->pool->unreference(buf->pool, buf->private); + else + buf->pool->destroy(buf->pool, buf->private); + } + if (buf->userBuffer) + num_user_buffers--; + else + num_buffers--; + free(buf); + } else + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + + +int +driBOData(struct _DriBufferObject *buf, + unsigned size, const void *data, + DriBufferPool *newPool, + uint64_t flags) +{ + void *virtual = NULL; + int newBuffer; + int retval = 0; + struct _DriBufferPool *pool; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + pool = buf->pool; + + if (pool == NULL && newPool != NULL) { + buf->pool = newPool; + pool = newPool; + } + if (newPool == NULL) + newPool = pool; + + if (!pool->create) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "driBOData called on invalid buffer\n"); + BM_CKFATAL(-EINVAL); + } + + newBuffer = (!buf->private || pool != newPool || + pool->size(pool, buf->private) < size); + + if (!flags) + flags = buf->flags; + + if (newBuffer) { + + if (buf->createdByReference) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "driBOData requiring resizing called on " + "shared buffer.\n"); + BM_CKFATAL(-EINVAL); + } + + if (buf->private) + buf->pool->destroy(buf->pool, buf->private); + + pool = newPool; + buf->pool = newPool; + buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (!buf->private) + retval = -ENOMEM; + + if (retval == 0) + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); + } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { + /* + * Buffer is busy. need to create a new one. + */ + + void *newBuf; + + newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (newBuf) { + buf->pool->destroy(buf->pool, buf->private); + buf->private = newBuf; + } + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } else { + uint64_t flag_diff = flags ^ buf->flags; + + /* + * We might need to change buffer flags. + */ + + if (flag_diff){ + assert(pool->setStatus != NULL); + BM_CKFATAL(pool->unmap(pool, buf->private)); + BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, + buf->flags)); + if (!data) + goto out; + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } + } + + if (retval == 0) { + if (data) + memcpy(virtual, data, size); + + BM_CKFATAL(pool->unmap(pool, buf->private)); + } + + out: + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval; +} + +void +driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, const void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, + &virtual)); + memcpy((unsigned char *) virtual + offset, data, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); + memcpy(data, (unsigned char *) virtual + offset, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->private != NULL) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "Invalid buffer for setReferenced\n"); + BM_CKFATAL(-EINVAL); + + } + if (buf->pool->reference == NULL) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "Invalid buffer pool for setReferenced\n"); + BM_CKFATAL(-EINVAL); + } + buf->private = buf->pool->reference(buf->pool, handle); + if (!buf->private) { + _mesa_error(NULL, GL_OUT_OF_MEMORY, + "Invalid buffer pool for setStatic\n"); + BM_CKFATAL(-ENOMEM); + } + buf->createdByReference = GL_TRUE; + buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +int +driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint) +{ + struct _DriBufferObject *buf; + int i; + + flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + ++num_buffers; + + assert(pool); + + for (i = 0; i < n; ++i) { + buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); + if (!buf) + return -ENOMEM; + + _glthread_INIT_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(buf->mutex); + buf->refCount = 1; + buf->flags = flags; + buf->hint = hint; + buf->name = name; + buf->alignment = alignment; + buf->pool = pool; + buf->createdByReference = 0; + _glthread_UNLOCK_MUTEX(buf->mutex); + buffers[i] = buf; + } + return 0; +} + +void +driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject **buffers, + void *ptr, unsigned bytes) +{ + const unsigned alignment = 1, flags = 0, hint = 0; + + --num_buffers; /* JB: is inced in GenBuffes */ + driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); + ++num_user_buffers; + + (*buffers)->userBuffer = 1; + (*buffers)->userData = ptr; + (*buffers)->userSize = bytes; +} + +void +driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) +{ + int i; + + for (i = 0; i < n; ++i) { + driBOUnReference(buffers[i]); + } +} + + +void +driInitBufMgr(int fd) +{ + ; +} + +/* + * Note that lists are per-context and don't need mutex protection. + */ + +struct _DriBufferList * +driBOCreateList(int target) +{ + struct _DriBufferList *list = calloc(sizeof(*list), 1); + + BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); + BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); + return list; +} + +int +driBOResetList(struct _DriBufferList * list) +{ + int ret; + ret = drmBOResetList(&list->drmBuffers); + if (ret) + return ret; + ret = drmBOResetList(&list->driBuffers); + return ret; +} + +void +driBOFreeList(struct _DriBufferList * list) +{ + drmBOFreeList(&list->drmBuffers); + drmBOFreeList(&list->driBuffers); + free(list); +} + + +/* + * Copied from libdrm, because it is needed by driAddValidateItem. + */ + +static drmBONode * +driAddListItem(drmBOList * list, drmBO * item, + uint64_t arg0, uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + memset(&node->bo_arg, 0, sizeof(node->bo_arg)); + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADDTAIL(&node->head, &list->list); + list->numOnList++; + return node; +} + +/* + * Slightly modified version compared to the libdrm version. + * This one returns the list index of the buffer put on the list. + */ + +static int +driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, + uint64_t mask, int *itemLoc, + struct _drmBONode **pnode) +{ + drmBONode *node, *cur; + drmMMListHead *l; + int count = 0; + + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + count++; + } + if (!cur) { + cur = driAddListItem(list, buf, flags, mask); + if (!cur) + return -ENOMEM; + + cur->arg0 = flags; + cur->arg1 = mask; + } else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + *itemLoc = count; + *pnode = cur; + return 0; +} + + +void +driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node) +{ + int newItem; + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(driAddValidateItem(&list->drmBuffers, + buf->pool->kernel(buf->pool, buf->private), + flags, mask, itemLoc, node)); + BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, + flags, mask, &newItem)); + if (newItem) + buf->refCount++; + + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +drmBOList *driGetdrmBOList(struct _DriBufferList *list) +{ + driWriteLockKernelBO(); + return &list->drmBuffers; +} + +void driPutdrmBOList(struct _DriBufferList *list) +{ + driWriteUnlockKernelBO(); +} + + +void +driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->fence) + BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + +void +driBOUnrefUserList(struct _DriBufferList *list) +{ + struct _DriBufferObject *buf; + void *curBuf; + + curBuf = drmBOListIterator(&list->driBuffers); + while (curBuf) { + buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + +struct _DriFenceObject * +driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, const char *name, + drmFence *kFence) +{ + struct _DriFenceObject *fence; + struct _DriBufferObject *buf; + void *curBuf; + + fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, + kFence, sizeof(*kFence)); + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space fencing callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + driBOFence(buf, fence); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } + + driBOResetList(list); + return fence; +} + +void +driBOValidateUserList(struct _DriBufferList * list) +{ + void *curBuf; + struct _DriBufferObject *buf; + + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space validation callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->validate) + BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); + _glthread_UNLOCK_MUTEX(buf->mutex); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + + +void +driPoolTakeDown(struct _DriBufferPool *pool) +{ + pool->takeDown(pool); + +} + +unsigned long +driBOSize(struct _DriBufferObject *buf) +{ + unsigned long size; + + _glthread_LOCK_MUTEX(buf->mutex); + size = buf->pool->size(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return size; + +} + +drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) +{ + return &list->drmBuffers; +} + +drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) +{ + return &list->driBuffers; +} + diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h new file mode 100644 index 0000000000..fdaf5ee93a --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + * Keith Whitwell + */ + +#ifndef _PSB_BUFMGR_H_ +#define _PSB_BUFMGR_H_ +#include +#include "i915_drm.h" +#include "ws_dri_fencemgr.h" + +typedef struct _drmBONode +{ + drmMMListHead head; + drmBO *buf; + struct drm_i915_op_arg bo_arg; + uint64_t arg0; + uint64_t arg1; +} drmBONode; + +typedef struct _drmBOList { + unsigned numTarget; + unsigned numCurrent; + unsigned numOnList; + drmMMListHead list; + drmMMListHead free; +} drmBOList; + + +struct _DriFenceObject; +struct _DriBufferObject; +struct _DriBufferPool; +struct _DriBufferList; + +/* + * Return a pointer to the libdrm buffer object this DriBufferObject + * uses. + */ + +extern drmBO *driBOKernel(struct _DriBufferObject *buf); +extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, + unsigned hint); +extern void driBOUnmap(struct _DriBufferObject *buf); +extern unsigned long driBOOffset(struct _DriBufferObject *buf); +extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); + +extern uint64_t driBOFlags(struct _DriBufferObject *buf); +extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); +extern void driBOUnReference(struct _DriBufferObject *buf); + +extern int driBOData(struct _DriBufferObject *r_buf, + unsigned size, const void *data, + struct _DriBufferPool *pool, uint64_t flags); + +extern void driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + const void *data); +extern void driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + void *data); +extern int driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint); +extern void driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject *buffers[], + void *ptr, unsigned bytes); +extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); +extern void driInitBufMgr(int fd); +extern struct _DriBufferList *driBOCreateList(int target); +extern int driBOResetList(struct _DriBufferList * list); +extern void driBOAddListItem(struct _DriBufferList * list, + struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node); + +extern void driBOValidateList(int fd, struct _DriBufferList * list); +extern void driBOFreeList(struct _DriBufferList * list); +extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, + const char *name, + drmFence *kFence); +extern void driBOUnrefUserList(struct _DriBufferList *list); +extern void driBOValidateUserList(struct _DriBufferList * list); +extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); +extern void driPutdrmBOList(struct _DriBufferList *list); + +extern void driBOFence(struct _DriBufferObject *buf, + struct _DriFenceObject *fence); + +extern void driPoolTakeDown(struct _DriBufferPool *pool); +extern void driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle); +unsigned long driBOSize(struct _DriBufferObject *buf); +extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); +extern void driPoolTakeDown(struct _DriBufferPool *pool); + +extern void driReadLockKernelBO(void); +extern void driReadUnlockKernelBO(void); +extern void driWriteLockKernelBO(void); +extern void driWriteUnlockKernelBO(void); + +/* + * For debugging purposes. + */ + +extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); +extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); +#endif diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h b/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h new file mode 100644 index 0000000000..3a302e13d3 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +#ifndef _PSB_BUFPOOL_H_ +#define _PSB_BUFPOOL_H_ + +#include +#include +struct _DriFenceObject; + +typedef struct _DriBufferPool +{ + int fd; + int (*map) (struct _DriBufferPool * pool, void *private, + unsigned flags, int hint, _glthread_Mutex *mutex, + void **virtual); + int (*unmap) (struct _DriBufferPool * pool, void *private); + int (*destroy) (struct _DriBufferPool * pool, void *private); + unsigned long (*offset) (struct _DriBufferPool * pool, void *private); + unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); + uint64_t (*flags) (struct _DriBufferPool * pool, void *private); + unsigned long (*size) (struct _DriBufferPool * pool, void *private); + void *(*create) (struct _DriBufferPool * pool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment); + void *(*reference) (struct _DriBufferPool * pool, unsigned handle); + int (*unreference) (struct _DriBufferPool * pool, void *private); + int (*fence) (struct _DriBufferPool * pool, void *private, + struct _DriFenceObject * fence); + drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); + int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy); + int (*setStatus) (struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags); + void (*takeDown) (struct _DriBufferPool * pool); + void *data; +} DriBufferPool; + +extern void bmError(int val, const char *file, const char *function, + int line); +#define BM_CKFATAL(val) \ + do{ \ + int tstVal = (val); \ + if (tstVal) \ + bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ + } while(0); + + +/* + * Builtin pools. + */ + +/* + * Kernel buffer objects. Size in multiples of page size. Page size aligned. + */ + +extern struct _DriBufferPool *driDRMPoolInit(int fd); +extern struct _DriBufferPool *driMallocPoolInit(void); + +struct _DriFreeSlabManager; +extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan); +extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); +extern struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); + + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c new file mode 100644 index 0000000000..7c55dbc674 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c @@ -0,0 +1,268 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" +#include "assert.h" + +/* + * Buffer pool implementation using DRM buffer objects as DRI buffer objects. + */ + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + unsigned pageSize = getpagesize(); + + if (!buf) + return NULL; + + if ((alignment > pageSize) && (alignment % pageSize)) { + free(buf); + return NULL; + } + + ret = drmBOCreate(pool->fd, size, alignment / pageSize, + NULL, + flags, hint, buf); + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static void * +pool_reference(struct _DriBufferPool *pool, unsigned handle) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + + if (!buf) + return NULL; + + ret = drmBOReference(pool->fd, handle, buf); + + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unreference(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOMap(pool->fd, buf, flags, hint, virtual); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOUnmap(pool->fd, buf); + driReadUnlockKernelBO(); + + return ret; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long offset; + + driReadLockKernelBO(); + assert(buf->flags & DRM_BO_FLAG_NO_MOVE); + offset = buf->offset; + driReadUnlockKernelBO(); + + return buf->offset; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + uint64_t flags; + + driReadLockKernelBO(); + flags = buf->flags; + driReadUnlockKernelBO(); + + return flags; +} + + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long size; + + driReadLockKernelBO(); + size = buf->size; + driReadUnlockKernelBO(); + + return buf->size; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + /* + * Noop. The kernel handles all fencing. + */ + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + return (drmBO *) private; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); + driReadUnlockKernelBO(); + + return ret; +} + + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + +/*static int +pool_setStatus(struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags) +{ + drmBO *buf = (drmBO *) private; + uint64_t new_flags = old_flags ^ flag_diff; + int ret; + + driReadLockKernelBO(); + ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, + 0, 0, 0); + driReadUnlockKernelBO(); + return ret; +}*/ + +struct _DriBufferPool * +driDRMPoolInit(int fd) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + + if (!pool) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + pool->reference = &pool_reference; + pool->unreference = &pool_unreference; + pool->data = NULL; + return pool; +} diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c new file mode 100644 index 0000000000..1f893b47ce --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c @@ -0,0 +1,377 @@ +#include "ws_dri_fencemgr.h" +#include "glthread.h" +#include +#include +#include + +/* + * Note: Locking order is + * _DriFenceObject::mutex + * _DriFenceMgr::mutex + */ + +struct _DriFenceMgr { + /* + * Constant members. Need no mutex protection. + */ + struct _DriFenceMgrCreateInfo info; + void *private; + + /* + * These members are protected by this->mutex + */ + _glthread_Mutex mutex; + int refCount; + drmMMListHead *heads; + int num_fences; +}; + +struct _DriFenceObject { + + /* + * These members are constant and need no mutex protection. + */ + struct _DriFenceMgr *mgr; + uint32_t fence_class; + uint32_t fence_type; + + /* + * These members are protected by mgr->mutex. + */ + drmMMListHead head; + int refCount; + + /* + * These members are protected by this->mutex. + */ + _glthread_Mutex mutex; + uint32_t signaled_type; + void *private; +}; + +uint32_t +driFenceType(struct _DriFenceObject *fence) +{ + return fence->fence_type; +} + +struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) +{ + struct _DriFenceMgr *tmp; + uint32_t i; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->refCount = 1; + tmp->info = *info; + tmp->num_fences = 0; + tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); + if (!tmp->heads) + goto out_err; + + for (i=0; iinfo.num_classes; ++i) { + DRMINITLISTHEAD(&tmp->heads[i]); + } + _glthread_UNLOCK_MUTEX(tmp->mutex); + return tmp; + + out_err: + if (tmp) + free(tmp); + return NULL; +} + +static void +driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) +{ + struct _DriFenceMgr *mgr = *pMgr; + + *pMgr = NULL; + if (--mgr->refCount == 0) + free(mgr); + else + _glthread_UNLOCK_MUTEX(mgr->mutex); +} + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr) +{ + _glthread_LOCK_MUTEX((*pMgr)->mutex); + driFenceMgrUnrefUnlock(pMgr); +} + +static void +driFenceUnReferenceLocked(struct _DriFenceObject **pFence) +{ + struct _DriFenceObject *fence = *pFence; + struct _DriFenceMgr *mgr = fence->mgr; + + *pFence = NULL; + if (--fence->refCount == 0) { + DRMLISTDELINIT(&fence->head); + if (fence->private) + mgr->info.unreference(mgr, &fence->private); + --mgr->num_fences; + fence->mgr = NULL; + --mgr->refCount; + free(fence); + + } +} + + +static void +driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, + drmMMListHead *list, + uint32_t fence_class, + uint32_t fence_type) +{ + struct _DriFenceObject *entry; + drmMMListHead *prev; + + while(list != &mgr->heads[fence_class]) { + entry = DRMLISTENTRY(struct _DriFenceObject, list, head); + + /* + * Up refcount so that entry doesn't disappear from under us + * when we unlock-relock mgr to get the correct locking order. + */ + + ++entry->refCount; + _glthread_UNLOCK_MUTEX(mgr->mutex); + _glthread_LOCK_MUTEX(entry->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + + prev = list->prev; + + + + if (list->prev == list) { + + /* + * Somebody else removed the entry from the list. + */ + + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + return; + } + + entry->signaled_type |= (fence_type & entry->fence_type); + if (entry->signaled_type == entry->fence_type) { + DRMLISTDELINIT(list); + mgr->info.unreference(mgr, &entry->private); + } + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + list = prev; + } +} + + +int +driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint) +{ + struct _DriFenceMgr *mgr = fence->mgr; + int ret = 0; + + _glthread_LOCK_MUTEX(fence->mutex); + + if ((fence->signaled_type & fence_type) == fence_type) + goto out0; + + ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); + if (ret) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + fence_type); + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) +{ + uint32_t ret; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = fence->signaled_type; + _glthread_UNLOCK_MUTEX(fence->mutex); + + return ret; +} + +int +driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, + uint32_t *signaled) +{ + int ret = 0; + struct _DriFenceMgr *mgr; + + _glthread_LOCK_MUTEX(fence->mutex); + mgr = fence->mgr; + *signaled = fence->signaled_type; + if ((fence->signaled_type & flush_type) == flush_type) + goto out0; + + ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); + if (ret) { + *signaled = fence->signaled_type; + goto out0; + } + + if ((fence->signaled_type | *signaled) == fence->signaled_type) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + *signaled); + + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +struct _DriFenceObject * +driFenceReference(struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(fence->mgr->mutex); + ++fence->refCount; + _glthread_UNLOCK_MUTEX(fence->mgr->mutex); + return fence; +} + +void +driFenceUnReference(struct _DriFenceObject **pFence) +{ + struct _DriFenceMgr *mgr; + + if (*pFence == NULL) + return; + + mgr = (*pFence)->mgr; + _glthread_LOCK_MUTEX(mgr->mutex); + ++mgr->refCount; + driFenceUnReferenceLocked(pFence); + driFenceMgrUnrefUnlock(&mgr); +} + +struct _DriFenceObject +*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, + uint32_t fence_type, void *private, size_t private_size) +{ + struct _DriFenceObject *fence; + size_t fence_size = sizeof(*fence); + + if (private_size) + fence_size = ((fence_size + 15) & ~15); + + fence = calloc(1, fence_size + private_size); + + if (!fence) { + int ret = mgr->info.finish(mgr, private, fence_type, 0); + + if (ret) + usleep(10000000); + + return NULL; + } + + _glthread_INIT_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + fence->refCount = 1; + DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); + fence->mgr = mgr; + ++mgr->refCount; + ++mgr->num_fences; + _glthread_UNLOCK_MUTEX(mgr->mutex); + fence->fence_class = fence_class; + fence->fence_type = fence_type; + fence->signaled_type = 0; + fence->private = private; + if (private_size) { + fence->private = (void *)(((uint8_t *) fence) + fence_size); + memcpy(fence->private, private, private_size); + } + + _glthread_UNLOCK_MUTEX(fence->mutex); + return fence; +} + + +static int +tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type) +{ + long fd = (long) mgr->private; + int dummy; + drmFence *fence = (drmFence *) private; + int ret; + + *signaled_type = 0; + ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); + if (ret) + return ret; + + *signaled_type = fence->signaled; + + return 0; +} + +static int +tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, + int lazy_hint) +{ + long fd = (long) mgr->private; + unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; + + return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); +} + +static int +tUnref(struct _DriFenceMgr *mgr, void **private) +{ + long fd = (long) mgr->private; + drmFence *fence = (drmFence *) *private; + *private = NULL; + + return drmFenceUnreference(fd, fence); +} + +struct _DriFenceMgr *driFenceMgrTTMInit(int fd) +{ + struct _DriFenceMgrCreateInfo info; + struct _DriFenceMgr *mgr; + + info.flags = DRI_FENCE_CLASS_ORDERED; + info.num_classes = 4; + info.signaled = tSignaled; + info.finish = tFinish; + info.unreference = tUnref; + + mgr = driFenceMgrCreate(&info); + if (mgr == NULL) + return NULL; + + mgr->private = (void *) (long) fd; + return mgr; +} + diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h new file mode 100644 index 0000000000..4ea58dfe18 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h @@ -0,0 +1,115 @@ +#ifndef DRI_FENCEMGR_H +#define DRI_FENCEMGR_H + +#include +#include + +struct _DriFenceObject; +struct _DriFenceMgr; + +/* + * Do a quick check to see if the fence manager has registered the fence + * object as signaled. Note that this function may return a false negative + * answer. + */ +extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); + +/* + * Check if the fence object is signaled. This function can be substantially + * more expensive to call than the above function, but will not return a false + * negative answer. The argument "flush_type" sets the types that the + * underlying mechanism must make sure will eventually signal. + */ +extern int driFenceSignaledType(struct _DriFenceObject *fence, + uint32_t flush_type, uint32_t *signaled); + +/* + * Convenience functions. + */ + +static inline int driFenceSignaled(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types; + int ret = driFenceSignaledType(fence, flush_type, &signaled_types); + if (ret) + return 0; + return ((signaled_types & flush_type) == flush_type); +} + +static inline int driFenceSignaledCached(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types = + driFenceSignaledTypeCached(fence); + + return ((signaled_types & flush_type) == flush_type); +} + +/* + * Reference a fence object. + */ +extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); + +/* + * Unreference a fence object. The fence object pointer will be reset to NULL. + */ + +extern void driFenceUnReference(struct _DriFenceObject **pFence); + + +/* + * Wait for a fence to signal the indicated fence_type. + * If "lazy_hint" is true, it indicates that the wait may sleep to avoid + * busy-wait polling. + */ +extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint); + +/* + * Create a DriFenceObject for manager "mgr". + * + * "private" is a pointer that should be used for the callbacks in + * struct _DriFenceMgrCreateInfo. + * + * if private_size is nonzero, then the info stored at *private, with size + * private size will be copied and the fence manager will instead use a + * pointer to the copied data for the callbacks in + * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by + * "private" may be destroyed after the call to driFenceCreate. + */ +extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, + uint32_t fence_class, + uint32_t fence_type, + void *private, + size_t private_size); + +extern uint32_t driFenceType(struct _DriFenceObject *fence); + +/* + * Fence creations are ordered. If a fence signals a fence_type, + * it is safe to assume that all fences of the same class that was + * created before that fence has signaled the same type. + */ + +#define DRI_FENCE_CLASS_ORDERED (1 << 0) + +struct _DriFenceMgrCreateInfo { + uint32_t flags; + uint32_t num_classes; + int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type); + int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); + int (*unreference) (struct _DriFenceMgr *mgr, void **private); +}; + +extern struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr); + +extern struct _DriFenceMgr * +driFenceMgrTTMInit(int fd); + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c new file mode 100644 index 0000000000..bf97d7e440 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c @@ -0,0 +1,162 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +#include +#include +#include +#include "imports.h" +#include "glthread.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" +#include "intel_screen.h" + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + unsigned long *private = malloc(size + 2*sizeof(unsigned long)); + if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) + abort(); + + *private = size; + return (void *)private; +} + + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + free(private); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + *virtual = (void *)((unsigned long *)private + 2); + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); + return 0UL; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + return *(unsigned long *) private; +} + + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + abort(); + return 0UL; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + abort(); + return NULL; +} + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + + +struct _DriBufferPool * +driMallocPoolInit(void) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + if (!pool) + return NULL; + + pool->data = NULL; + pool->fd = -1; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + return pool; +} diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c new file mode 100644 index 0000000000..e69519a01f --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c @@ -0,0 +1,970 @@ +/************************************************************************** + * + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#include +#include +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" +#include "ws_dri_bufmgr.h" +#include "glthread.h" + +#define DRI_SLABPOOL_ALLOC_RETRIES 100 + +struct _DriSlab; + +struct _DriSlabBuffer { + int isSlabBuffer; + drmBO *bo; + struct _DriFenceObject *fence; + struct _DriSlab *parent; + drmMMListHead head; + uint32_t mapCount; + uint32_t start; + uint32_t fenceType; + int unFenced; + _glthread_Cond event; +}; + +struct _DriKernelBO { + int fd; + drmBO bo; + drmMMListHead timeoutHead; + drmMMListHead head; + struct timeval timeFreed; + uint32_t pageAlignment; + void *virtual; +}; + +struct _DriSlab{ + drmMMListHead head; + drmMMListHead freeBuffers; + uint32_t numBuffers; + uint32_t numFree; + struct _DriSlabBuffer *buffers; + struct _DriSlabSizeHeader *header; + struct _DriKernelBO *kbo; +}; + + +struct _DriSlabSizeHeader { + drmMMListHead slabs; + drmMMListHead freeSlabs; + drmMMListHead delayedBuffers; + uint32_t numDelayed; + struct _DriSlabPool *slabPool; + uint32_t bufSize; + _glthread_Mutex mutex; +}; + +struct _DriFreeSlabManager { + struct timeval slabTimeout; + struct timeval checkInterval; + struct timeval nextCheck; + drmMMListHead timeoutList; + drmMMListHead unCached; + drmMMListHead cached; + _glthread_Mutex mutex; +}; + + +struct _DriSlabPool { + + /* + * The data of this structure remains constant after + * initialization and thus needs no mutex protection. + */ + + struct _DriFreeSlabManager *fMan; + uint64_t proposedFlags; + uint64_t validMask; + uint32_t *bucketSizes; + uint32_t numBuckets; + uint32_t pageSize; + int fd; + int pageAlignment; + int maxSlabSize; + int desiredNumBuffers; + struct _DriSlabSizeHeader *headers; +}; + +/* + * FIXME: Perhaps arrange timeout slabs in size buckets for fast + * retreival?? + */ + + +static inline int +driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) +{ + return ((arg1->tv_sec > arg2->tv_sec) || + ((arg1->tv_sec == arg2->tv_sec) && + (arg1->tv_usec > arg2->tv_usec))); +} + +static inline void +driTimeAdd(struct timeval *arg, struct timeval *add) +{ + unsigned int sec; + + arg->tv_sec += add->tv_sec; + arg->tv_usec += add->tv_usec; + sec = arg->tv_usec / 1000000; + arg->tv_sec += sec; + arg->tv_usec -= sec*1000000; +} + +static void +driFreeKernelBO(struct _DriKernelBO *kbo) +{ + if (!kbo) + return; + + (void) drmBOUnreference(kbo->fd, &kbo->bo); + free(kbo); +} + + +static void +driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, + struct timeval *time) +{ + drmMMListHead *list, *next; + struct _DriKernelBO *kbo; + + if (!driTimeAfterEq(time, &fMan->nextCheck)) + return; + + for (list = fMan->timeoutList.next, next = list->next; + list != &fMan->timeoutList; + list = next, next = list->next) { + + kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); + + if (!driTimeAfterEq(time, &kbo->timeFreed)) + break; + + DRMLISTDELINIT(&kbo->timeoutHead); + DRMLISTDELINIT(&kbo->head); + driFreeKernelBO(kbo); + } + + fMan->nextCheck = *time; + driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); +} + + +/* + * Add a _DriKernelBO to the free slab manager. + * This means that it is available for reuse, but if it's not + * reused in a while, it will be freed. + */ + +static void +driSetKernelBOFree(struct _DriFreeSlabManager *fMan, + struct _DriKernelBO *kbo) +{ + struct timeval time; + + _glthread_LOCK_MUTEX(fMan->mutex); + gettimeofday(&time, NULL); + driTimeAdd(&time, &fMan->slabTimeout); + + kbo->timeFreed = time; + + if (kbo->bo.flags & DRM_BO_FLAG_CACHED) + DRMLISTADD(&kbo->head, &fMan->cached); + else + DRMLISTADD(&kbo->head, &fMan->unCached); + + DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); + driFreeTimeoutKBOsLocked(fMan, &time); + + _glthread_UNLOCK_MUTEX(fMan->mutex); +} + +/* + * Get a _DriKernelBO for us to use as storage for a slab. + * + */ + +static struct _DriKernelBO * +driAllocKernelBO(struct _DriSlabSizeHeader *header) + +{ + struct _DriSlabPool *slabPool = header->slabPool; + struct _DriFreeSlabManager *fMan = slabPool->fMan; + drmMMListHead *list, *next, *head; + uint32_t size = header->bufSize * slabPool->desiredNumBuffers; + struct _DriKernelBO *kbo; + struct _DriKernelBO *kboTmp; + int ret; + + /* + * FIXME: We should perhaps allow some variation in slabsize in order + * to efficiently reuse slabs. + */ + + size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; + size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); + _glthread_LOCK_MUTEX(fMan->mutex); + + kbo = NULL; + + retry: + head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? + &fMan->cached : &fMan->unCached; + + for (list = head->next, next = list->next; + list != head; + list = next, next = list->next) { + + kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); + + if ((kboTmp->bo.size == size) && + (slabPool->pageAlignment == 0 || + (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { + + if (!kbo) + kbo = kboTmp; + + if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) + break; + + } + } + + if (kbo) { + DRMLISTDELINIT(&kbo->head); + DRMLISTDELINIT(&kbo->timeoutHead); + } + + _glthread_UNLOCK_MUTEX(fMan->mutex); + + if (kbo) { + uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; + + ret = 0; + if (new_mask) { + ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, + new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); + } + if (ret == 0) + return kbo; + + driFreeKernelBO(kbo); + kbo = NULL; + goto retry; + } + + kbo = calloc(1, sizeof(struct _DriKernelBO)); + if (!kbo) + return NULL; + + kbo->fd = slabPool->fd; + DRMINITLISTHEAD(&kbo->head); + DRMINITLISTHEAD(&kbo->timeoutHead); + ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, + slabPool->proposedFlags, + DRM_BO_HINT_DONT_FENCE, &kbo->bo); + if (ret) + goto out_err0; + + ret = drmBOMap(kbo->fd, &kbo->bo, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &kbo->virtual); + + if (ret) + goto out_err1; + + ret = drmBOUnmap(kbo->fd, &kbo->bo); + if (ret) + goto out_err1; + + return kbo; + + out_err1: + drmBOUnreference(kbo->fd, &kbo->bo); + out_err0: + free(kbo); + return NULL; +} + + +static int +driAllocSlab(struct _DriSlabSizeHeader *header) +{ + struct _DriSlab *slab; + struct _DriSlabBuffer *buf; + uint32_t numBuffers; + int ret; + int i; + + slab = calloc(1, sizeof(*slab)); + if (!slab) + return -ENOMEM; + + slab->kbo = driAllocKernelBO(header); + if (!slab->kbo) { + ret = -ENOMEM; + goto out_err0; + } + + numBuffers = slab->kbo->bo.size / header->bufSize; + + slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); + if (!slab->buffers) { + ret = -ENOMEM; + goto out_err1; + } + + DRMINITLISTHEAD(&slab->head); + DRMINITLISTHEAD(&slab->freeBuffers); + slab->numBuffers = numBuffers; + slab->numFree = 0; + slab->header = header; + + buf = slab->buffers; + for (i=0; i < numBuffers; ++i) { + buf->parent = slab; + buf->start = i* header->bufSize; + buf->mapCount = 0; + buf->isSlabBuffer = 1; + _glthread_INIT_COND(buf->event); + DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); + slab->numFree++; + buf++; + } + + DRMLISTADDTAIL(&slab->head, &header->slabs); + + return 0; + + out_err1: + driSetKernelBOFree(header->slabPool->fMan, slab->kbo); + free(slab->buffers); + out_err0: + free(slab); + return ret; +} + +/* + * Delete a buffer from the slab header delayed list and put + * it on the slab free list. + */ + +static void +driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) +{ + struct _DriSlab *slab = buf->parent; + struct _DriSlabSizeHeader *header = slab->header; + drmMMListHead *list = &buf->head; + + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &slab->freeBuffers); + slab->numFree++; + + if (slab->head.next == &slab->head) + DRMLISTADDTAIL(&slab->head, &header->slabs); + + if (slab->numFree == slab->numBuffers) { + list = &slab->head; + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &header->freeSlabs); + } + + if (header->slabs.next == &header->slabs || + slab->numFree != slab->numBuffers) { + + drmMMListHead *next; + struct _DriFreeSlabManager *fMan = header->slabPool->fMan; + + for (list = header->freeSlabs.next, next = list->next; + list != &header->freeSlabs; + list = next, next = list->next) { + + slab = DRMLISTENTRY(struct _DriSlab, list, head); + + DRMLISTDELINIT(list); + driSetKernelBOFree(fMan, slab->kbo); + free(slab->buffers); + free(slab); + } + } +} + +static void +driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) +{ + drmMMListHead *list, *prev, *first; + struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + int firstWasSignaled = 1; + int signaled; + int i; + int ret; + + /* + * Rerun the freeing test if the youngest tested buffer + * was signaled, since there might be more idle buffers + * in the delay list. + */ + + while (firstWasSignaled) { + firstWasSignaled = 0; + signaled = 0; + first = header->delayedBuffers.next; + + /* Only examine the oldest 1/3 of delayed buffers: + */ + if (header->numDelayed > 3) { + for (i = 0; i < header->numDelayed; i += 3) { + first = first->next; + } + } + + for (list = first, prev = list->prev; + list != &header->delayedBuffers; + list = prev, prev = list->prev) { + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + slab = buf->parent; + + if (!signaled) { + if (wait) { + ret = driFenceFinish(buf->fence, buf->fenceType, 0); + if (ret) + break; + signaled = 1; + wait = 0; + } else { + signaled = driFenceSignaled(buf->fence, buf->fenceType); + } + if (signaled) { + if (list == first) + firstWasSignaled = 1; + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } + } +} + + +static struct _DriSlabBuffer * +driSlabAllocBuffer(struct _DriSlabSizeHeader *header) +{ + static struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + drmMMListHead *list; + int count = DRI_SLABPOOL_ALLOC_RETRIES; + + _glthread_LOCK_MUTEX(header->mutex); + while(header->slabs.next == &header->slabs && count > 0) { + driSlabCheckFreeLocked(header, 0); + if (header->slabs.next != &header->slabs) + break; + + _glthread_UNLOCK_MUTEX(header->mutex); + if (count != DRI_SLABPOOL_ALLOC_RETRIES) + usleep(1); + _glthread_LOCK_MUTEX(header->mutex); + (void) driAllocSlab(header); + count--; + } + + list = header->slabs.next; + if (list == &header->slabs) { + _glthread_UNLOCK_MUTEX(header->mutex); + return NULL; + } + slab = DRMLISTENTRY(struct _DriSlab, list, head); + if (--slab->numFree == 0) + DRMLISTDELINIT(list); + + list = slab->freeBuffers.next; + DRMLISTDELINIT(list); + + _glthread_UNLOCK_MUTEX(header->mutex); + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + return buf; +} + +static void * +pool_create(struct _DriBufferPool *driPool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment) +{ + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + struct _DriSlabSizeHeader *header; + struct _DriSlabBuffer *buf; + void *dummy; + int i; + int ret; + + /* + * FIXME: Check for compatibility. + */ + header = pool->headers; + for (i=0; inumBuckets; ++i) { + if (header->bufSize >= size) + break; + header++; + } + + if (i < pool->numBuckets) + return driSlabAllocBuffer(header); + + + /* + * Fall back to allocate a buffer object directly from DRM. + * and wrap it in a driBO structure. + */ + + + buf = calloc(1, sizeof(*buf)); + + if (!buf) + return NULL; + + buf->bo = calloc(1, sizeof(*buf->bo)); + if (!buf->bo) + goto out_err0; + + if (alignment) { + if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) + goto out_err1; + if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) + goto out_err1; + } + + ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, + flags, hint, buf->bo); + if (ret) + goto out_err1; + + ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &dummy); + if (ret) + goto out_err2; + + ret = drmBOUnmap(pool->fd, buf->bo); + if (ret) + goto out_err2; + + return buf; + out_err2: + drmBOUnreference(pool->fd, buf->bo); + out_err1: + free(buf->bo); + out_err0: + free(buf); + return NULL; +} + +static int +pool_destroy(struct _DriBufferPool *driPool, void *private) +{ + struct _DriSlabBuffer *buf = + (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + int ret; + + ret = drmBOUnreference(pool->fd, buf->bo); + free(buf->bo); + free(buf); + return ret; + } + + slab = buf->parent; + header = slab->header; + + _glthread_LOCK_MUTEX(header->mutex); + buf->unFenced = 0; + buf->mapCount = 0; + + if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { + DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); + header->numDelayed++; + } else { + if (buf->fence) + driFenceUnReference(&buf->fence); + driSlabFreeBufferLocked(buf); + } + + _glthread_UNLOCK_MUTEX(header->mutex); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *driPool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + while(buf->unFenced) + _glthread_COND_WAIT(buf->event, *mutex); + + if (!buf->fence) + return 0; + + driFenceFinish(buf->fence, buf->fenceType, lazy); + driFenceUnReference(&buf->fence); + + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + int busy; + + if (buf->isSlabBuffer) + busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); + else + busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); + + + if (busy) { + if (hint & DRM_BO_HINT_DONT_BLOCK) + return -EBUSY; + else { + (void) pool_waitIdle(pool, private, mutex, 0); + } + } + + ++buf->mapCount; + *virtual = (buf->isSlabBuffer) ? + (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : + (void *) buf->bo->virtual; + + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + --buf->mapCount; + if (buf->mapCount == 0 && buf->isSlabBuffer) + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return buf->bo->offset; + } + + slab = buf->parent; + header = slab->header; + + (void) header; + assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return slab->kbo->bo.offset + buf->start; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return buf->start; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return buf->bo->flags; + + return buf->parent->kbo->bo.flags; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + if (!buf->isSlabBuffer) + return buf->bo->size; + + return buf->parent->header->bufSize; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + drmBO *bo; + + if (buf->fence) + driFenceUnReference(&buf->fence); + + buf->fence = driFenceReference(fence); + bo = (buf->isSlabBuffer) ? + &buf->parent->kbo->bo: + buf->bo; + buf->fenceType = bo->fenceFlags; + + buf->unFenced = 0; + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf) + return NULL; + + return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; +} + +static int +pool_validate(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return 0; + + while(buf->mapCount != 0) + _glthread_COND_WAIT(buf->event, *mutex); + + buf->unFenced = 1; + return 0; +} + + +struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) +{ + struct _DriFreeSlabManager *tmp; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; + tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; + tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; + + tmp->checkInterval.tv_usec = checkIntervalMsec*1000; + tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; + tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; + + gettimeofday(&tmp->nextCheck, NULL); + driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); + DRMINITLISTHEAD(&tmp->timeoutList); + DRMINITLISTHEAD(&tmp->unCached); + DRMINITLISTHEAD(&tmp->cached); + _glthread_UNLOCK_MUTEX(tmp->mutex); + + return tmp; +} + +void +driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) +{ + struct timeval time; + + time = fMan->nextCheck; + driTimeAdd(&time, &fMan->checkInterval); + + _glthread_LOCK_MUTEX(fMan->mutex); + driFreeTimeoutKBOsLocked(fMan, &time); + _glthread_UNLOCK_MUTEX(fMan->mutex); + + assert(fMan->timeoutList.next == &fMan->timeoutList); + assert(fMan->unCached.next == &fMan->unCached); + assert(fMan->cached.next == &fMan->cached); + + free(fMan); +} + +static void +driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, + struct _DriSlabSizeHeader *header) +{ + _glthread_INIT_MUTEX(header->mutex); + _glthread_LOCK_MUTEX(header->mutex); + + DRMINITLISTHEAD(&header->slabs); + DRMINITLISTHEAD(&header->freeSlabs); + DRMINITLISTHEAD(&header->delayedBuffers); + + header->numDelayed = 0; + header->slabPool = pool; + header->bufSize = size; + + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +driFinishSizeHeader(struct _DriSlabSizeHeader *header) +{ + drmMMListHead *list, *next; + struct _DriSlabBuffer *buf; + + _glthread_LOCK_MUTEX(header->mutex); + for (list = header->delayedBuffers.next, next = list->next; + list != &header->delayedBuffers; + list = next, next = list->next) { + + buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); + if (buf->fence) { + (void) driFenceFinish(buf->fence, buf->fenceType, 0); + driFenceUnReference(&buf->fence); + } + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +pool_takedown(struct _DriBufferPool *driPool) +{ + struct _DriSlabPool *pool = driPool->data; + int i; + + for (i=0; inumBuckets; ++i) { + driFinishSizeHeader(&pool->headers[i]); + } + + free(pool->headers); + free(pool->bucketSizes); + free(pool); + free(driPool); +} + +struct _DriBufferPool * +driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan) +{ + struct _DriBufferPool *driPool; + struct _DriSlabPool *pool; + uint32_t i; + + driPool = calloc(1, sizeof(*driPool)); + if (!driPool) + return NULL; + + pool = calloc(1, sizeof(*pool)); + if (!pool) + goto out_err0; + + pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); + if (!pool->bucketSizes) + goto out_err1; + + pool->headers = calloc(numSizes, sizeof(*pool->headers)); + if (!pool->headers) + goto out_err2; + + pool->fMan = fMan; + pool->proposedFlags = flags; + pool->validMask = validMask; + pool->numBuckets = numSizes; + pool->pageSize = getpagesize(); + pool->fd = fd; + pool->pageAlignment = pageAlignment; + pool->maxSlabSize = maxSlabSize; + pool->desiredNumBuffers = desiredNumBuffers; + + for (i=0; inumBuckets; ++i) { + pool->bucketSizes[i] = (smallestSize << i); + driInitSizeHeader(pool, pool->bucketSizes[i], + &pool->headers[i]); + } + + driPool->data = (void *) pool; + driPool->map = &pool_map; + driPool->unmap = &pool_unmap; + driPool->destroy = &pool_destroy; + driPool->offset = &pool_offset; + driPool->poolOffset = &pool_poolOffset; + driPool->flags = &pool_flags; + driPool->size = &pool_size; + driPool->create = &pool_create; + driPool->fence = &pool_fence; + driPool->kernel = &pool_kernel; + driPool->validate = &pool_validate; + driPool->waitIdle = &pool_waitIdle; + driPool->takeDown = &pool_takedown; + + return driPool; + + out_err2: + free(pool->bucketSizes); + out_err1: + free(pool); + out_err0: + free(driPool); + + return NULL; +} -- cgit v1.2.3 From 45fd9ec462bf338b286d3b757c3e67d54f663dad Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 22 May 2008 16:42:53 +0200 Subject: i915: Use the malloc pool for constant buffers since they don't go to the GPU directly. --- src/gallium/winsys/dri/intel/intel_winsys.h | 2 +- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 29 ++++++++++++------------ 2 files changed, 16 insertions(+), 15 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys.h b/src/gallium/winsys/dri/intel/intel_winsys.h index d0a319f9a4..3d32db10a4 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys.h +++ b/src/gallium/winsys/dri/intel/intel_winsys.h @@ -53,6 +53,7 @@ intel_create_i915simple( struct intel_context *intel, struct intel_buffer { struct pipe_buffer base; + struct _DriBufferPool *pool; struct _DriBufferObject *driBO; }; @@ -69,5 +70,4 @@ dri_bo( struct pipe_buffer *buf ) } - #endif diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 44baa6d9fa..7b1c0acfc9 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -50,6 +50,7 @@ struct intel_pipe_winsys { struct pipe_winsys winsys; struct _DriBufferPool *regionPool; + struct _DriBufferPool *mallocPool; struct _DriFreeSlabManager *fMan; }; @@ -110,16 +111,19 @@ intel_buffer_create(struct pipe_winsys *winsys, struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); unsigned flags = 0; + struct _DriBufferPool *pool; buffer->base.refcount = 1; buffer->base.alignment = alignment; buffer->base.usage = usage; buffer->base.size = size; - if (usage & (PIPE_BUFFER_USAGE_VERTEX /*| IWS_BUFFER_USAGE_LOCAL*/)) { + if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; + pool = iws->mallocPool; } else { flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + pool = iws->regionPool; } if (usage & PIPE_BUFFER_USAGE_GPU_READ) @@ -141,10 +145,11 @@ intel_buffer_create(struct pipe_winsys *winsys, flags |= DRM_BO_FLAG_CACHED; #endif - driGenBuffers( iws->regionPool, + buffer->pool = pool; + driGenBuffers( buffer->pool, "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); - driBOData( buffer->driBO, size, NULL, iws->regionPool, 0 ); + driBOData( buffer->driBO, size, NULL, buffer->pool, 0 ); return &buffer->base; } @@ -278,8 +283,7 @@ intel_fence_finish( struct pipe_winsys *sws, struct pipe_fence_handle *fence, unsigned flag ) { - /* JB: Lets allways lazy wait */ - return driFenceFinish((struct _DriFenceObject *)fence, flag, 1); + return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); } struct pipe_winsys * @@ -310,15 +314,9 @@ intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) iws->winsys.fence_finish = intel_fence_finish; if (fd) - iws->regionPool = driSlabPoolInit(fd, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - 64, 6, 16, 4096, 0, - fMan); + iws->regionPool = driDRMPoolInit(fd); + + iws->mallocPool = driMallocPoolInit(); return &iws->winsys; } @@ -331,6 +329,9 @@ intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) if (iws->regionPool) { driPoolTakeDown(iws->regionPool); } + if (iws->mallocPool) { + driPoolTakeDown(iws->mallocPool); + } free(iws); } -- cgit v1.2.3 From 01cc1eebe92441ec33e951b95f0a5b52721741f0 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 23 May 2008 11:14:12 +0200 Subject: i915: Make batchbuffers larger. --- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 2 +- src/gallium/winsys/dri/intel/intel_screen.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 3a8591b580..aa2eed53b8 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -65,7 +65,7 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch) driBOUnrefUserList(batch->list); driBOResetList(batch->list); - batch->size = 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize; + batch->size = 4 * 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize; driBOData(batch->buffer, batch->size, NULL, NULL, 0); /* diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index a3fc6d7344..58bebbe972 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -200,7 +200,7 @@ intelCreatePools(__DRIscreenPrivate * sPriv) DRM_BO_FLAG_MEM_TT, DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, - 4096, //intelScreen->maxBatchSize, + 4 * 4096, //intelScreen->maxBatchSize, 1, 40, 16*16384, 0, intelScreen->fMan); #endif -- cgit v1.2.3 From d607a02da929cd192a3b0896c38dbb468ffa5b0d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 23 May 2008 11:24:33 +0200 Subject: i915: Made EGL report the actual modes on the screen/output pair --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index a9c0218455..ac1825210e 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -94,6 +94,18 @@ drm_update_res(struct drm_driver *drm_drv) drm_drv->res = drmModeGetResources(drm_drv->device->drmFD); } +static void +drm_add_modes_from_output(_EGLScreen *screen, drmModeOutputPtr output) +{ + struct drm_mode_modeinfo *m; + int i; + + for (i = 0; i < output->count_modes; i++) { + m = &output->modes[i]; + _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name); + } +} + static EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) { @@ -137,7 +149,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) screen->output = output; _eglInitScreen(&screen->base); _eglAddScreen(disp, &screen->base); - _eglAddNewMode(&screen->base, 1024, 768, 60 * 1000, "1024x768-60"); + drm_add_modes_from_output(&screen->base, output); } /* for now we only have one config */ @@ -396,7 +408,7 @@ drm_find_mode(drmModeOutputPtr output, _EGLMode *mode) for (i = 0; i < output->count_modes; i++) { m = &output->modes[i]; - if (m->hdisplay == mode->Width && m->vdisplay == mode->Height) + if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) break; m = NULL; } -- cgit v1.2.3 From 5bf6ffb0b2be34ffb000e9700861b177afa9df97 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 23 May 2008 16:11:38 +0200 Subject: i915: Improved vertex buffer performance --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 7b1c0acfc9..62b43cc395 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -51,7 +51,8 @@ struct intel_pipe_winsys { struct pipe_winsys winsys; struct _DriBufferPool *regionPool; struct _DriBufferPool *mallocPool; - struct _DriFreeSlabManager *fMan; + struct _DriBufferPool *vertexPool; + struct _DriFreeSlabManager *fMan; /** shared between all pipes */ }; @@ -119,8 +120,12 @@ intel_buffer_create(struct pipe_winsys *winsys, buffer->base.size = size; if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { - flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; + flags |= DRM_BO_FLAG_MEM_LOCAL; pool = iws->mallocPool; + } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { + /* For vertex buffers */ + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + pool = iws->vertexPool; } else { flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; pool = iws->regionPool; @@ -313,8 +318,19 @@ intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) iws->winsys.fence_signalled = intel_fence_signalled; iws->winsys.fence_finish = intel_fence_finish; - if (fd) + if (fd) { iws->regionPool = driDRMPoolInit(fd); + iws->vertexPool = driSlabPoolInit(fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + 32 * 4096, + 1, 40, 32 * 4096 * 2, 0, + fMan); + } iws->mallocPool = driMallocPoolInit(); -- cgit v1.2.3 From 7fbb61eedd4b07f07007a172cea227d5c363b908 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 23 May 2008 16:55:30 +0200 Subject: i915: Revert accidental change --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 62b43cc395..6a42c79033 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -120,7 +120,7 @@ intel_buffer_create(struct pipe_winsys *winsys, buffer->base.size = size; if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { - flags |= DRM_BO_FLAG_MEM_LOCAL; + flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; pool = iws->mallocPool; } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { /* For vertex buffers */ -- cgit v1.2.3 From 8f67f98959261d193cb5f3db274b55fb24e2bb1e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 25 May 2008 14:26:18 +1000 Subject: nouveau: missed PCI case --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 792eaaa79e..aca16a8b12 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -310,7 +310,8 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) /* Check current memtype vs requested, if they match do nothing */ if ((nvbo->drm.flags & NOUVEAU_MEM_FB) && (flags & NOUVEAU_BO_VRAM)) return 0; - if ((nvbo->drm.flags & NOUVEAU_MEM_AGP) && (flags & NOUVEAU_BO_GART)) + if ((nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) && + (flags & NOUVEAU_BO_GART)) return 0; if (nvbo->drm.size == 0 && nvbo->sysmem && (flags & NOUVEAU_BO_LOCAL)) return 0; -- cgit v1.2.3 From 77ce568ff704e6cdcfaa557965c894752d19e462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 26 May 2008 20:14:40 +0900 Subject: Remove CVS keywords. --- src/gallium/winsys/dri/intel/server/i830_common.h | 1 - src/gallium/winsys/dri/intel/server/i830_dri.h | 1 - 2 files changed, 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h index f1fd3939ab..f84f453309 100644 --- a/src/gallium/winsys/dri/intel/server/i830_common.h +++ b/src/gallium/winsys/dri/intel/server/i830_common.h @@ -26,7 +26,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ #ifndef _I830_COMMON_H_ #define _I830_COMMON_H_ diff --git a/src/gallium/winsys/dri/intel/server/i830_dri.h b/src/gallium/winsys/dri/intel/server/i830_dri.h index c2a3af8cbf..685de4a551 100644 --- a/src/gallium/winsys/dri/intel/server/i830_dri.h +++ b/src/gallium/winsys/dri/intel/server/i830_dri.h @@ -1,4 +1,3 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ #ifndef _I830_DRI_H #define _I830_DRI_H -- cgit v1.2.3 From c2bd95abf60a8b6ea83dce3fc67603b36f937484 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 May 2008 01:18:45 +0200 Subject: i915: Make EGL_i915 segfault if modesetting is not working --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index ac1825210e..12eeff2b23 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -114,6 +114,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) struct drm_screen *screen = NULL; drmModeOutputPtr output = NULL; drmModeResPtr res = NULL; + unsigned count_outputs = 0; EGLint i; int fd; @@ -131,8 +132,10 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) drm_update_res(drm_drv); res = drm_drv->res; + if (res) + count_outputs = res->count_outputs; - for(i = 0; i < res->count_outputs; i++) { + for(i = 0; i < count_outputs; i++) { output = drmModeGetOutput(fd, res->outputs[i]); if (!output) -- cgit v1.2.3 From ae3795a968f07fc150d4c34aa1a9cd067f33b914 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 May 2008 12:27:27 +0200 Subject: i915: Make EGL_i915 compile --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 12eeff2b23..98dbe26376 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "eglconfig.h" #include "eglcontext.h" @@ -13,7 +14,6 @@ #include "eglscreen.h" #include "eglsurface.h" -#include "glapi.h" #include "intel_egl.h" #include "xf86drm.h" @@ -283,9 +283,9 @@ drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext /* generate handle and insert into hash table */ _eglSaveContext(&c->base); - assert(c->base.Handle); + assert(_eglGetContextHandle(&c->base)); - return c->base.Handle; + return _eglGetContextHandle(&c->base); err_gl: free(context); err_c: -- cgit v1.2.3 From 5d90f97f48f8ba231d52bb1a4758dd37f81ec8d6 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 May 2008 12:27:52 +0200 Subject: i915: Don't segfault on buffer allocation error --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 98dbe26376..809371fdeb 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -479,12 +479,13 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, DRM_BO_FLAG_NO_EVICT, DRM_BO_HINT_DONT_FENCE, &scrn->buffer); - prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); if (ret) { printf("failed to create framebuffer (ret %d)\n", ret); return EGL_FALSE; } + prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); + ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height, 32, 32, pitch, scrn->buffer.handle, -- cgit v1.2.3 From 08130512b9961da76a6385403d56387125df5e8c Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 27 May 2008 13:18:25 +0200 Subject: i915: Made vbuf work --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 10e1a84cc1..059b16be3b 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -328,8 +328,8 @@ intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_TT, - 32 * 4096, - 1, 40, 32 * 4096 * 2, 0, + 128, + 6, 120, 32 * 4096, 0, fMan); } -- cgit v1.2.3 From cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 27 May 2008 19:00:16 +0200 Subject: i915: Made vertex submission eaven faster --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 059b16be3b..fb8f44c845 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -224,7 +224,6 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned tex_usage) { const unsigned alignment = 64; - //int ret; surf->width = width; surf->height = height; @@ -235,7 +234,8 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); + surf->pitch * surf->cpp * surf->height); + if(!surf->buffer) return -1; @@ -328,8 +328,8 @@ intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_TT, - 128, - 6, 120, 32 * 4096, 0, + 128 * 4096, + 1, 120, 128 * 4096 * 4, 0, fMan); } -- cgit v1.2.3 From ce56bcb640072496809d2aefede5a32fe9256ace Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 27 May 2008 21:15:36 +0200 Subject: i915: Prepare for tiled private front and back buffers --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 26 ++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index fb8f44c845..2e6c452cd1 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -212,6 +212,15 @@ round_up(unsigned n, unsigned multiple) return (n + multiple - 1) & ~(multiple - 1); } +static unsigned +power_of_two(unsigned x) +{ + int value = 1; + while (value <= x) + value = value << 1; + return value; +} + /*pipe_buffer_reference(winsys, &i915_render->vbo, NULL);*/ /** * Copied from xm_winsys.c */ @@ -224,18 +233,31 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned tex_usage) { const unsigned alignment = 64; + assert(!surf->buffer); +#if 0 + surf->width = width; + surf->height = round_up(height, 8); + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = power_of_two(MAX2(width * surf->cpp, 512)); + surf->buffer = winsys->buffer_create(winsys, 2*4096, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->height); + + surf->pitch = surf->pitch / surf->cpp; + surf->height = height; +#else surf->width = width; surf->height = height; surf->format = format; surf->cpp = pf_get_size(format); surf->pitch = round_up(width, alignment / surf->cpp); - assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, surf->pitch * surf->cpp * surf->height); - +#endif if(!surf->buffer) return -1; -- cgit v1.2.3 From 2c004a4bece706c590f5ab03432d2aa65d6d0263 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 May 2008 14:22:50 +0200 Subject: i915: DriConfigOptions started complaining on this line --- src/gallium/winsys/dri/intel/intel_screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 58bebbe972..429a2cf8f8 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -50,11 +50,11 @@ PUBLIC const char __driConfigOptions[] = DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY - DRI_CONF_FORCE_S3TC_ENABLE(false) +// DRI_CONF_FORCE_S3TC_ENABLE(false) DRI_CONF_ALLOW_LARGE_TEXTURES(1) DRI_CONF_SECTION_END DRI_CONF_END; -const uint __driNConfigOptions = 4; +const uint __driNConfigOptions = 3; #ifdef USE_NEW_INTERFACE static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; -- cgit v1.2.3 From 0cd75a4c99ec63b514b6fbb53152858fa20f53ec Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 12:54:01 +0200 Subject: i915: Get up to date with the latest EGL changes --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 809371fdeb..41b7eac4ed 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -588,7 +588,7 @@ drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) * plug in API functions. */ _EGLDriver * -_eglMain(_EGLDisplay *dpy) +_eglMain(_EGLDisplay *dpy, const char *args) { struct drm_driver *drm; -- cgit v1.2.3 From 837601af522b9d1e687040015672769392884fa1 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 12:43:09 +0200 Subject: i915: Ops how did that get there --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 2e6c452cd1..b3e5f29c3e 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -220,7 +220,7 @@ power_of_two(unsigned x) value = value << 1; return value; } - /*pipe_buffer_reference(winsys, &i915_render->vbo, NULL);*/ + /** * Copied from xm_winsys.c */ -- cgit v1.2.3 From 79b67d8408d1ba5b2232791ae35e731a5953b52d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 12:44:53 +0200 Subject: i915: Remove last usage of surface_alloc_storage --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 31 +----------------------- 1 file changed, 1 insertion(+), 30 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index b3e5f29c3e..a7f3047352 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -232,36 +232,7 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned flags, unsigned tex_usage) { - const unsigned alignment = 64; - assert(!surf->buffer); -#if 0 - surf->width = width; - surf->height = round_up(height, 8); - surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = power_of_two(MAX2(width * surf->cpp, 512)); - - surf->buffer = winsys->buffer_create(winsys, 2*4096, - PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->height); - - surf->pitch = surf->pitch / surf->cpp; - surf->height = height; -#else - surf->width = width; - surf->height = height; - surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); - - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * surf->height); -#endif - if(!surf->buffer) - return -1; - - return 0; + return -1; } -- cgit v1.2.3 From 056bea86b013858832a6ab390fe6efe310a7bc8f Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 15:49:23 +0200 Subject: i915: Deprecated pipe_winsys buffer functions --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 45 ++++-------------------- 1 file changed, 7 insertions(+), 38 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index a7f3047352..af439a796f 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -190,40 +190,16 @@ intel_flush_frontbuffer( struct pipe_winsys *winsys, intelDisplaySurface(dPriv, surf, NULL); } - +/* + * Deprecated surface functions + */ static struct pipe_surface * intel_i915_surface_alloc(struct pipe_winsys *winsys) { - struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); - if (surf) { - surf->refcount = 1; - surf->winsys = winsys; - } - return surf; + assert("intel_i915_surface_alloc is deprecated" & 0); + return NULL; } - -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - -static unsigned -power_of_two(unsigned x) -{ - int value = 1; - while (value <= x) - value = value << 1; - return value; -} - -/** - * Copied from xm_winsys.c - */ static int intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, @@ -232,21 +208,14 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned flags, unsigned tex_usage) { + assert("intel_i915_surface_alloc_storage is deprecated" & 0); return -1; } - static void intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) { - struct pipe_surface *surf = *s; - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - pipe_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; + assert("intel_i915_surface_release is deprecated" & 0); } -- cgit v1.2.3 From 643cc9387d03b5002a4a1e1a95f0dbcfff83b2d2 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 16:03:21 +0200 Subject: i915: Cleaned up intel_winsys_pipe.c --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 76 ++++++++++++------------ 1 file changed, 39 insertions(+), 37 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index af439a796f..51a79ca535 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -31,8 +31,6 @@ #include #include -//#include "dri_bufpool.h" -//#include "dri_bufmgr.h" #include "intel_context.h" #include "intel_winsys.h" @@ -45,8 +43,6 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" - - struct intel_pipe_winsys { struct pipe_winsys winsys; struct _DriBufferPool *regionPool; @@ -56,7 +52,6 @@ struct intel_pipe_winsys { }; - /* Turn a pipe winsys into an intel/pipe winsys: */ static inline struct intel_pipe_winsys * @@ -66,8 +61,12 @@ intel_pipe_winsys( struct pipe_winsys *winsys ) } -/* Most callbacks map direcly onto dri_bufmgr operations: +/* + * Buffer functions. + * + * Most callbacks map direcly onto dri_bufmgr operations: */ + static void *intel_buffer_map(struct pipe_winsys *winsys, struct pipe_buffer *buf, unsigned flags ) @@ -89,7 +88,6 @@ static void intel_buffer_unmap(struct pipe_winsys *winsys, driBOUnmap( dri_bo(buf) ); } - static void intel_buffer_destroy(struct pipe_winsys *winsys, struct pipe_buffer *buf) @@ -98,11 +96,6 @@ intel_buffer_destroy(struct pipe_winsys *winsys, FREE(buf); } - -/* Pipe has no concept of pools. We choose the tex/region pool - * for all buffers. - * Grabs the hardware lock! - */ static struct pipe_buffer * intel_buffer_create(struct pipe_winsys *winsys, unsigned alignment, @@ -175,24 +168,12 @@ intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) } -/* The state tracker (should!) keep track of whether the fake - * frontbuffer has been touched by any rendering since the last time - * we copied its contents to the real frontbuffer. Our task is easy: - */ -static void -intel_flush_frontbuffer( struct pipe_winsys *winsys, - struct pipe_surface *surf, - void *context_private) -{ - struct intel_context *intel = (struct intel_context *) context_private; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - intelDisplaySurface(dPriv, surf, NULL); -} - /* - * Deprecated surface functions + * Surface functions. + * + * Deprecated! */ + static struct pipe_surface * intel_i915_surface_alloc(struct pipe_winsys *winsys) { @@ -218,13 +199,9 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) assert("intel_i915_surface_release is deprecated" & 0); } - - -static const char * -intel_get_name( struct pipe_winsys *winsys ) -{ - return "Intel/DRI/ttm"; -} +/* + * Fence functions + */ static void intel_fence_reference( struct pipe_winsys *sws, @@ -254,6 +231,33 @@ intel_fence_finish( struct pipe_winsys *sws, return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); } + +/* + * Mixed functions + */ + +static const char * +intel_get_name( struct pipe_winsys *winsys ) +{ + return "Intel/DRI/ttm"; +} + +/* + * The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +intel_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + intelDisplaySurface(dPriv, surf, NULL); +} + struct pipe_winsys * intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) { @@ -300,7 +304,6 @@ intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) return &iws->winsys; } - void intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) { @@ -313,4 +316,3 @@ intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) } free(iws); } - -- cgit v1.2.3 From d0c0c0d1e67f92df8866e6218b868b3de954a5e1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 30 May 2008 00:28:29 +1000 Subject: nouveau: oops, more tex-surfaces fallout --- src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index 755c8b6997..2fab1eab65 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -42,7 +42,8 @@ nouveau_surface_alloc(struct pipe_winsys *ws) static int nouveau_surface_alloc_storage(struct pipe_winsys *ws, struct pipe_surface *surf, unsigned width, unsigned height, - enum pipe_format format, unsigned flags) + enum pipe_format format, unsigned flags, + unsigned tex_usage) { unsigned pitch = ((width * pf_get_size(format)) + 63) & ~63; -- cgit v1.2.3 From bee79eb9b9ef649585dc507dc756b1e79eb00d2c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 29 May 2008 17:02:55 -0600 Subject: egl: new EGL/gallium/softpipe/xlib winsys Checkpoint commit. Most required code is in place, and compiles, but totally untested. --- src/gallium/winsys/egl_xlib/Makefile | 87 ++++++ src/gallium/winsys/egl_xlib/egl_xlib.c | 461 ++++++++++++++++++++++++++++++++ src/gallium/winsys/egl_xlib/sw_winsys.c | 244 +++++++++++++++++ src/gallium/winsys/egl_xlib/sw_winsys.h | 40 +++ 4 files changed, 832 insertions(+) create mode 100644 src/gallium/winsys/egl_xlib/Makefile create mode 100644 src/gallium/winsys/egl_xlib/egl_xlib.c create mode 100644 src/gallium/winsys/egl_xlib/sw_winsys.c create mode 100644 src/gallium/winsys/egl_xlib/sw_winsys.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile new file mode 100644 index 0000000000..fe4b931e30 --- /dev/null +++ b/src/gallium/winsys/egl_xlib/Makefile @@ -0,0 +1,87 @@ +# src/gallium/winsys/egl_xlib/Makefile + +# Build softpipe/xlib/EGL driver library/object: "softpipe_egl.so" + + +TOP = ../../../.. +include $(TOP)/configs/current + + +LIBNAME = softpipe_egl.so + + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + -I$(TOP)/src/egl/main \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/auxiliary + +WINSYS_SOURCES = \ + egl_xlib.c \ + sw_winsys.c + +WINSYS_OBJECTS = $(WINSYS_SOURCES:.c=.o) + + +LIBS = \ + $(GALLIUM_DRIVERS) \ + $(TOP)/src/mesa/libglapi.a \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + + +LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1 + + +.SUFFIXES : .cpp + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $(LOCAL_CFLAGS) $< -o $@ + + + +default: $(TOP)/$(LIB_DIR)/$(LIBNAME) + + +# Make the softpipe_egl.so library +$(TOP)/$(LIB_DIR)/$(LIBNAME): $(WINSYS_OBJECTS) $(LIBS) + $(TOP)/bin/mklib -o $(LIBNAME) \ + -linker "$(CC)" \ + -noprefix \ + -install $(TOP)/$(LIB_DIR) \ + $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) \ + --start-group $(LIBS) --end-group + +# $(GL_LIB_DEPS) + + +depend: $(ALL_SOURCES) + @ echo "running $(MKDEP)" + @ rm -f depend # workaround oops on gutsy?!? + @ touch depend + @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \ + > /dev/null 2>/dev/null + + +install: default + $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) + @if [ -e $(TOP)/$(LIB_DIR) ]; then \ + $(INSTALL) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(INSTALL_DIR)/$(LIB_DIR); \ + fi + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h + +clean: + -rm -f *.o *~ *.bak + + +include depend diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c new file mode 100644 index 0000000000..4741da87cd --- /dev/null +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -0,0 +1,461 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * EGL / softpipe / xlib winsys module + * + * Authors: Brian Paul + */ + + +#include + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "softpipe/sp_winsys.h" + +#include "eglconfig.h" +#include "eglconfigutil.h" +#include "eglcontext.h" +#include "egldisplay.h" +#include "egldriver.h" +#include "eglglobals.h" +#include "egllog.h" +#include "eglsurface.h" + +#include "state_tracker/st_public.h" + +#include "sw_winsys.h" + + +/** subclass of _EGLDriver */ +struct xlib_egl_driver +{ + _EGLDriver Base; /**< base class */ + + struct pipe_winsys *winsys; + struct pipe_screen *screen; +}; + + +/** subclass of _EGLContext */ +struct xlib_egl_context +{ + _EGLContext Base; /**< base class */ + + struct pipe_context *pipe; /**< Gallium driver context */ + struct st_context *Context; /**< Mesa/gallium state tracker context */ +}; + + +/** subclass of _EGLSurface */ +struct xlib_egl_surface +{ + _EGLSurface Base; /**< base class */ + + Display *Dpy; /**< The X Display of the window */ + Window Win; /**< The user-created window ID */ + GC Gc; + XVisualInfo VisInfo; + + struct pipe_winsys *winsys; + + struct st_framebuffer *Framebuffer; +}; + + +/** cast wrapper */ +static INLINE struct xlib_egl_driver * +xlib_egl_driver(_EGLDriver *drv) +{ + return (struct xlib_egl_driver *) drv; +} + + +static struct xlib_egl_surface * +lookup_surface(EGLSurface surf) +{ + _EGLSurface *surface = _eglLookupSurface(surf); + return (struct xlib_egl_surface *) surface; +} + + +static struct xlib_egl_context * +lookup_context(EGLContext surf) +{ + _EGLContext *context = _eglLookupContext(surf); + return (struct xlib_egl_context *) context; +} + + +/** + * XXX temporary + * Need to query X server's GLX visuals. + */ +static void +init_configs(_EGLDriver *drv, EGLDisplay dpy) +{ + _EGLDisplay *disp = _eglLookupDisplay(dpy); + int i; + + for (i = 0; i < 2; i++) { + _EGLConfig config; + int id = i + 1; + _eglInitConfig(&config, id); + SET_CONFIG_ATTRIB(&config, EGL_RED_SIZE, 8); + SET_CONFIG_ATTRIB(&config, EGL_GREEN_SIZE, 8); + SET_CONFIG_ATTRIB(&config, EGL_BLUE_SIZE, 8); + SET_CONFIG_ATTRIB(&config, EGL_ALPHA_SIZE, 8); + if (i > 0) { + SET_CONFIG_ATTRIB(&config, EGL_DEPTH_SIZE, 24); + SET_CONFIG_ATTRIB(&config, EGL_STENCIL_SIZE, 8); + } + _eglAddConfig(disp, &config); + } +} + + + +/** + * Called via eglInitialize(), drv->API.Initialize(). + */ +static EGLBoolean +xlib_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, + EGLint *minor, EGLint *major) +{ + /* visual configs */ + + init_configs(drv, dpy); + + + drv->Initialized = EGL_TRUE; + + /* we're supporting EGL 1.4 */ + *minor = 1; + *major = 4; + + return EGL_TRUE; +} + + +/** + * Called via eglTerminate(), drv->API.Terminate(). + */ +static EGLBoolean +xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) +{ + + return EGL_TRUE; +} + + +/** Get size of given window */ +static Status +get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) +{ + Window root; + Status stat; + int xpos, ypos; + unsigned int w, h, bw, depth; + stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); + *width = w; + *height = h; + return stat; +} + + +static void +display_surface(struct pipe_winsys *pws, + struct pipe_surface *psurf, + struct xlib_egl_surface *xsurf) +{ + XImage *ximage; + void *data; + + ximage = XCreateImage(xsurf->Dpy, + xsurf->VisInfo.visual, + xsurf->VisInfo.depth, + ZPixmap, 0, /* format, offset */ + NULL, /* data */ + 0, 0, /* size */ + 32, /* bitmap_pad */ + 0); /* bytes_per_line */ + + + assert(ximage->format); + assert(ximage->bitmap_unit); + + data = pws->buffer_map(pws, psurf->buffer, 0); + + /* update XImage's fields */ + ximage->data = data; + ximage->width = psurf->width; + ximage->height = psurf->height; + ximage->bytes_per_line = psurf->pitch * psurf->cpp; + + XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc, + ximage, 0, 0, 0, 0, psurf->width, psurf->height); + + ximage->data = NULL; + XDestroyImage(ximage); + + pws->buffer_unmap(pws, psurf->buffer); +} + + + +/** Display gallium surface in X window */ +static void +flush_frontbuffer(struct pipe_winsys *pws, + struct pipe_surface *psurf, + void *context_private) +{ + struct xlib_egl_surface *xsurf = (struct xlib_egl_surface *) context_private; + display_surface(pws, psurf, xsurf); +} + + + +/** + * Called via eglCreateContext(), drv->API.CreateContext(). + */ +static EGLContext +xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + EGLContext share_list, const EGLint *attrib_list) +{ + struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); + _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); + struct xlib_egl_context *ctx; + struct st_context *share_ctx = NULL; /* XXX fix */ + __GLcontextModes visual; + + ctx = CALLOC_STRUCT(xlib_egl_context); + if (!ctx) + return EGL_NO_CONTEXT; + + /* let EGL lib init the common stuff */ + if (!_eglInitContext(drv, dpy, &ctx->Base, config, attrib_list)) { + free(ctx); + return EGL_NO_CONTEXT; + } + + /* create a softpipe context */ + ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL); + + /* Now do xlib / state tracker inits here */ + _eglConfigToContextModesRec(conf, &visual); + ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx); + + + return _eglGetContextHandle(&ctx->Base); +} + + +static EGLBoolean +xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx) +{ + struct xlib_egl_context *context = lookup_context(ctx); + if (context) { + if (context->Base.IsBound) { + context->Base.DeletePending = EGL_TRUE; + } + else { + st_destroy_context(context->Context); + free(context); + } + return EGL_TRUE; + } + else { + _eglError(EGL_BAD_CONTEXT, "eglDestroyContext"); + return EGL_TRUE; + } +} + + +/** + * Called via eglMakeCurrent(), drv->API.MakeCurrent(). + */ +static EGLBoolean +xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, + EGLSurface r, EGLContext context) +{ + if (!_eglMakeCurrent(drv, dpy, d, r, context)) + return EGL_FALSE; + + /* XXX anything todo? */ + + return EGL_TRUE; +} + + +static enum pipe_format +choose_color_format(const __GLcontextModes *visual) +{ + if (visual->redBits == 8 && + visual->greenBits == 8 && + visual->blueBits == 8 && + visual->alphaBits == 8) { + /* XXX this really also depends on the ordering of R,G,B,A */ + return PIPE_FORMAT_A8R8G8B8_UNORM; + } + else { + assert(0); + return PIPE_FORMAT_NONE; + } +} + + +static enum pipe_format +choose_depth_format(const __GLcontextModes *visual) +{ + if (visual->depthBits > 0) + return PIPE_FORMAT_Z24S8_UNORM; + else + return PIPE_FORMAT_NONE; +} + + +static enum pipe_format +choose_stencil_format(const __GLcontextModes *visual) +{ + if (visual->stencilBits > 0) + return PIPE_FORMAT_Z24S8_UNORM; + else + return PIPE_FORMAT_NONE; +} + + +/** + * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). + */ +static EGLSurface +xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + NativeWindowType window, const EGLint *attrib_list) +{ + struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); + + struct xlib_egl_surface *surf; + __GLcontextModes visual; + uint width, height; + + surf = CALLOC_STRUCT(xlib_egl_surface); + if (!surf) + return EGL_NO_SURFACE; + + /* Let EGL lib init the common stuff */ + if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_WINDOW_BIT, + config, attrib_list)) { + free(surf); + return EGL_NO_SURFACE; + } + + /* + * Now init the Xlib and gallium stuff + */ + surf->Win = (Window) window; /* The X window ID */ + surf->Dpy = disp->Xdpy; /* The X display */ + surf->Gc = XCreateGC(surf->Dpy, surf->Win, 0, NULL); + + surf->winsys = xdrv->winsys; + + _eglConfigToContextModesRec(conf, &visual); + get_drawable_size(surf->Dpy, surf->Win, &width, &height); + + /* Create GL statetracker framebuffer */ + surf->Framebuffer = st_create_framebuffer(&visual, + choose_color_format(&visual), + choose_depth_format(&visual), + choose_stencil_format(&visual), + width, height, + (void *) surf); + return surf; +} + + +static EGLBoolean +xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) +{ + /* error checking step: */ + if (!_eglSwapBuffers(drv, dpy, draw)) + return EGL_FALSE; + + { + struct xlib_egl_surface *xsurf = lookup_surface(draw); + struct pipe_winsys *pws = xsurf->winsys; + struct pipe_surface *psurf = + st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT); + + display_surface(pws, psurf, xsurf); + } + + return EGL_TRUE; +} + + +/** + * This is the main entrypoint into the driver. + * Called by libEGL to instantiate an _EGLDriver object. + */ +_EGLDriver * +_eglMain(_EGLDisplay *dpy, const char *args) +{ + struct xlib_egl_driver *xdrv; + + _eglLog(_EGL_INFO, "Entering EGL/Xlib _eglMain(%s)", args); + + xdrv = CALLOC_STRUCT(xlib_egl_driver); + if (!xdrv) + return NULL; + + _eglInitDriverFallbacks(&xdrv->Base); + xdrv->Base.API.Initialize = xlib_eglInitialize; + xdrv->Base.API.Terminate = xlib_eglTerminate; + xdrv->Base.API.CreateContext = xlib_eglCreateContext; + xdrv->Base.API.DestroyContext = xlib_eglDestroyContext; + xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface; + xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent; + xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers; + + + xdrv->Base.ClientAPIs = "OpenGL"; /* "OpenGL_ES" */ + xdrv->Base.Name = "Xlib/softpipe"; + + /* create one winsys and use it for all contexts/surfaces */ + xdrv->winsys = create_sw_winsys(); + xdrv->winsys->flush_frontbuffer = flush_frontbuffer; + + xdrv->screen = softpipe_create_screen(xdrv->winsys); + + + return &xdrv->Base; +} + diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c new file mode 100644 index 0000000000..0e71bdee9d --- /dev/null +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -0,0 +1,244 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Totally software-based winsys layer. + * Note that the one winsys function that we can't implement here + * is flush_frontbuffer(). + * Whoever uses this code will have to provide that. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "sw_winsys.h" + + + +/** Subclass of pipe_winsys */ +struct sw_pipe_winsys +{ + struct pipe_winsys Base; + /* no extra fields for now */ +}; + + +/** subclass of pipe_buffer */ +struct sw_pipe_buffer +{ + struct pipe_buffer Base; + boolean UserBuffer; /** Is this a user-space buffer? */ + void *Data; + void *Mapped; +}; + + +/** cast wrapper */ +static INLINE struct sw_pipe_buffer * +sw_pipe_buffer(struct pipe_buffer *b) +{ + return (struct sw_pipe_buffer *) b; +} + + + +static const char * +get_name(struct pipe_winsys *pws) +{ + return "software"; +} + + +/** Create new pipe_buffer and allocate storage of given size */ +static struct pipe_buffer * +buffer_create(struct pipe_winsys *pws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer); + if (!buffer) + return NULL; + + buffer->Base.refcount = 1; + buffer->Base.alignment = alignment; + buffer->Base.usage = usage; + buffer->Base.size = size; + + /* align to 16-byte multiple for Cell */ + buffer->Data = align_malloc(size, MAX2(alignment, 16)); + + return &buffer->Base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) +{ + struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer); + if (!buffer) + return NULL; + + buffer->Base.refcount = 1; + buffer->Base.size = bytes; + buffer->UserBuffer = TRUE; + buffer->Data = ptr; + + return &buffer->Base; +} + + +static void * +buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags) +{ + struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf); + buffer->Mapped = buffer->Data; + return buffer->Mapped; +} + + +static void +buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf); + buffer->Mapped = NULL; +} + + +static void +buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf); + + if (buffer->Data && !buffer->UserBuffer) { + align_free(buffer->Data); + buffer->Data = NULL; + } + + free(buffer); +} + + +/** + * Called via winsys->surface_alloc() to create new surfaces. + */ +static struct pipe_surface * +surface_alloc(struct pipe_winsys *ws) +{ + struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); + if (!surf) + return NULL; + + surf->refcount = 1; + surf->winsys = ws; + + return surf; +} + + +static void +surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + assert(!surf->texture); + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + +static void +fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ + /* no-op */ +} + + +static int +fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + /* no-op */ + return 0; +} + + +static int +fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + /* no-op */ + return 0; +} + + +/** + * Create/return a new pipe_winsys object. + */ +struct pipe_winsys * +create_sw_winsys(void) +{ + struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys); + if (!ws) + return NULL; + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + */ + ws->Base.buffer_create = buffer_create; + ws->Base.user_buffer_create = user_buffer_create; + ws->Base.buffer_map = buffer_map; + ws->Base.buffer_unmap = buffer_unmap; + ws->Base.buffer_destroy = buffer_destroy; + + ws->Base.surface_alloc = surface_alloc; + ws->Base.surface_alloc_storage = NULL; /* unused */ + ws->Base.surface_release = surface_release; + + ws->Base.fence_reference = fence_reference; + ws->Base.fence_signalled = fence_signalled; + ws->Base.fence_finish = fence_finish; + + ws->Base.flush_frontbuffer = NULL; /* not implemented here! */ + + ws->Base.get_name = get_name; + + return &ws->Base; +} diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.h b/src/gallium/winsys/egl_xlib/sw_winsys.h new file mode 100644 index 0000000000..f96c5a14b0 --- /dev/null +++ b/src/gallium/winsys/egl_xlib/sw_winsys.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef SW_WINSYS_H +#define SW_WINSYS_H + + +struct pipe_winsys; + + +extern struct pipe_winsys * +create_sw_winsys(void); + + +#endif /* SW_WINSYS_H */ -- cgit v1.2.3 From 524408f1a5b39c8c25a277e41e4eee54fd726b84 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 30 May 2008 00:38:07 +1000 Subject: nouveau: rework buffer validation a bit --- src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 20 +++-- src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 109 ++++++++++++----------- 2 files changed, 69 insertions(+), 60 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h index a31c9a514b..5829f649cd 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -107,7 +107,7 @@ extern void nouveau_fence_flush(struct nouveau_channel *); struct nouveau_pushbuf_reloc { - uint64_t next; + struct nouveau_pushbuf_bo *pbbo; uint32_t *ptr; uint32_t flags; uint32_t data; @@ -116,13 +116,14 @@ struct nouveau_pushbuf_reloc { }; struct nouveau_pushbuf_bo { - uint64_t next; - uint64_t handle; - uint64_t flags; - uint64_t relocs; - int nr_relocs; + struct nouveau_channel *channel; + struct nouveau_bo *bo; + unsigned flags; + unsigned handled; }; +#define NOUVEAU_PUSHBUF_MAX_BUFFERS 1024 +#define NOUVEAU_PUSHBUF_MAX_RELOCS 1024 struct nouveau_pushbuf_priv { struct nouveau_pushbuf base; @@ -132,8 +133,10 @@ struct nouveau_pushbuf_priv { unsigned start; unsigned size; - uint64_t buffers; - int nr_buffers; + struct nouveau_pushbuf_bo *buffers; + unsigned nr_buffers; + struct nouveau_pushbuf_reloc *relocs; + unsigned nr_relocs; }; #define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n)) @@ -242,6 +245,7 @@ nouveau_notifier_wait_status(struct nouveau_notifier *, int id, int status, struct nouveau_bo_priv { struct nouveau_bo base; + struct nouveau_pushbuf_bo *pending; struct nouveau_fence *fence; struct nouveau_fence *wr_fence; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c index 78919bdee8..815046ba85 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -97,6 +97,10 @@ nouveau_pushbuf_init(struct nouveau_channel *chan) nouveau_pushbuf_space(chan, 0); chan->pushbuf = &nvchan->pb.base; + nvchan->pb.buffers = calloc(NOUVEAU_PUSHBUF_MAX_BUFFERS, + sizeof(struct nouveau_pushbuf_bo)); + nvchan->pb.relocs = calloc(NOUVEAU_PUSHBUF_MAX_RELOCS, + sizeof(struct nouveau_pushbuf_reloc)); return 0; } @@ -131,8 +135,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) { struct nouveau_channel_priv *nvchan = nouveau_channel(chan); struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; - struct nouveau_pushbuf_bo *pbbo; - int ret; + int ret, i; if (nvpb->base.remaining == nvpb->size) return 0; @@ -150,38 +153,47 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) /* Validate buffers + apply relocations */ nvchan->user_charge = 0; - while ((pbbo = ptr_to_pbbo(nvpb->buffers))) { - struct nouveau_pushbuf_reloc *r; - struct nouveau_bo *bo = &ptr_to_bo(pbbo->handle)->base; - - ret = nouveau_bo_validate(chan, bo, pbbo->flags); - assert (ret == 0); - - if (bo->offset == nouveau_bo(bo)->offset && - bo->flags == nouveau_bo(bo)->flags) { + for (i = 0; i < nvpb->nr_relocs; i++) { + struct nouveau_pushbuf_reloc *r = &nvpb->relocs[i]; + struct nouveau_pushbuf_bo *pbbo = r->pbbo; + struct nouveau_bo *bo = pbbo->bo; + + /* Validated, mem matches presumed, no relocation necessary */ + if (pbbo->handled & 2) { + if (!(pbbo->handled & 1)) + assert(0); + continue; + } - while ((r = ptr_to_pbrel(pbbo->relocs))) { - pbbo->relocs = r->next; - free(r); + /* Not yet validated, do it now */ + if (!(pbbo->handled & 1)) { + ret = nouveau_bo_validate(chan, bo, pbbo->flags); + if (ret) { + assert(0); + return ret; } + pbbo->handled |= 1; - nouveau_bo_del(&bo); - nvpb->buffers = pbbo->next; - free(pbbo); - continue; + if (bo->offset == nouveau_bo(bo)->offset && + bo->flags == nouveau_bo(bo)->flags) { + pbbo->handled |= 2; + continue; + } + bo->offset = nouveau_bo(bo)->offset; + bo->flags = nouveau_bo(bo)->flags; } - bo->offset = nouveau_bo(bo)->offset; - bo->flags = nouveau_bo(bo)->flags; - while ((r = ptr_to_pbrel(pbbo->relocs))) { - *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); - pbbo->relocs = r->next; - free(r); - } + /* Apply the relocation */ + *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); + } + nvpb->nr_relocs = 0; + + /* Dereference all buffers on validate list */ + for (i = 0; i < nvpb->nr_buffers; i++) { + struct nouveau_pushbuf_bo *pbbo = &nvpb->buffers[i]; - nouveau_bo_del(&bo); - nvpb->buffers = pbbo->next; - free(pbbo); + nouveau_bo(pbbo->bo)->pending = NULL; + nouveau_bo_del(&pbbo->bo); } nvpb->nr_buffers = 0; @@ -206,25 +218,21 @@ static struct nouveau_pushbuf_bo * nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) { struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); - struct nouveau_pushbuf_bo *pbbo = ptr_to_pbbo(nvpb->buffers); - struct nouveau_bo *ref = NULL; + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_pushbuf_bo *pbbo; - while (pbbo) { - if (pbbo->handle == bo->handle) - return pbbo; - pbbo = ptr_to_pbbo(pbbo->next); - } + if (nvbo->pending) + return nvbo->pending; - pbbo = malloc(sizeof(struct nouveau_pushbuf_bo)); - pbbo->next = nvpb->buffers; - nvpb->buffers = pbbo_to_ptr(pbbo); - nvpb->nr_buffers++; + if (nvpb->nr_buffers >= NOUVEAU_PUSHBUF_MAX_BUFFERS) + return NULL; + pbbo = nvpb->buffers + nvpb->nr_buffers++; + nvbo->pending = pbbo; - nouveau_bo_ref(bo->device, bo->handle, &ref); - pbbo->handle = bo_to_ptr(ref); + nouveau_bo_ref(bo->device, bo->handle, &pbbo->bo); + pbbo->channel = chan; pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; - pbbo->relocs = 0; - pbbo->nr_relocs = 0; + pbbo->handled = 0; return pbbo; } @@ -233,24 +241,21 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, struct nouveau_bo *bo, uint32_t data, uint32_t flags, uint32_t vor, uint32_t tor) { + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); struct nouveau_pushbuf_bo *pbbo; struct nouveau_pushbuf_reloc *r; - if (!chan) - return -EINVAL; + if (nvpb->nr_relocs >= NOUVEAU_PUSHBUF_MAX_RELOCS) + return -ENOMEM; pbbo = nouveau_pushbuf_emit_buffer(chan, bo); if (!pbbo) - return -EFAULT; - - r = malloc(sizeof(struct nouveau_pushbuf_reloc)); - r->next = pbbo->relocs; - pbbo->relocs = pbrel_to_ptr(r); - pbbo->nr_relocs++; - + return -ENOMEM; pbbo->flags |= (flags & NOUVEAU_BO_RDWR); pbbo->flags &= (flags | NOUVEAU_BO_RDWR); + r = nvpb->relocs + nvpb->nr_relocs++; + r->pbbo = pbbo; r->ptr = ptr; r->flags = flags; r->data = data; -- cgit v1.2.3 From 8b31d5fc8a5425b01adf80f4873cb816925ee0d1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 30 May 2008 11:00:59 +1000 Subject: nouveau: flush pending pushbuf if buffer on validate list at map/del --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index aca16a8b12..57f5b7d1ae 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -256,6 +256,9 @@ nouveau_bo_del(struct nouveau_bo **bo) if (--nvbo->refcount) return; + if (nvbo->pending) + nouveau_pushbuf_flush(nvbo->pending->channel, 0); + if (nvbo->fence) nouveau_fence_signal_cb(nvbo->fence, nouveau_bo_del_cb, nvbo); else @@ -270,6 +273,11 @@ nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags) if (!nvbo) return -EINVAL; + if (nvbo->pending && + (nvbo->pending->flags & NOUVEAU_BO_WR || flags & NOUVEAU_BO_WR)) { + nouveau_pushbuf_flush(nvbo->pending->channel, 0); + } + if (flags & NOUVEAU_BO_WR) nouveau_fence_wait(&nvbo->fence); else -- cgit v1.2.3 From cf13cf245e91669eb916a6d51676b0d66ff62ead Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 30 May 2008 14:32:59 +1000 Subject: nouveau: fix warning --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index d9fc3f6ce1..ef5fb7ec0d 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -99,7 +99,7 @@ nouveau_context_create(const __GLcontextModes *glVis, struct st_context *st_share = NULL; struct nouveau_channel_context *nvc = NULL; struct nouveau_device *dev = nv_screen->device; - int i, ret; + int i; if (sharedContextPrivate) { st_share = ((struct nouveau_context *)sharedContextPrivate)->st; -- cgit v1.2.3 From 9760ab234951d18c9606e962c6e3ac1f56fc6385 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 30 May 2008 13:30:51 +0200 Subject: i915: Fix extentions not being set --- src/gallium/winsys/dri/intel/intel_context.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index cc2fc11c5e..6a0c381849 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -35,6 +35,7 @@ #include "intel_batchbuffer.h" #include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" #include "pipe/p_defines.h" #include "pipe/p_context.h" @@ -218,6 +219,8 @@ intelCreateContext(const __GLcontextModes * visual, intel->st = st_create_context(pipe, visual, st_share); + driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE ); + return GL_TRUE; } -- cgit v1.2.3 From 7b0a551c4cebc44cc06face712eb9659ccdebcc9 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 16:56:42 +0200 Subject: i915: Made batch buffer size much larger --- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 2 +- src/gallium/winsys/dri/intel/intel_screen.c | 6 +++--- src/gallium/winsys/dri/intel/intel_screen.h | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index aa2eed53b8..09d4eef484 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -65,7 +65,7 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch) driBOUnrefUserList(batch->list); driBOResetList(batch->list); - batch->size = 4 * 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize; + batch->size = batch->intel->intelScreen->max_batch_size; driBOData(batch->buffer, batch->size, NULL, NULL, 0); /* diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 429a2cf8f8..0be88974f4 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -200,8 +200,8 @@ intelCreatePools(__DRIscreenPrivate * sPriv) DRM_BO_FLAG_MEM_TT, DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, - 4 * 4096, //intelScreen->maxBatchSize, - 1, 40, 16*16384, 0, + intelScreen->max_batch_size, + 1, 40, intelScreen->max_batch_size * 16, 0, intelScreen->fMan); #endif intelScreen->havePools = GL_TRUE; @@ -262,7 +262,7 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - + intelScreen->max_batch_size = 16 * 4096; #if 1 // ZZZ JB intelScreen->mgr = driFenceMgrTTMInit(sPriv->fd); diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index c17f0202e4..1db0502b13 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -80,6 +80,7 @@ struct intel_screen struct _DriFenceMgr *mgr; struct _DriFreeSlabManager *fMan; unsigned batch_id; + unsigned max_batch_size; struct pipe_winsys *winsys; }; -- cgit v1.2.3 From 057ee55720faee0e1269937d70bbafe6df5c57e6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 11:41:18 -0600 Subject: egl: added surface_alloc_storage() --- src/gallium/winsys/egl_xlib/sw_winsys.c | 39 ++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index 0e71bdee9d..fd0cb9fb12 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -70,6 +70,15 @@ sw_pipe_buffer(struct pipe_buffer *b) } +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + static const char * get_name(struct pipe_winsys *pws) @@ -168,6 +177,34 @@ surface_alloc(struct pipe_winsys *ws) } +static int +surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if(!surf->buffer) + return -1; + + return 0; +} + + static void surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) { @@ -229,7 +266,7 @@ create_sw_winsys(void) ws->Base.buffer_destroy = buffer_destroy; ws->Base.surface_alloc = surface_alloc; - ws->Base.surface_alloc_storage = NULL; /* unused */ + ws->Base.surface_alloc_storage = surface_alloc_storage; ws->Base.surface_release = surface_release; ws->Base.fence_reference = fence_reference; -- cgit v1.2.3 From 750782a327a1d295f4ed00a590c362f32912d597 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 11:42:08 -0600 Subject: egl: assorted fixes. The code works now. --- src/gallium/winsys/egl_xlib/egl_xlib.c | 67 ++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 7 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 4741da87cd..555bb8b7b4 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -176,6 +176,28 @@ xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) } +static void +get_drawable_visual_info(Display *dpy, Drawable d, XVisualInfo *visInfo) +{ + XWindowAttributes attr; + XVisualInfo visTemp, *vis; + int num_visuals; + + XGetWindowAttributes(dpy, d, &attr); + + visTemp.screen = DefaultScreen(dpy); + visTemp.visualid = attr.visual->visualid; + vis = XGetVisualInfo(dpy, + (VisualScreenMask | VisualIDMask), + &visTemp, &num_visuals); + if (vis) + *visInfo = *vis; + + XFree(vis); +} + + + /** Get size of given window */ static Status get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) @@ -191,6 +213,16 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) } +static void +check_and_update_buffer_size(struct xlib_egl_surface *surface) +{ + uint width, height; + get_drawable_size(surface->Dpy, surface->Win, &width, &height); + st_resize_framebuffer(surface->Framebuffer, width, height); +} + + + static void display_surface(struct pipe_winsys *pws, struct pipe_surface *psurf, @@ -223,6 +255,8 @@ display_surface(struct pipe_winsys *pws, XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc, ximage, 0, 0, 0, 0, psurf->width, psurf->height); + XSync(xsurf->Dpy, 0); + ximage->data = NULL; XDestroyImage(ximage); @@ -303,13 +337,21 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx) * Called via eglMakeCurrent(), drv->API.MakeCurrent(). */ static EGLBoolean -xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, - EGLSurface r, EGLContext context) +xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, + EGLSurface draw, EGLSurface read, EGLContext ctx) { - if (!_eglMakeCurrent(drv, dpy, d, r, context)) + struct xlib_egl_context *context = lookup_context(ctx); + struct xlib_egl_surface *draw_surf = lookup_surface(draw); + struct xlib_egl_surface *read_surf = lookup_surface(read); + + if (!_eglMakeCurrent(drv, dpy, draw, read, context)) return EGL_FALSE; - /* XXX anything todo? */ + st_make_current((context ? context->Context : NULL), + (draw_surf ? draw_surf->Framebuffer : NULL), + (read_surf ? read_surf->Framebuffer : NULL)); + + check_and_update_buffer_size(draw_surf); return EGL_TRUE; } @@ -336,7 +378,7 @@ static enum pipe_format choose_depth_format(const __GLcontextModes *visual) { if (visual->depthBits > 0) - return PIPE_FORMAT_Z24S8_UNORM; + return PIPE_FORMAT_S8Z24_UNORM; else return PIPE_FORMAT_NONE; } @@ -346,7 +388,7 @@ static enum pipe_format choose_stencil_format(const __GLcontextModes *visual) { if (visual->stencilBits > 0) - return PIPE_FORMAT_Z24S8_UNORM; + return PIPE_FORMAT_S8Z24_UNORM; else return PIPE_FORMAT_NONE; } @@ -378,6 +420,8 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, return EGL_NO_SURFACE; } + _eglSaveSurface(&surf->Base); + /* * Now init the Xlib and gallium stuff */ @@ -389,6 +433,10 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, _eglConfigToContextModesRec(conf, &visual); get_drawable_size(surf->Dpy, surf->Win, &width, &height); + get_drawable_visual_info(surf->Dpy, surf->Win, &surf->VisInfo); + + surf->Base.Width = width; + surf->Base.Height = height; /* Create GL statetracker framebuffer */ surf->Framebuffer = st_create_framebuffer(&visual, @@ -397,7 +445,10 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, choose_stencil_format(&visual), width, height, (void *) surf); - return surf; + + st_resize_framebuffer(surf->Framebuffer, width, height); + + return _eglGetSurfaceHandle(&surf->Base); } @@ -414,6 +465,8 @@ xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) struct pipe_surface *psurf = st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT); + st_notify_swapbuffers(xsurf->Framebuffer); + display_surface(pws, psurf, xsurf); } -- cgit v1.2.3 From 64d0eb111d5a19bc251dfc59884c945cf93c6bb0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 11:51:50 -0600 Subject: egl: fix-up window resizes --- src/gallium/winsys/egl_xlib/egl_xlib.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 555bb8b7b4..b683898dcb 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -219,6 +219,8 @@ check_and_update_buffer_size(struct xlib_egl_surface *surface) uint width, height; get_drawable_size(surface->Dpy, surface->Win, &width, &height); st_resize_framebuffer(surface->Framebuffer, width, height); + surface->Base.Width = width; + surface->Base.Height = height; } @@ -468,6 +470,8 @@ xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) st_notify_swapbuffers(xsurf->Framebuffer); display_surface(pws, psurf, xsurf); + + check_and_update_buffer_size(xsurf); } return EGL_TRUE; -- cgit v1.2.3 From 52676207e338b4c2b4953747521921ab79d70f06 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 12:06:06 -0600 Subject: egl: added eglDestroySurface function --- src/gallium/winsys/egl_xlib/egl_xlib.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index b683898dcb..bd2acd0411 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -454,6 +454,28 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, } +static EGLBoolean +xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +{ + struct xlib_egl_surface *surf = lookup_surface(surface); + if (surf) { + _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface); + if (surf->Base.IsBound) { + surf->Base.DeletePending = EGL_TRUE; + } + else { + st_unreference_framebuffer(&surf->Framebuffer); + free(surf); + } + return EGL_TRUE; + } + else { + _eglError(EGL_BAD_SURFACE, "eglDestroySurface"); + return EGL_FALSE; + } +} + + static EGLBoolean xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) { @@ -499,6 +521,7 @@ _eglMain(_EGLDisplay *dpy, const char *args) xdrv->Base.API.CreateContext = xlib_eglCreateContext; xdrv->Base.API.DestroyContext = xlib_eglDestroyContext; xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface; + xdrv->Base.API.DestroySurface = xlib_eglDestroySurface; xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent; xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers; -- cgit v1.2.3 From ba7aeb8b34c2e310b6ba0d3dbfdc68b0d6ab82c8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 13:46:31 -0600 Subject: egl: specify client API by bit flag, not string --- src/gallium/winsys/egl_xlib/egl_xlib.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index bd2acd0411..1458f83c02 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -302,6 +302,12 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, return EGL_NO_CONTEXT; } + if (ctx->Base.ClientAPI != EGL_OPENGL_API) { + _eglError(EGL_BAD_MATCH, "eglCreateContext(only OpenGL API supported)"); + free(ctx); + return EGL_NO_CONTEXT; + } + /* create a softpipe context */ ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL); @@ -309,6 +315,7 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, _eglConfigToContextModesRec(conf, &visual); ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx); + _eglSaveContext(&ctx->Base); return _eglGetContextHandle(&ctx->Base); } @@ -525,8 +532,8 @@ _eglMain(_EGLDisplay *dpy, const char *args) xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent; xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers; + xdrv->Base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; - xdrv->Base.ClientAPIs = "OpenGL"; /* "OpenGL_ES" */ xdrv->Base.Name = "Xlib/softpipe"; /* create one winsys and use it for all contexts/surfaces */ @@ -535,7 +542,6 @@ _eglMain(_EGLDisplay *dpy, const char *args) xdrv->screen = softpipe_create_screen(xdrv->winsys); - return &xdrv->Base; } -- cgit v1.2.3 From 3c4162ed2afe4da252d2a32c14e486515935ba39 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 14:51:40 -0600 Subject: egl: eglGetProcAddress() stub --- src/gallium/winsys/egl_xlib/egl_xlib.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 1458f83c02..99389970f5 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -176,6 +176,17 @@ xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) } +static _EGLProc +xlib_eglGetProcAddress(const char *procname) +{ + /* XXX for each supported API, evaluate GetProcAddress(name) */ + /* + return _glapi_get_proc_address(procname); + */ + return NULL; +} + + static void get_drawable_visual_info(Display *dpy, Drawable d, XVisualInfo *visInfo) { @@ -525,6 +536,7 @@ _eglMain(_EGLDisplay *dpy, const char *args) _eglInitDriverFallbacks(&xdrv->Base); xdrv->Base.API.Initialize = xlib_eglInitialize; xdrv->Base.API.Terminate = xlib_eglTerminate; + xdrv->Base.API.GetProcAddress = xlib_eglGetProcAddress; xdrv->Base.API.CreateContext = xlib_eglCreateContext; xdrv->Base.API.DestroyContext = xlib_eglDestroyContext; xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface; -- cgit v1.2.3 From 7c22bb383a8fcccf71d7916ce91ae6cb17ac1e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 3 Jun 2008 00:03:17 +0900 Subject: gdi: Port of the gdi mesa driver to gallium (Alan Hourihane). --- src/gallium/winsys/gdi/SConscript | 33 ++ src/gallium/winsys/gdi/colors.h | 29 ++ src/gallium/winsys/gdi/opengl32.def | 859 ++++++++++++++++++++++++++++++++++ src/gallium/winsys/gdi/wgl.c | 703 ++++++++++++++++++++++++++++ src/gallium/winsys/gdi/wmesa.c | 890 ++++++++++++++++++++++++++++++++++++ src/gallium/winsys/gdi/wmesadef.h | 40 ++ 6 files changed, 2554 insertions(+) create mode 100644 src/gallium/winsys/gdi/SConscript create mode 100644 src/gallium/winsys/gdi/colors.h create mode 100644 src/gallium/winsys/gdi/opengl32.def create mode 100644 src/gallium/winsys/gdi/wgl.c create mode 100644 src/gallium/winsys/gdi/wmesa.c create mode 100644 src/gallium/winsys/gdi/wmesadef.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript new file mode 100644 index 0000000000..170fdf5127 --- /dev/null +++ b/src/gallium/winsys/gdi/SConscript @@ -0,0 +1,33 @@ +####################################################################### +# SConscript for gdi winsys + +Import('*') + +if env['platform'] == 'windows': + + env = env.Clone() + + env.Append(CPPPATH = [ + '#src/mesa/glapi', + '#src/mesa', + '#src/mesa/main', + ]) + + sources = [ + 'opengl32.def', + 'wgl.c', + 'wmesa.c', + ] + + drivers = [ + softpipe, + ] + + env.Append(LIBS = ['gdi32', 'user32']) + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='opengl32', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/winsys/gdi/colors.h b/src/gallium/winsys/gdi/colors.h new file mode 100644 index 0000000000..03e512c1fa --- /dev/null +++ b/src/gallium/winsys/gdi/colors.h @@ -0,0 +1,29 @@ +/* Values for wmesa->pixelformat: */ + +#define PF_8A8B8G8R 3 /* 32-bit TrueColor: 8-A, 8-B, 8-G, 8-R */ +#define PF_8R8G8B 4 /* 32-bit TrueColor: 8-R, 8-G, 8-B */ +#define PF_5R6G5B 5 /* 16-bit TrueColor: 5-R, 6-G, 5-B bits */ +#define PF_DITHER8 6 /* Dithered RGB using a lookup table */ +#define PF_LOOKUP 7 /* Undithered RGB using a lookup table */ +#define PF_GRAYSCALE 10 /* Grayscale or StaticGray */ +#define PF_BADFORMAT 11 +#define PF_INDEX8 12 + + +#define BGR8(r,g,b) (unsigned)(((BYTE)((b & 0xc0) | ((g & 0xe0)>>2) | \ + ((r & 0xe0)>>5)))) + +/* Windows uses 5,5,5 for 16-bit */ +#define BGR16(r,g,b) ( (((unsigned short)b ) >> 3) | \ + (((unsigned short)g & 0xf8) << 2) | \ + (((unsigned short)r & 0xf8) << 7) ) + +#define BGR24(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)| \ + ((WORD)((BYTE)(g))<<8))| \ + (((DWORD)(BYTE)(r))<<16))) + +#define BGR32(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)| \ + ((WORD)((BYTE)(g))<<8))| \ + (((DWORD)(BYTE)(r))<<16))) + + diff --git a/src/gallium/winsys/gdi/opengl32.def b/src/gallium/winsys/gdi/opengl32.def new file mode 100644 index 0000000000..54e72f57b1 --- /dev/null +++ b/src/gallium/winsys/gdi/opengl32.def @@ -0,0 +1,859 @@ +; DO NOT EDIT - This file generated automatically by mesadef.py script +;DESCRIPTION 'Mesa (OpenGL work-alike) for Win32' +VERSION 6.5 +; +; Module definition file for Mesa (OPENGL32.DLL) +; +; Note: The OpenGL functions use the STDCALL +; function calling convention. Microsoft's +; OPENGL32 uses this convention and so must the +; Mesa OPENGL32 so that the Mesa DLL can be used +; as a drop-in replacement. +; +; The linker exports STDCALL entry points with +; 'decorated' names; e.g., _glBegin@0, where the +; trailing number is the number of bytes of +; parameter data pushed onto the stack. The +; callee is responsible for popping this data +; off the stack, usually via a RETF n instruction. +; +; However, the Microsoft OPENGL32.DLL does not export +; the decorated names, even though the calling convention +; is STDCALL. So, this module definition file is +; needed to force the Mesa OPENGL32.DLL to export the +; symbols in the same manner as the Microsoft DLL. +; Were it not for this problem, this file would not +; be needed (for the gl* functions) since the entry +; points are compiled with dllexport declspec. +; +; However, this file is still needed to export "internal" +; Mesa symbols for the benefit of the OSMESA32.DLL. +; +EXPORTS + glNewList + glEndList + glCallList + glCallLists + glDeleteLists + glGenLists + glListBase + glBegin + glBitmap + glColor3b + glColor3bv + glColor3d + glColor3dv + glColor3f + glColor3fv + glColor3i + glColor3iv + glColor3s + glColor3sv + glColor3ub + glColor3ubv + glColor3ui + glColor3uiv + glColor3us + glColor3usv + glColor4b + glColor4bv + glColor4d + glColor4dv + glColor4f + glColor4fv + glColor4i + glColor4iv + glColor4s + glColor4sv + glColor4ub + glColor4ubv + glColor4ui + glColor4uiv + glColor4us + glColor4usv + glEdgeFlag + glEdgeFlagv + glEnd + glIndexd + glIndexdv + glIndexf + glIndexfv + glIndexi + glIndexiv + glIndexs + glIndexsv + glNormal3b + glNormal3bv + glNormal3d + glNormal3dv + glNormal3f + glNormal3fv + glNormal3i + glNormal3iv + glNormal3s + glNormal3sv + glRasterPos2d + glRasterPos2dv + glRasterPos2f + glRasterPos2fv + glRasterPos2i + glRasterPos2iv + glRasterPos2s + glRasterPos2sv + glRasterPos3d + glRasterPos3dv + glRasterPos3f + glRasterPos3fv + glRasterPos3i + glRasterPos3iv + glRasterPos3s + glRasterPos3sv + glRasterPos4d + glRasterPos4dv + glRasterPos4f + glRasterPos4fv + glRasterPos4i + glRasterPos4iv + glRasterPos4s + glRasterPos4sv + glRectd + glRectdv + glRectf + glRectfv + glRecti + glRectiv + glRects + glRectsv + glTexCoord1d + glTexCoord1dv + glTexCoord1f + glTexCoord1fv + glTexCoord1i + glTexCoord1iv + glTexCoord1s + glTexCoord1sv + glTexCoord2d + glTexCoord2dv + glTexCoord2f + glTexCoord2fv + glTexCoord2i + glTexCoord2iv + glTexCoord2s + glTexCoord2sv + glTexCoord3d + glTexCoord3dv + glTexCoord3f + glTexCoord3fv + glTexCoord3i + glTexCoord3iv + glTexCoord3s + glTexCoord3sv + glTexCoord4d + glTexCoord4dv + glTexCoord4f + glTexCoord4fv + glTexCoord4i + glTexCoord4iv + glTexCoord4s + glTexCoord4sv + glVertex2d + glVertex2dv + glVertex2f + glVertex2fv + glVertex2i + glVertex2iv + glVertex2s + glVertex2sv + glVertex3d + glVertex3dv + glVertex3f + glVertex3fv + glVertex3i + glVertex3iv + glVertex3s + glVertex3sv + glVertex4d + glVertex4dv + glVertex4f + glVertex4fv + glVertex4i + glVertex4iv + glVertex4s + glVertex4sv + glClipPlane + glColorMaterial + glCullFace + glFogf + glFogfv + glFogi + glFogiv + glFrontFace + glHint + glLightf + glLightfv + glLighti + glLightiv + glLightModelf + glLightModelfv + glLightModeli + glLightModeliv + glLineStipple + glLineWidth + glMaterialf + glMaterialfv + glMateriali + glMaterialiv + glPointSize + glPolygonMode + glPolygonStipple + glScissor + glShadeModel + glTexParameterf + glTexParameterfv + glTexParameteri + glTexParameteriv + glTexImage1D + glTexImage2D + glTexEnvf + glTexEnvfv + glTexEnvi + glTexEnviv + glTexGend + glTexGendv + glTexGenf + glTexGenfv + glTexGeni + glTexGeniv + glFeedbackBuffer + glSelectBuffer + glRenderMode + glInitNames + glLoadName + glPassThrough + glPopName + glPushName + glDrawBuffer + glClear + glClearAccum + glClearIndex + glClearColor + glClearStencil + glClearDepth + glStencilMask + glColorMask + glDepthMask + glIndexMask + glAccum + glDisable + glEnable + glFinish + glFlush + glPopAttrib + glPushAttrib + glMap1d + glMap1f + glMap2d + glMap2f + glMapGrid1d + glMapGrid1f + glMapGrid2d + glMapGrid2f + glEvalCoord1d + glEvalCoord1dv + glEvalCoord1f + glEvalCoord1fv + glEvalCoord2d + glEvalCoord2dv + glEvalCoord2f + glEvalCoord2fv + glEvalMesh1 + glEvalPoint1 + glEvalMesh2 + glEvalPoint2 + glAlphaFunc + glBlendFunc + glLogicOp + glStencilFunc + glStencilOp + glDepthFunc + glPixelZoom + glPixelTransferf + glPixelTransferi + glPixelStoref + glPixelStorei + glPixelMapfv + glPixelMapuiv + glPixelMapusv + glReadBuffer + glCopyPixels + glReadPixels + glDrawPixels + glGetBooleanv + glGetClipPlane + glGetDoublev + glGetError + glGetFloatv + glGetIntegerv + glGetLightfv + glGetLightiv + glGetMapdv + glGetMapfv + glGetMapiv + glGetMaterialfv + glGetMaterialiv + glGetPixelMapfv + glGetPixelMapuiv + glGetPixelMapusv + glGetPolygonStipple + glGetString + glGetTexEnvfv + glGetTexEnviv + glGetTexGendv + glGetTexGenfv + glGetTexGeniv + glGetTexImage + glGetTexParameterfv + glGetTexParameteriv + glGetTexLevelParameterfv + glGetTexLevelParameteriv + glIsEnabled + glIsList + glDepthRange + glFrustum + glLoadIdentity + glLoadMatrixf + glLoadMatrixd + glMatrixMode + glMultMatrixf + glMultMatrixd + glOrtho + glPopMatrix + glPushMatrix + glRotated + glRotatef + glScaled + glScalef + glTranslated + glTranslatef + glViewport + glArrayElement + glColorPointer + glDisableClientState + glDrawArrays + glDrawElements + glEdgeFlagPointer + glEnableClientState + glGetPointerv + glIndexPointer + glInterleavedArrays + glNormalPointer + glTexCoordPointer + glVertexPointer + glPolygonOffset + glCopyTexImage1D + glCopyTexImage2D + glCopyTexSubImage1D + glCopyTexSubImage2D + glTexSubImage1D + glTexSubImage2D + glAreTexturesResident + glBindTexture + glDeleteTextures + glGenTextures + glIsTexture + glPrioritizeTextures + glIndexub + glIndexubv + glPopClientAttrib + glPushClientAttrib + glBlendColor + glBlendEquation + glDrawRangeElements + glColorTable + glColorTableParameterfv + glColorTableParameteriv + glCopyColorTable + glGetColorTable + glGetColorTableParameterfv + glGetColorTableParameteriv + glColorSubTable + glCopyColorSubTable + glConvolutionFilter1D + glConvolutionFilter2D + glConvolutionParameterf + glConvolutionParameterfv + glConvolutionParameteri + glConvolutionParameteriv + glCopyConvolutionFilter1D + glCopyConvolutionFilter2D + glGetConvolutionFilter + glGetConvolutionParameterfv + glGetConvolutionParameteriv + glGetSeparableFilter + glSeparableFilter2D + glGetHistogram + glGetHistogramParameterfv + glGetHistogramParameteriv + glGetMinmax + glGetMinmaxParameterfv + glGetMinmaxParameteriv + glHistogram + glMinmax + glResetHistogram + glResetMinmax + glTexImage3D + glTexSubImage3D + glCopyTexSubImage3D + glActiveTextureARB + glClientActiveTextureARB + glMultiTexCoord1dARB + glMultiTexCoord1dvARB + glMultiTexCoord1fARB + glMultiTexCoord1fvARB + glMultiTexCoord1iARB + glMultiTexCoord1ivARB + glMultiTexCoord1sARB + glMultiTexCoord1svARB + glMultiTexCoord2dARB + glMultiTexCoord2dvARB + glMultiTexCoord2fARB + glMultiTexCoord2fvARB + glMultiTexCoord2iARB + glMultiTexCoord2ivARB + glMultiTexCoord2sARB + glMultiTexCoord2svARB + glMultiTexCoord3dARB + glMultiTexCoord3dvARB + glMultiTexCoord3fARB + glMultiTexCoord3fvARB + glMultiTexCoord3iARB + glMultiTexCoord3ivARB + glMultiTexCoord3sARB + glMultiTexCoord3svARB + glMultiTexCoord4dARB + glMultiTexCoord4dvARB + glMultiTexCoord4fARB + glMultiTexCoord4fvARB + glMultiTexCoord4iARB + glMultiTexCoord4ivARB + glMultiTexCoord4sARB + glMultiTexCoord4svARB + glLoadTransposeMatrixfARB + glLoadTransposeMatrixdARB + glMultTransposeMatrixfARB + glMultTransposeMatrixdARB + glSampleCoverageARB + glCompressedTexImage3DARB + glCompressedTexImage2DARB + glCompressedTexImage1DARB + glCompressedTexSubImage3DARB + glCompressedTexSubImage2DARB + glCompressedTexSubImage1DARB + glGetCompressedTexImageARB + glActiveTexture + glClientActiveTexture + glMultiTexCoord1d + glMultiTexCoord1dv + glMultiTexCoord1f + glMultiTexCoord1fv + glMultiTexCoord1i + glMultiTexCoord1iv + glMultiTexCoord1s + glMultiTexCoord1sv + glMultiTexCoord2d + glMultiTexCoord2dv + glMultiTexCoord2f + glMultiTexCoord2fv + glMultiTexCoord2i + glMultiTexCoord2iv + glMultiTexCoord2s + glMultiTexCoord2sv + glMultiTexCoord3d + glMultiTexCoord3dv + glMultiTexCoord3f + glMultiTexCoord3fv + glMultiTexCoord3i + glMultiTexCoord3iv + glMultiTexCoord3s + glMultiTexCoord3sv + glMultiTexCoord4d + glMultiTexCoord4dv + glMultiTexCoord4f + glMultiTexCoord4fv + glMultiTexCoord4i + glMultiTexCoord4iv + glMultiTexCoord4s + glMultiTexCoord4sv + glLoadTransposeMatrixf + glLoadTransposeMatrixd + glMultTransposeMatrixf + glMultTransposeMatrixd + glSampleCoverage + glCompressedTexImage3D + glCompressedTexImage2D + glCompressedTexImage1D + glCompressedTexSubImage3D + glCompressedTexSubImage2D + glCompressedTexSubImage1D + glGetCompressedTexImage + glBlendColorEXT + glPolygonOffsetEXT + glTexImage3DEXT + glTexSubImage3DEXT + glTexSubImage1DEXT + glTexSubImage2DEXT + glCopyTexImage1DEXT + glCopyTexImage2DEXT + glCopyTexSubImage1DEXT + glCopyTexSubImage2DEXT + glCopyTexSubImage3DEXT + glAreTexturesResidentEXT + glBindTextureEXT + glDeleteTexturesEXT + glGenTexturesEXT + glIsTextureEXT + glPrioritizeTexturesEXT + glArrayElementEXT + glColorPointerEXT + glDrawArraysEXT + glEdgeFlagPointerEXT + glGetPointervEXT + glIndexPointerEXT + glNormalPointerEXT + glTexCoordPointerEXT + glVertexPointerEXT + glBlendEquationEXT + glPointParameterfEXT + glPointParameterfvEXT + glPointParameterfARB + glPointParameterfvARB + glColorTableEXT + glGetColorTableEXT + glGetColorTableParameterivEXT + glGetColorTableParameterfvEXT + glLockArraysEXT + glUnlockArraysEXT + glDrawRangeElementsEXT + glSecondaryColor3bEXT + glSecondaryColor3bvEXT + glSecondaryColor3dEXT + glSecondaryColor3dvEXT + glSecondaryColor3fEXT + glSecondaryColor3fvEXT + glSecondaryColor3iEXT + glSecondaryColor3ivEXT + glSecondaryColor3sEXT + glSecondaryColor3svEXT + glSecondaryColor3ubEXT + glSecondaryColor3ubvEXT + glSecondaryColor3uiEXT + glSecondaryColor3uivEXT + glSecondaryColor3usEXT + glSecondaryColor3usvEXT + glSecondaryColorPointerEXT + glMultiDrawArraysEXT + glMultiDrawElementsEXT + glFogCoordfEXT + glFogCoordfvEXT + glFogCoorddEXT + glFogCoorddvEXT + glFogCoordPointerEXT + glBlendFuncSeparateEXT + glFlushVertexArrayRangeNV + glVertexArrayRangeNV + glCombinerParameterfvNV + glCombinerParameterfNV + glCombinerParameterivNV + glCombinerParameteriNV + glCombinerInputNV + glCombinerOutputNV + glFinalCombinerInputNV + glGetCombinerInputParameterfvNV + glGetCombinerInputParameterivNV + glGetCombinerOutputParameterfvNV + glGetCombinerOutputParameterivNV + glGetFinalCombinerInputParameterfvNV + glGetFinalCombinerInputParameterivNV + glResizeBuffersMESA + glWindowPos2dMESA + glWindowPos2dvMESA + glWindowPos2fMESA + glWindowPos2fvMESA + glWindowPos2iMESA + glWindowPos2ivMESA + glWindowPos2sMESA + glWindowPos2svMESA + glWindowPos3dMESA + glWindowPos3dvMESA + glWindowPos3fMESA + glWindowPos3fvMESA + glWindowPos3iMESA + glWindowPos3ivMESA + glWindowPos3sMESA + glWindowPos3svMESA + glWindowPos4dMESA + glWindowPos4dvMESA + glWindowPos4fMESA + glWindowPos4fvMESA + glWindowPos4iMESA + glWindowPos4ivMESA + glWindowPos4sMESA + glWindowPos4svMESA + glWindowPos2dARB + glWindowPos2fARB + glWindowPos2iARB + glWindowPos2sARB + glWindowPos2dvARB + glWindowPos2fvARB + glWindowPos2ivARB + glWindowPos2svARB + glWindowPos3dARB + glWindowPos3fARB + glWindowPos3iARB + glWindowPos3sARB + glWindowPos3dvARB + glWindowPos3fvARB + glWindowPos3ivARB + glWindowPos3svARB + glAreProgramsResidentNV + glBindProgramNV + glDeleteProgramsNV + glExecuteProgramNV + glGenProgramsNV + glGetProgramParameterdvNV + glGetProgramParameterfvNV + glGetProgramivNV + glGetProgramStringNV + glGetTrackMatrixivNV + glGetVertexAttribdvNV + glGetVertexAttribfvNV + glGetVertexAttribivNV + glGetVertexAttribPointervNV + glIsProgramNV + glLoadProgramNV + glProgramParameter4dNV + glProgramParameter4dvNV + glProgramParameter4fNV + glProgramParameter4fvNV + glProgramParameters4dvNV + glProgramParameters4fvNV + glRequestResidentProgramsNV + glTrackMatrixNV + glVertexAttribPointerNV + glVertexAttrib1dNV + glVertexAttrib1dvNV + glVertexAttrib1fNV + glVertexAttrib1fvNV + glVertexAttrib1sNV + glVertexAttrib1svNV + glVertexAttrib2dNV + glVertexAttrib2dvNV + glVertexAttrib2fNV + glVertexAttrib2fvNV + glVertexAttrib2sNV + glVertexAttrib2svNV + glVertexAttrib3dNV + glVertexAttrib3dvNV + glVertexAttrib3fNV + glVertexAttrib3fvNV + glVertexAttrib3sNV + glVertexAttrib3svNV + glVertexAttrib4dNV + glVertexAttrib4dvNV + glVertexAttrib4fNV + glVertexAttrib4fvNV + glVertexAttrib4sNV + glVertexAttrib4svNV + glVertexAttrib4ubNV + glVertexAttrib4ubvNV + glVertexAttribs1dvNV + glVertexAttribs1fvNV + glVertexAttribs1svNV + glVertexAttribs2dvNV + glVertexAttribs2fvNV + glVertexAttribs2svNV + glVertexAttribs3dvNV + glVertexAttribs3fvNV + glVertexAttribs3svNV + glVertexAttribs4dvNV + glVertexAttribs4fvNV + glVertexAttribs4svNV + glVertexAttribs4ubvNV + glPointParameteriNV + glPointParameterivNV + glFogCoordf + glFogCoordfv + glFogCoordd + glFogCoorddv + glFogCoordPointer + glMultiDrawArrays + glMultiDrawElements + glPointParameterf + glPointParameterfv + glPointParameteri + glPointParameteriv + glSecondaryColor3b + glSecondaryColor3bv + glSecondaryColor3d + glSecondaryColor3dv + glSecondaryColor3f + glSecondaryColor3fv + glSecondaryColor3i + glSecondaryColor3iv + glSecondaryColor3s + glSecondaryColor3sv + glSecondaryColor3ub + glSecondaryColor3ubv + glSecondaryColor3ui + glSecondaryColor3uiv + glSecondaryColor3us + glSecondaryColor3usv + glSecondaryColorPointer + glWindowPos2d + glWindowPos2dv + glWindowPos2f + glWindowPos2fv + glWindowPos2i + glWindowPos2iv + glWindowPos2s + glWindowPos2sv + glWindowPos3d + glWindowPos3dv + glWindowPos3f + glWindowPos3fv + glWindowPos3i + glWindowPos3iv + glWindowPos3s + glWindowPos3sv + glVertexAttrib1sARB + glVertexAttrib1fARB + glVertexAttrib1dARB + glVertexAttrib2sARB + glVertexAttrib2fARB + glVertexAttrib2dARB + glVertexAttrib3sARB + glVertexAttrib3fARB + glVertexAttrib3dARB + glVertexAttrib4sARB + glVertexAttrib4fARB + glVertexAttrib4dARB + glVertexAttrib4NubARB + glVertexAttrib1svARB + glVertexAttrib1fvARB + glVertexAttrib1dvARB + glVertexAttrib2svARB + glVertexAttrib2fvARB + glVertexAttrib2dvARB + glVertexAttrib3svARB + glVertexAttrib3fvARB + glVertexAttrib3dvARB + glVertexAttrib4bvARB + glVertexAttrib4svARB + glVertexAttrib4ivARB + glVertexAttrib4ubvARB + glVertexAttrib4usvARB + glVertexAttrib4uivARB + glVertexAttrib4fvARB + glVertexAttrib4dvARB + glVertexAttrib4NbvARB + glVertexAttrib4NsvARB + glVertexAttrib4NivARB + glVertexAttrib4NubvARB + glVertexAttrib4NusvARB + glVertexAttrib4NuivARB + glVertexAttribPointerARB + glEnableVertexAttribArrayARB + glDisableVertexAttribArrayARB + glProgramStringARB + glBindProgramARB + glDeleteProgramsARB + glGenProgramsARB + glIsProgramARB + glProgramEnvParameter4dARB + glProgramEnvParameter4dvARB + glProgramEnvParameter4fARB + glProgramEnvParameter4fvARB + glProgramLocalParameter4dARB + glProgramLocalParameter4dvARB + glProgramLocalParameter4fARB + glProgramLocalParameter4fvARB + glGetProgramEnvParameterdvARB + glGetProgramEnvParameterfvARB + glGetProgramLocalParameterdvARB + glGetProgramLocalParameterfvARB + glGetProgramivARB + glGetProgramStringARB + glGetVertexAttribdvARB + glGetVertexAttribfvARB + glGetVertexAttribivARB + glGetVertexAttribPointervARB + glProgramNamedParameter4fNV + glProgramNamedParameter4dNV + glProgramNamedParameter4fvNV + glProgramNamedParameter4dvNV + glGetProgramNamedParameterfvNV + glGetProgramNamedParameterdvNV + glBindBufferARB + glBufferDataARB + glBufferSubDataARB + glDeleteBuffersARB + glGenBuffersARB + glGetBufferParameterivARB + glGetBufferPointervARB + glGetBufferSubDataARB + glIsBufferARB + glMapBufferARB + glUnmapBufferARB + glGenQueriesARB + glDeleteQueriesARB + glIsQueryARB + glBeginQueryARB + glEndQueryARB + glGetQueryivARB + glGetQueryObjectivARB + glGetQueryObjectuivARB + glBindBuffer + glBufferData + glBufferSubData + glDeleteBuffers + glGenBuffers + glGetBufferParameteriv + glGetBufferPointerv + glGetBufferSubData + glIsBuffer + glMapBuffer + glUnmapBuffer + glGenQueries + glDeleteQueries + glIsQuery + glBeginQuery + glEndQuery + glGetQueryiv + glGetQueryObjectiv + glGetQueryObjectuiv +; +; WGL API + wglChoosePixelFormat + wglCopyContext + wglCreateContext + wglCreateLayerContext + wglDeleteContext + wglDescribeLayerPlane + wglDescribePixelFormat + wglGetCurrentContext + wglGetCurrentDC + wglGetLayerPaletteEntries + wglGetPixelFormat + wglGetProcAddress + wglMakeCurrent + wglRealizeLayerPalette + wglSetLayerPaletteEntries + wglSetPixelFormat + wglShareLists + wglSwapBuffers + wglSwapLayerBuffers + wglUseFontBitmapsA + wglUseFontBitmapsW + wglUseFontOutlinesA + wglUseFontOutlinesW + wglGetExtensionsStringARB diff --git a/src/gallium/winsys/gdi/wgl.c b/src/gallium/winsys/gdi/wgl.c new file mode 100644 index 0000000000..50126014a8 --- /dev/null +++ b/src/gallium/winsys/gdi/wgl.c @@ -0,0 +1,703 @@ +/* $Id: wgl.c,v 1.12 2006/03/30 07:58:24 kschultz Exp $ */ + +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * File name : wgl.c + * WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru + * Some things originated from the 3Dfx WGL functions + */ + +/* + * This file contains the implementation of the wgl* functions for + * Mesa on Windows. Since these functions are provided by Windows in + * GDI/OpenGL, we must supply our versions that work with Mesa here. + */ + + +/* We're essentially building part of GDI here, so define this so that + * we get the right export linkage. */ +#ifdef __MINGW32__ + +#include +#include +#include +#include + +# if defined(BUILD_GL32) +# define WINGDIAPI __declspec(dllexport) +# else +# define __W32API_USE_DLLIMPORT__ +# endif + +#include +#include "GL/mesa_wgl.h" +#include + +#else + +#define _GDI32_ +#include + +#endif + +#include "glapi.h" +#include "GL/wmesa.h" /* protos for wmesa* functions */ + +/* + * Pixel Format Descriptors + */ + +/* Extend the PFD to include DB flag */ +struct __pixelformat__ +{ + PIXELFORMATDESCRIPTOR pfd; + GLboolean doubleBuffered; +}; + +/* These are the PFD's supported by this driver. */ +struct __pixelformat__ pfd[] = +{ + /* Double Buffer, alpha */ + { + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| + PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, + PFD_TYPE_RGBA, + 24, + 8, 0, + 8, 8, + 8, 16, + 8, 24, + 0, 0, 0, 0, 0, + 16, 8, + 0, 0, 0, + 0, 0, 0 + }, + GL_TRUE + }, + /* Single Buffer, alpha */ + { + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| + PFD_GENERIC_FORMAT, + PFD_TYPE_RGBA, + 24, + 8, 0, + 8, 8, + 8, 16, + 8, 24, + 0, 0, 0, 0, 0, + 16, 8, + 0, 0, 0, + 0, 0, 0 + }, + GL_FALSE + }, + /* Double Buffer, no alpha */ + { + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| + PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, + PFD_TYPE_RGBA, + 24, + 8, 0, + 8, 8, + 8, 16, + 0, 0, + 0, 0, 0, 0, 0, + 16, 8, + 0, 0, 0, + 0, 0, 0 + }, + GL_TRUE + }, + /* Single Buffer, no alpha */ + { + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| + PFD_GENERIC_FORMAT, + PFD_TYPE_RGBA, + 24, + 8, 0, + 8, 8, + 8, 16, + 0, 0, + 0, 0, 0, 0, 0, + 16, 8, + 0, 0, 0, + 0, 0, 0 + }, + GL_FALSE + }, +}; + +int npfd = sizeof(pfd) / sizeof(pfd[0]); + + +/* + * Contexts + */ + +typedef struct { + WMesaContext ctx; +} MesaWglCtx; + +#define MESAWGL_CTX_MAX_COUNT 20 + +static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT]; + +static unsigned ctx_count = 0; +static int ctx_current = -1; +static unsigned curPFD = 0; + +static HDC CurrentHDC = 0; + + +WINGDIAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc) +{ + int i = 0; + if (!ctx_count) { + for(i=0;inSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1) + { + SetLastError(0); + return(0); + } + for(i = 0; i < npfd;i++) + { + delta = 0; + if( + (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) && + !(pfd[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW)) + continue; + if( + (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) && + !(pfd[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP)) + continue; + if( + (ppfd->dwFlags & PFD_SUPPORT_GDI) && + !(pfd[i].pfd.dwFlags & PFD_SUPPORT_GDI)) + continue; + if( + (ppfd->dwFlags & PFD_SUPPORT_OPENGL) && + !(pfd[i].pfd.dwFlags & PFD_SUPPORT_OPENGL)) + continue; + if( + !(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) && + ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != + (pfd[i].pfd.dwFlags & PFD_DOUBLEBUFFER))) + continue; + if( + !(ppfd->dwFlags & PFD_STEREO_DONTCARE) && + ((ppfd->dwFlags & PFD_STEREO) != + (pfd[i].pfd.dwFlags & PFD_STEREO))) + continue; + if(ppfd->iPixelType != pfd[i].pfd.iPixelType) + delta++; + if(ppfd->cAlphaBits != pfd[i].pfd.cAlphaBits) + delta++; + if(delta < bestdelta) + { + best = i + 1; + bestdelta = delta; + if(bestdelta == 0) + break; + } + } + if(best == -1) + { + SetLastError(0); + return(0); + } + return(best); +} + +WINGDIAPI int GLAPIENTRY wglDescribePixelFormat(HDC hdc, + int iPixelFormat, + UINT nBytes, + LPPIXELFORMATDESCRIPTOR ppfd) +{ + (void) hdc; + + if(ppfd == NULL) + return(npfd); + if(iPixelFormat < 1 || iPixelFormat > npfd || + nBytes != sizeof(PIXELFORMATDESCRIPTOR)) + { + SetLastError(0); + return(0); + } + *ppfd = pfd[iPixelFormat - 1].pfd; + return(npfd); +} + +WINGDIAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc) +{ + PROC p = (PROC) _glapi_get_proc_address((const char *) lpszProc); + if (p) + return p; + + SetLastError(0); + return(NULL); +} + +WINGDIAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc) +{ + (void) hdc; + if(curPFD == 0) { + SetLastError(0); + return(0); + } + return(curPFD); +} + +WINGDIAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat, + const PIXELFORMATDESCRIPTOR *ppfd) +{ + (void) hdc; + + if(iPixelFormat < 1 || iPixelFormat > npfd || + ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) { + SetLastError(0); + return(FALSE); + } + curPFD = iPixelFormat; + return(TRUE); +} + +WINGDIAPI BOOL GLAPIENTRY wglSwapBuffers(HDC hdc) +{ + WMesaSwapBuffers(hdc); + return TRUE; +} + +static FIXED FixedFromDouble(double d) +{ + long l = (long) (d * 65536L); + return *(FIXED *) (void *) &l; +} + + +/* +** This is cribbed from FX/fxwgl.c, and seems to implement support +** for bitmap fonts where the wglUseFontBitmapsA() code implements +** support for outline fonts. In combination they hopefully give +** fairly generic support for fonts. +*/ +static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar, + DWORD numChars, DWORD listBase) +{ +#define VERIFY(a) a + + TEXTMETRIC metric; + BITMAPINFO *dibInfo; + HDC bitDevice; + COLORREF tempColor; + int i; + + VERIFY(GetTextMetrics(fontDevice, &metric)); + + dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1); + dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + dibInfo->bmiHeader.biPlanes = 1; + dibInfo->bmiHeader.biBitCount = 1; + dibInfo->bmiHeader.biCompression = BI_RGB; + + bitDevice = CreateCompatibleDC(fontDevice); + + /* Swap fore and back colors so the bitmap has the right polarity */ + tempColor = GetBkColor(bitDevice); + SetBkColor(bitDevice, GetTextColor(bitDevice)); + SetTextColor(bitDevice, tempColor); + + /* Place chars based on base line */ + VERIFY(SetTextAlign(bitDevice, TA_BASELINE) != GDI_ERROR ? 1 : 0); + + for(i = 0; i < (int)numChars; i++) { + SIZE size; + char curChar; + int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res; + HBITMAP bitObject; + HGDIOBJ origBmap; + unsigned char *bmap; + + curChar = (char)(i + firstChar); + + /* Find how high/wide this character is */ + VERIFY(GetTextExtentPoint32(bitDevice, (LPCWSTR)&curChar, 1, &size)); + + /* Create the output bitmap */ + charWidth = size.cx; + charHeight = size.cy; + /* Round up to the next multiple of 32 bits */ + bmapWidth = ((charWidth + 31) / 32) * 32; + bmapHeight = charHeight; + bitObject = CreateCompatibleBitmap(bitDevice, + bmapWidth, + bmapHeight); + /* VERIFY(bitObject); */ + + /* Assign the output bitmap to the device */ + origBmap = SelectObject(bitDevice, bitObject); + (void) VERIFY(origBmap); + + VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) ); + + /* Use our source font on the device */ + VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT))); + + /* Draw the character */ + VERIFY(TextOut(bitDevice, 0, metric.tmAscent, (LPCWSTR)&curChar, 1)); + + /* Unselect our bmap object */ + VERIFY(SelectObject(bitDevice, origBmap)); + + /* Convert the display dependant representation to a 1 bit deep DIB */ + numBytes = (bmapWidth * bmapHeight) / 8; + bmap = (unsigned char *)malloc(numBytes); + dibInfo->bmiHeader.biWidth = bmapWidth; + dibInfo->bmiHeader.biHeight = bmapHeight; + res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap, + dibInfo, + DIB_RGB_COLORS); + /* VERIFY(res); */ + + /* Create the GL object */ + glNewList(i + listBase, GL_COMPILE); + glBitmap(bmapWidth, bmapHeight, 0.0, (GLfloat)metric.tmDescent, + (GLfloat)charWidth, 0.0, + bmap); + glEndList(); + /* CheckGL(); */ + + /* Destroy the bmap object */ + DeleteObject(bitObject); + + /* Deallocate the bitmap data */ + free(bmap); + } + + /* Destroy the DC */ + VERIFY(DeleteDC(bitDevice)); + + free(dibInfo); + + return TRUE; +#undef VERIFY +} + +WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsA(HDC hdc, DWORD first, + DWORD count, DWORD listBase) +{ + int i; + GLuint font_list; + DWORD size; + GLYPHMETRICS gm; + HANDLE hBits; + LPSTR lpBits; + MAT2 mat; + int success = TRUE; + + if (count == 0) + return FALSE; + + font_list = listBase; + + mat.eM11 = FixedFromDouble(1); + mat.eM12 = FixedFromDouble(0); + mat.eM21 = FixedFromDouble(0); + mat.eM22 = FixedFromDouble(-1); + + memset(&gm,0,sizeof(gm)); + + /* + ** If we can't get the glyph outline, it may be because this is a fixed + ** font. Try processing it that way. + */ + if( GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat) + == GDI_ERROR ) { + return wglUseFontBitmaps_FX( hdc, first, count, listBase ); + } + + /* + ** Otherwise process all desired characters. + */ + for (i = 0; i < (int)count; i++) { + DWORD err; + + glNewList( font_list+i, GL_COMPILE ); + + /* allocate space for the bitmap/outline */ + size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, + &gm, 0, NULL, &mat); + if (size == GDI_ERROR) { + glEndList( ); + err = GetLastError(); + success = FALSE; + continue; + } + + hBits = GlobalAlloc(GHND, size+1); + lpBits = GlobalLock(hBits); + + err = + GetGlyphOutline(hdc, /* handle to device context */ + first + i, /* character to query */ + GGO_BITMAP, /* format of data to return */ + &gm, /* ptr to structure for metrics*/ + size, /* size of buffer for data */ + lpBits, /* pointer to buffer for data */ + &mat /* pointer to transformation */ + /* matrix structure */ + ); + + if (err == GDI_ERROR) { + GlobalUnlock(hBits); + GlobalFree(hBits); + + glEndList( ); + err = GetLastError(); + success = FALSE; + continue; + } + + glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY, + (GLfloat)-gm.gmptGlyphOrigin.x, + (GLfloat)gm.gmptGlyphOrigin.y, + (GLfloat)gm.gmCellIncX, + (GLfloat)gm.gmCellIncY, + (const GLubyte * )lpBits); + + GlobalUnlock(hBits); + GlobalFree(hBits); + + glEndList( ); + } + + return success; +} + + + +/* NOT IMPLEMENTED YET */ +WINGDIAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc, + HGLRC hglrcDst, + UINT mask) +{ + (void) hglrcSrc; (void) hglrcDst; (void) mask; + return(FALSE); +} + +WINGDIAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc, + int iLayerPlane) +{ + (void) hdc; (void) iLayerPlane; + SetLastError(0); + return(NULL); +} + +WINGDIAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1, + HGLRC hglrc2) +{ + (void) hglrc1; (void) hglrc2; + return(TRUE); +} + + +WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc, + DWORD first, + DWORD count, + DWORD listBase) +{ + (void) hdc; (void) first; (void) count; (void) listBase; + return FALSE; +} + +WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc, + DWORD first, + DWORD count, + DWORD listBase, + FLOAT deviation, + FLOAT extrusion, + int format, + LPGLYPHMETRICSFLOAT lpgmf) +{ + (void) hdc; (void) first; (void) count; + (void) listBase; (void) deviation; (void) extrusion; (void) format; + (void) lpgmf; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc, + DWORD first, + DWORD count, + DWORD listBase, + FLOAT deviation, + FLOAT extrusion, + int format, + LPGLYPHMETRICSFLOAT lpgmf) +{ + (void) hdc; (void) first; (void) count; + (void) listBase; (void) deviation; (void) extrusion; (void) format; + (void) lpgmf; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nBytes, + LPLAYERPLANEDESCRIPTOR plpd) +{ + (void) hdc; (void) iPixelFormat; (void) iLayerPlane; + (void) nBytes; (void) plpd; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc, + int iLayerPlane, + int iStart, + int cEntries, + CONST COLORREF *pcr) +{ + (void) hdc; (void) iLayerPlane; (void) iStart; + (void) cEntries; (void) pcr; + SetLastError(0); + return(0); +} + +WINGDIAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc, + int iLayerPlane, + int iStart, + int cEntries, + COLORREF *pcr) +{ + (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr; + SetLastError(0); + return(0); +} + +WINGDIAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc, + int iLayerPlane, + BOOL bRealize) +{ + (void) hdc; (void) iLayerPlane; (void) bRealize; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc, + UINT fuPlanes) +{ + (void) hdc; (void) fuPlanes; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI const char * GLAPIENTRY wglGetExtensionsStringARB(HDC hdc) +{ + return "WGL_ARB_extensions_string"; +} diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c new file mode 100644 index 0000000000..74a8292352 --- /dev/null +++ b/src/gallium/winsys/gdi/wmesa.c @@ -0,0 +1,890 @@ +/* + * Windows (Win32/Win64) device driver for Mesa + * + */ + +#include "mtypes.h" +#include +#include "wmesadef.h" + +#undef Elements + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "softpipe/sp_winsys.h" +#include "glapi/glapi.h" +#include "colors.h" + +extern GLvisual * +_mesa_create_visual( GLboolean rgbFlag, + GLboolean dbFlag, + GLboolean stereoFlag, + GLint redBits, + GLint greenBits, + GLint blueBits, + GLint alphaBits, + GLint indexBits, + GLint depthBits, + GLint stencilBits, + GLint accumRedBits, + GLint accumGreenBits, + GLint accumBlueBits, + GLint accumAlphaBits, + GLint numSamples ); + +/* linked list of our Framebuffers (windows) */ +WMesaFramebuffer FirstFramebuffer = NULL; + +struct wmesa_pipe_winsys +{ + struct pipe_winsys base; +}; + +/** + * Choose the pixel format for the given visual. + * This will tell the gallium driver how to pack pixel data into + * drawing surfaces. + */ +static GLuint +choose_pixel_format(GLvisual *v) +{ +#if 1 + return PIPE_FORMAT_A8R8G8B8_UNORM; +#else + if ( GET_REDMASK(v) == 0x0000ff + && GET_GREENMASK(v) == 0x00ff00 + && GET_BLUEMASK(v) == 0xff0000 + && v->BitsPerPixel == 32) { + if (CHECK_BYTE_ORDER(v)) { + /* no byteswapping needed */ + return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */; + } + else { + return PIPE_FORMAT_R8G8B8A8_UNORM; + } + } + else if ( GET_REDMASK(v) == 0xff0000 + && GET_GREENMASK(v) == 0x00ff00 + && GET_BLUEMASK(v) == 0x0000ff + && v->BitsPerPixel == 32) { + if (CHECK_BYTE_ORDER(v)) { + /* no byteswapping needed */ + return PIPE_FORMAT_A8R8G8B8_UNORM; + } + else { + return PIPE_FORMAT_B8G8R8A8_UNORM; + } + } + else if ( GET_REDMASK(v) == 0xf800 + && GET_GREENMASK(v) == 0x07e0 + && GET_BLUEMASK(v) == 0x001f + && CHECK_BYTE_ORDER(v) + && v->BitsPerPixel == 16) { + /* 5-6-5 RGB */ + return PIPE_FORMAT_R5G6B5_UNORM; + } + +printf("BITS %d\n",v->BitsPerPixel); + assert(0); + return 0; +#endif +} + +/* + * Determine the pixel format based on the pixel size. + */ +static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC) +{ + /* Only 16 and 32 bit targets are supported now */ + assert(pwfb->cColorBits == 0 || + pwfb->cColorBits == 16 || + pwfb->cColorBits == 32); + + switch(pwfb->cColorBits){ + case 8: + pwfb->pixelformat = PF_INDEX8; + break; + case 16: + pwfb->pixelformat = PF_5R6G5B; + break; + case 32: + pwfb->pixelformat = PF_8R8G8B; + break; + default: + pwfb->pixelformat = PF_BADFORMAT; + } +} + + +/** + * Create DIB for back buffer. + * We write into this memory with the span routines and then blit it + * to the window on a buffer swap. + */ +BOOL wmCreateBackingStore(WMesaFramebuffer pwfb, long lxSize, long lySize) +{ + HDC hdc = pwfb->hDC; + BITMAPINFO bmi; + LPBITMAPINFO pbmi = &bmi; + HDC hic; + + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = lxSize; + pbmi->bmiHeader.biHeight= -lySize; + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biBitCount = pwfb->cColorBits; + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biXPelsPerMeter = 0; + pbmi->bmiHeader.biYPelsPerMeter = 0; + pbmi->bmiHeader.biClrUsed = 0; + pbmi->bmiHeader.biClrImportant = 0; + + hic = CreateIC("display", NULL, NULL, NULL); + pwfb->dib_hDC = CreateCompatibleDC(hic); + + pwfb->hbmDIB = CreateDIBSection(hic, + pbmi, + DIB_RGB_COLORS, + (void **)&(pwfb->pbPixels), + 0, + 0); + pwfb->hOldBitmap = SelectObject(pwfb->dib_hDC, pwfb->hbmDIB); + + DeleteDC(hic); + + wmSetPixelFormat(pwfb, pwfb->hDC); + return TRUE; +} + +/** + * Create a new WMesaFramebuffer object which will correspond to the + * given HDC (Window handle). + */ +WMesaFramebuffer +wmesa_new_framebuffer(HDC hdc, GLvisual *visual, GLuint width, GLuint height) +{ + WMesaFramebuffer pwfb + = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer)); + if (pwfb) { + enum pipe_format colorFormat, depthFormat, stencilFormat; + + /* determine PIPE_FORMATs for buffers */ + colorFormat = choose_pixel_format(visual); + + if (visual->depthBits == 0) + depthFormat = PIPE_FORMAT_NONE; + else if (visual->depthBits <= 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits <= 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_Z32_UNORM; + + if (visual->stencilBits == 8) { + if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) + stencilFormat = depthFormat; + else + stencilFormat = PIPE_FORMAT_S8_UNORM; + } + else { + stencilFormat = PIPE_FORMAT_NONE; + } + + pwfb->stfb = st_create_framebuffer(visual, + colorFormat, depthFormat, stencilFormat, + width, height, + (void *) pwfb); + + pwfb->cColorBits = GetDeviceCaps(hdc, BITSPIXEL); + +#if 0 + wmCreateBackingStore(pwfb, width, height); +#endif + + pwfb->hDC = hdc; + /* insert at head of list */ + pwfb->next = FirstFramebuffer; + FirstFramebuffer = pwfb; + } + return pwfb; +} + +/** + * Given an hdc, free the corresponding WMesaFramebuffer + */ +void +wmesa_free_framebuffer(HDC hdc) +{ + WMesaFramebuffer pwfb, prev; + for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { + if (pwfb->hDC == hdc) + break; + prev = pwfb; + } + if (pwfb) { + if (pwfb == FirstFramebuffer) + FirstFramebuffer = pwfb->next; + else + prev->next = pwfb->next; + free(pwfb); + } +} + +/** + * Given an hdc, return the corresponding WMesaFramebuffer + */ +WMesaFramebuffer +wmesa_lookup_framebuffer(HDC hdc) +{ + WMesaFramebuffer pwfb; + for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { + if (pwfb->hDC == hdc) + return pwfb; + } + return NULL; +} + + +/** + * Given a GLframebuffer, return the corresponding WMesaFramebuffer. + */ +static WMesaFramebuffer wmesa_framebuffer(GLframebuffer *fb) +{ + return (WMesaFramebuffer) fb; +} + + +/** + * Given a GLcontext, return the corresponding WMesaContext. + */ +static WMesaContext wmesa_context(const GLcontext *ctx) +{ + return (WMesaContext) ctx; +} + +static wmDeleteBackingStore(WMesaFramebuffer pwfb) +{ + if (pwfb->hbmDIB) { + SelectObject(pwfb->dib_hDC, pwfb->hOldBitmap); + DeleteDC(pwfb->dib_hDC); + DeleteObject(pwfb->hbmDIB); + } +} + + +/** + * Find the width and height of the window named by hdc. + */ +static void +get_window_size(HDC hdc, GLuint *width, GLuint *height) +{ + if (WindowFromDC(hdc)) { + RECT rect; + GetClientRect(WindowFromDC(hdc), &rect); + *width = rect.right - rect.left; + *height = rect.bottom - rect.top; + } + else { /* Memory context */ + /* From contributed code - use the size of the desktop + * for the size of a memory context (?) */ + *width = GetDeviceCaps(hdc, HORZRES); + *height = GetDeviceCaps(hdc, VERTRES); + } +} + +/** + * Low-level OS/window system memory buffer + */ +struct wm_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; +}; + +struct wmesa_surface +{ + struct pipe_surface surface; + + int no_swap; +}; + + +/** Cast wrapper */ +static INLINE struct wmesa_surface * +wmesa_surface(struct pipe_surface *ps) +{ +// assert(0); + return (struct wmesa_surface *) ps; +} + +/** + * Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque + * buffer pointer... + */ +static INLINE struct wm_buffer * +wm_buffer( struct pipe_buffer *buf ) +{ + return (struct wm_buffer *)buf; +} + + + +/* Most callbacks map direcly onto dri_bufmgr operations: + */ +static void * +wm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, + unsigned flags) +{ + struct wm_buffer *wm_buf = wm_buffer(buf); + wm_buf->mapped = wm_buf->data; + return wm_buf->mapped; +} + +static void +wm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct wm_buffer *wm_buf = wm_buffer(buf); + wm_buf->mapped = NULL; +} + +static void +wm_buffer_destroy(struct pipe_winsys *pws, + struct pipe_buffer *buf) +{ + struct wm_buffer *oldBuf = wm_buffer(buf); + + if (oldBuf->data) { + { + if (!oldBuf->userBuffer) { + align_free(oldBuf->data); + } + } + + oldBuf->data = NULL; + } + + free(oldBuf); +} + + +static void +wm_flush_frontbuffer(struct pipe_winsys *pws, + struct pipe_surface *surf, + void *context_private) +{ + WMesaContext pwc = context_private; + WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(pwc->hDC); + struct wm_buffer *wm_buf; + BITMAPINFO bmi, *pbmi; + +#if 0 + if (pwfb) + BitBlt(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, + pwfb->dib_hDC, 0, 0, SRCCOPY); +#else + wm_buf = wm_buffer(surf->buffer); + + pbmi = &bmi; + memset(pbmi, 0, sizeof(BITMAPINFO)); + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = pwfb->stfb->Base.Width; + pbmi->bmiHeader.biHeight= -((long)pwfb->stfb->Base.Height); + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biBitCount = pwfb->cColorBits; + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biXPelsPerMeter = 0; + pbmi->bmiHeader.biYPelsPerMeter = 0; + pbmi->bmiHeader.biClrUsed = 0; + pbmi->bmiHeader.biClrImportant = 0; + + StretchDIBits(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, wm_buf->data, pbmi, 0, SRCCOPY); +#endif +} + + + +static const char * +wm_get_name(struct pipe_winsys *pws) +{ + return "gdi"; +} + +static struct pipe_buffer * +wm_buffer_create(struct pipe_winsys *pws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct wm_buffer *buffer = CALLOC_STRUCT(wm_buffer); + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + if (buffer->data == NULL) { + /* align to 16-byte multiple for Cell */ + buffer->data = align_malloc(size, max(alignment, 16)); + } + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +wm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) +{ + struct wm_buffer *buffer = CALLOC_STRUCT(wm_buffer); + buffer->base.refcount = 1; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +wm_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if(!surf->buffer) + return -1; + + return 0; +} + + +/** + * Called via winsys->surface_alloc() to create new surfaces. + */ +static struct pipe_surface * +wm_surface_alloc(struct pipe_winsys *ws) +{ + struct wmesa_surface *wms = CALLOC_STRUCT(wmesa_surface); + static boolean no_swap = 0; + static boolean firsttime = 1; + + if (firsttime) { + no_swap = getenv("SP_NO_RAST") != NULL; + firsttime = 0; + } + + assert(ws); + + wms->surface.refcount = 1; + wms->surface.winsys = ws; + + wms->no_swap = no_swap; + + return &wms->surface; +} + +static void +wm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + +/* + * Fence functions - basically nothing to do, as we don't create any actual + * fence objects. + */ + +static void +wm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +wm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +wm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + + +struct pipe_winsys * +wmesa_get_pipe_winsys(GLvisual *visual) +{ + static struct wmesa_pipe_winsys *ws = NULL; + + if (!ws) { + ws = CALLOC_STRUCT(wmesa_pipe_winsys); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + */ + ws->base.buffer_create = wm_buffer_create; + ws->base.user_buffer_create = wm_user_buffer_create; + ws->base.buffer_map = wm_buffer_map; + ws->base.buffer_unmap = wm_buffer_unmap; + ws->base.buffer_destroy = wm_buffer_destroy; + + ws->base.surface_alloc = wm_surface_alloc; + ws->base.surface_alloc_storage = wm_surface_alloc_storage; + ws->base.surface_release = wm_surface_release; + + ws->base.fence_reference = wm_fence_reference; + ws->base.fence_signalled = wm_fence_signalled; + ws->base.fence_finish = wm_fence_finish; + + ws->base.flush_frontbuffer = wm_flush_frontbuffer; + ws->base.get_name = wm_get_name; + } + + return &ws->base; +} + + + +/**********************************************************************/ +/***** WMESA Functions *****/ +/**********************************************************************/ + +WMesaContext WMesaCreateContext(HDC hDC, + HPALETTE* Pal, + GLboolean rgb_flag, + GLboolean db_flag, + GLboolean alpha_flag) +{ + WMesaContext c; + struct pipe_winsys *pws; + struct pipe_context *pipe; + struct pipe_screen *screen; + GLint red_bits, green_bits, blue_bits, alpha_bits; + GLvisual *visual; + + (void) Pal; + + /* Indexed mode not supported */ + if (!rgb_flag) + return NULL; + + /* Allocate wmesa context */ + c = CALLOC_STRUCT(wmesa_context); + if (!c) + return NULL; + + c->hDC = hDC; + + /* Get data for visual */ + /* Dealing with this is actually a bit of overkill because Mesa will end + * up treating all color component size requests less than 8 by using + * a single byte per channel. In addition, the interface to the span + * routines passes colors as an entire byte per channel anyway, so there + * is nothing to be saved by telling the visual to be 16 bits if the device + * is 16 bits. That is, Mesa is going to compute colors down to 8 bits per + * channel anyway. + * But we go through the motions here anyway. + */ + c->cColorBits = GetDeviceCaps(c->hDC, BITSPIXEL); + + switch (c->cColorBits) { + case 16: + red_bits = green_bits = blue_bits = 5; + alpha_bits = 0; + break; + default: + red_bits = green_bits = blue_bits = 8; + alpha_bits = 8; + break; + } + /* Create visual based on flags */ + visual = _mesa_create_visual(rgb_flag, + db_flag, /* db_flag */ + GL_FALSE, /* stereo */ + red_bits, green_bits, blue_bits, /* color RGB */ + alpha_flag ? alpha_bits : 0, /* color A */ + 0, /* index bits */ + DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */ + 8, /* stencil_bits */ + 16,16,16, /* accum RGB */ + alpha_flag ? 16 : 0, /* accum A */ + 1); /* num samples */ + + if (!visual) { + _mesa_free(c); + return NULL; + } + + pws = wmesa_get_pipe_winsys(visual); + + screen = softpipe_create_screen(pws); + + if (!screen) { + _mesa_free(c); + return NULL; + } + + pipe = softpipe_create(screen, pws, NULL); + + if (!pipe) { + /* FIXME - free screen */ + _mesa_free(c); + return NULL; + } + + pipe->priv = c; + + c->st = st_create_context(pipe, visual, NULL); + + c->st->ctx->DriverCtx = c; + + return c; +} + + +void WMesaDestroyContext( WMesaContext pwc ) +{ + GLcontext *ctx = pwc->st->ctx; + WMesaFramebuffer pwfb; + GET_CURRENT_CONTEXT(cur_ctx); + + if (cur_ctx == ctx) { + /* unbind current if deleting current context */ + WMesaMakeCurrent(NULL, NULL); + } + + /* clean up frame buffer resources */ + pwfb = wmesa_lookup_framebuffer(pwc->hDC); + if (pwfb) { +#if 0 + wmDeleteBackingStore(pwfb); +#endif + wmesa_free_framebuffer(pwc->hDC); + } + + /* Release for device, not memory contexts */ + if (WindowFromDC(pwc->hDC) != NULL) + { + ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC); + } + + st_destroy_context(pwc->st); + _mesa_free(pwc); +} + + +void WMesaMakeCurrent(WMesaContext c, HDC hdc) +{ + GLuint width = 0, height = 0; + WMesaFramebuffer pwfb; + + { + /* return if already current */ + GET_CURRENT_CONTEXT(ctx); + WMesaContext pwc = wmesa_context(ctx); + if (pwc && c == pwc && pwc->hDC == hdc) + return; + } + + pwfb = wmesa_lookup_framebuffer(hdc); + + if (hdc) { + get_window_size(hdc, &width, &height); + } + + /* Lazy creation of framebuffers */ + if (c && !pwfb && (hdc != 0)) { + GLvisual *visual = &c->st->ctx->Visual; + + pwfb = wmesa_new_framebuffer(hdc, visual, width, height); + } + + if (c && pwfb) { + st_make_current(c->st, pwfb->stfb, pwfb->stfb); + + st_resize_framebuffer(pwfb->stfb, width, height); + } + else { + /* Detach */ + st_make_current( NULL, NULL, NULL ); + } +} + + +void WMesaSwapBuffers( HDC hdc ) +{ + struct pipe_surface *surf; + struct wm_buffer *wm_buf; + WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc); + BITMAPINFO bmi, *pbmi; + + if (!pwfb) { + _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc"); + return; + } + + + /* If we're swapping the buffer associated with the current context + * we have to flush any pending rendering commands first. + */ + st_notify_swapbuffers(pwfb->stfb); + +#if 0 + BitBlt(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, + pwfb->dib_hDC, 0, 0, SRCCOPY); +#else + surf = st_get_framebuffer_surface(pwfb->stfb, ST_SURFACE_BACK_LEFT); + wm_buf = wm_buffer(surf->buffer); + + pbmi = &bmi; + memset(pbmi, 0, sizeof(BITMAPINFO)); + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = pwfb->stfb->Base.Width; + pbmi->bmiHeader.biHeight= -((long)pwfb->stfb->Base.Height); + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biBitCount = pwfb->cColorBits; + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biXPelsPerMeter = 0; + pbmi->bmiHeader.biYPelsPerMeter = 0; + pbmi->bmiHeader.biClrUsed = 0; + pbmi->bmiHeader.biClrImportant = 0; + + StretchDIBits(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, wm_buf->data, pbmi, 0, SRCCOPY); + + { + GLuint width = 0, height = 0; + + get_window_size(pwfb->hDC, &width, &height); + + st_resize_framebuffer(pwfb->stfb, width, height); + } +#endif +} + +/* This is hopefully a temporary hack to define some needed dispatch + * table entries. Hopefully, I'll find a better solution. The + * dispatch table generation scripts ought to be making these dummy + * stubs as well. */ +#if !defined(__MINGW32__) || !defined(GL_NO_STDCALL) +void gl_dispatch_stub_543(void){} +void gl_dispatch_stub_544(void){} +void gl_dispatch_stub_545(void){} +void gl_dispatch_stub_546(void){} +void gl_dispatch_stub_547(void){} +void gl_dispatch_stub_548(void){} +void gl_dispatch_stub_549(void){} +void gl_dispatch_stub_550(void){} +void gl_dispatch_stub_551(void){} +void gl_dispatch_stub_552(void){} +void gl_dispatch_stub_553(void){} +void gl_dispatch_stub_554(void){} +void gl_dispatch_stub_555(void){} +void gl_dispatch_stub_556(void){} +void gl_dispatch_stub_557(void){} +void gl_dispatch_stub_558(void){} +void gl_dispatch_stub_559(void){} +void gl_dispatch_stub_560(void){} +void gl_dispatch_stub_561(void){} +void gl_dispatch_stub_565(void){} +void gl_dispatch_stub_566(void){} +void gl_dispatch_stub_577(void){} +void gl_dispatch_stub_578(void){} +void gl_dispatch_stub_603(void){} +void gl_dispatch_stub_645(void){} +void gl_dispatch_stub_646(void){} +void gl_dispatch_stub_647(void){} +void gl_dispatch_stub_648(void){} +void gl_dispatch_stub_649(void){} +void gl_dispatch_stub_650(void){} +void gl_dispatch_stub_651(void){} +void gl_dispatch_stub_652(void){} +void gl_dispatch_stub_653(void){} +void gl_dispatch_stub_733(void){} +void gl_dispatch_stub_734(void){} +void gl_dispatch_stub_735(void){} +void gl_dispatch_stub_736(void){} +void gl_dispatch_stub_737(void){} +void gl_dispatch_stub_738(void){} +void gl_dispatch_stub_744(void){} +void gl_dispatch_stub_745(void){} +void gl_dispatch_stub_746(void){} +void gl_dispatch_stub_760(void){} +void gl_dispatch_stub_761(void){} +void gl_dispatch_stub_763(void){} +void gl_dispatch_stub_765(void){} +void gl_dispatch_stub_766(void){} +void gl_dispatch_stub_767(void){} +void gl_dispatch_stub_768(void){} + +void gl_dispatch_stub_562(void){} +void gl_dispatch_stub_563(void){} +void gl_dispatch_stub_564(void){} +void gl_dispatch_stub_567(void){} +void gl_dispatch_stub_568(void){} +void gl_dispatch_stub_569(void){} +void gl_dispatch_stub_580(void){} +void gl_dispatch_stub_581(void){} +void gl_dispatch_stub_606(void){} +void gl_dispatch_stub_654(void){} +void gl_dispatch_stub_655(void){} +void gl_dispatch_stub_656(void){} +void gl_dispatch_stub_739(void){} +void gl_dispatch_stub_740(void){} +void gl_dispatch_stub_741(void){} +void gl_dispatch_stub_748(void){} +void gl_dispatch_stub_749(void){} +void gl_dispatch_stub_769(void){} +void gl_dispatch_stub_770(void){} +void gl_dispatch_stub_771(void){} +void gl_dispatch_stub_772(void){} +void gl_dispatch_stub_773(void){} + +#endif diff --git a/src/gallium/winsys/gdi/wmesadef.h b/src/gallium/winsys/gdi/wmesadef.h new file mode 100644 index 0000000000..fb8ce30a08 --- /dev/null +++ b/src/gallium/winsys/gdi/wmesadef.h @@ -0,0 +1,40 @@ +#ifndef WMESADEF_H +#define WMESADEF_H +#ifdef __MINGW32__ +#include +#endif +#if 0 +#include "context.h" +#endif +#include "state_tracker/st_context.h" +#include "state_tracker/st_public.h" + + +/** + * The Windows Mesa rendering context, derived from GLcontext. + */ +struct wmesa_context { + struct st_context *st; + HDC hDC; + BYTE cColorBits; +}; + +/** + * Windows framebuffer, derived from gl_framebuffer + */ +struct wmesa_framebuffer +{ + struct st_framebuffer *stfb; + HDC hDC; + int pixelformat; + BYTE cColorBits; + HDC dib_hDC; + HBITMAP hbmDIB; + HBITMAP hOldBitmap; + PBYTE pbPixels; + struct wmesa_framebuffer *next; +}; + +typedef struct wmesa_framebuffer *WMesaFramebuffer; + +#endif /* WMESADEF_H */ -- cgit v1.2.3 From 5a67df6d7cc8c74bfb71a8f19b8f6fdfb525091b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 3 Jun 2008 00:04:19 +0900 Subject: scons: Integrate gdi winsys. Conditional build of the winsys based on the platform. --- src/gallium/winsys/SConscript | 9 ++- src/gallium/winsys/dri/SConscript | 101 ++++++++++++++++---------------- src/gallium/winsys/dri/intel/SConscript | 76 ++++++++++++------------ src/gallium/winsys/xlib/SConscript | 50 ++++++++-------- 4 files changed, 124 insertions(+), 112 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index e8a581adb2..bf1718e7a5 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -1,11 +1,16 @@ Import('*') -if 'intel' in env['winsys'] and dri: +if env['dri']: SConscript([ 'dri/SConscript', ]) -if 'xlib' in env['winsys'] and not dri: +if 'xlib' in env['winsys']: SConscript([ 'xlib/SConscript', ]) + +if 'gdi' in env['winsys']: + SConscript([ + 'gdi/SConscript', + ]) diff --git a/src/gallium/winsys/dri/SConscript b/src/gallium/winsys/dri/SConscript index 8c56ce917c..aef5210a32 100644 --- a/src/gallium/winsys/dri/SConscript +++ b/src/gallium/winsys/dri/SConscript @@ -1,51 +1,54 @@ Import('*') -drienv = env.Clone() - -drienv.Replace(CPPPATH = [ - '#src/mesa/drivers/dri/common', - '#include', - '#include/GL/internal', - '#src/gallium/include', - '#src/gallium/auxiliary', - '#src/gallium/drivers', - '#src/mesa', - '#src/mesa/main', - '#src/mesa/glapi', - '#src/mesa/math', - '#src/mesa/transform', - '#src/mesa/shader', - '#src/mesa/swrast', - '#src/mesa/swrast_setup', - '#src/egl/main', - '#src/egl/drivers/dri', -]) - -drienv.ParseConfig('pkg-config --cflags --libs libdrm') - -COMMON_GALLIUM_SOURCES = [ - '#src/mesa/drivers/dri/common/utils.c', - '#src/mesa/drivers/dri/common/vblank.c', - '#src/mesa/drivers/dri/common/dri_util.c', - '#src/mesa/drivers/dri/common/xmlconfig.c', -] - -COMMON_BM_SOURCES = [ - '#src/mesa/drivers/dri/common/dri_bufmgr.c', - '#src/mesa/drivers/dri/common/dri_drmpool.c', -] - -Export([ - 'drienv', - 'COMMON_GALLIUM_SOURCES', - 'COMMON_BM_SOURCES', -]) - -# TODO: Installation -#install: $(LIBNAME) -# $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) -# $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) - -SConscript([ - 'intel/SConscript', -]) +if env['dri']: + + drienv = env.Clone() + + drienv.Replace(CPPPATH = [ + '#src/mesa/drivers/dri/common', + '#include', + '#include/GL/internal', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/gallium/drivers', + '#src/mesa', + '#src/mesa/main', + '#src/mesa/glapi', + '#src/mesa/math', + '#src/mesa/transform', + '#src/mesa/shader', + '#src/mesa/swrast', + '#src/mesa/swrast_setup', + '#src/egl/main', + '#src/egl/drivers/dri', + ]) + + drienv.ParseConfig('pkg-config --cflags --libs libdrm') + + COMMON_GALLIUM_SOURCES = [ + '#src/mesa/drivers/dri/common/utils.c', + '#src/mesa/drivers/dri/common/vblank.c', + '#src/mesa/drivers/dri/common/dri_util.c', + '#src/mesa/drivers/dri/common/xmlconfig.c', + ] + + COMMON_BM_SOURCES = [ + '#src/mesa/drivers/dri/common/dri_bufmgr.c', + '#src/mesa/drivers/dri/common/dri_drmpool.c', + ] + + Export([ + 'drienv', + 'COMMON_GALLIUM_SOURCES', + 'COMMON_BM_SOURCES', + ]) + + # TODO: Installation + #install: $(LIBNAME) + # $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) + # $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + + if 'intel' in env['winsys']: + SConscript([ + 'intel/SConscript', + ]) diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript index 0ad19d42a8..6a4f50afcc 100644 --- a/src/gallium/winsys/dri/intel/SConscript +++ b/src/gallium/winsys/dri/intel/SConscript @@ -1,39 +1,41 @@ Import('*') -env = drienv.Clone() - -env.Append(CPPPATH = [ - '../intel', - 'server' -]) - -#MINIGLX_SOURCES = server/intel_dri.c - -DRIVER_SOURCES = [ - 'intel_winsys_pipe.c', - 'intel_winsys_softpipe.c', - 'intel_winsys_i915.c', - 'intel_batchbuffer.c', - 'intel_swapbuffers.c', - 'intel_context.c', - 'intel_lock.c', - 'intel_screen.c', - 'intel_batchpool.c', -] - -sources = \ - COMMON_GALLIUM_SOURCES + \ - COMMON_BM_SOURCES + \ - DRIVER_SOURCES - -drivers = [ - softpipe, - i915simple -] - -# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -env.SharedLibrary( - target ='i915tex_dri.so', - source = sources, - LIBS = drivers + mesa + auxiliaries + env['LIBS'], -) \ No newline at end of file +if 'mesa' in env['statetrackers']: + + env = drienv.Clone() + + env.Append(CPPPATH = [ + '../intel', + 'server' + ]) + + #MINIGLX_SOURCES = server/intel_dri.c + + DRIVER_SOURCES = [ + 'intel_winsys_pipe.c', + 'intel_winsys_softpipe.c', + 'intel_winsys_i915.c', + 'intel_batchbuffer.c', + 'intel_swapbuffers.c', + 'intel_context.c', + 'intel_lock.c', + 'intel_screen.c', + 'intel_batchpool.c', + ] + + sources = \ + COMMON_GALLIUM_SOURCES + \ + COMMON_BM_SOURCES + \ + DRIVER_SOURCES + + drivers = [ + softpipe, + i915simple + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='i915tex_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 218b89285f..5e98a36abc 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -3,30 +3,32 @@ Import('*') -env = env.Clone() +if env['platform'] == 'linux' and 'mesa' in env['statetrackers'] and not env['dri']: -env.Append(CPPPATH = [ - '#/src/mesa', - '#/src/mesa/main', -]) + env = env.Clone() -sources = [ - 'glxapi.c', - 'fakeglx.c', - 'xfonts.c', - 'xm_api.c', - 'xm_winsys.c', - 'xm_winsys_aub.c', - 'brw_aub.c', -] - -drivers = [ - softpipe, -] + env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', + ]) -# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -env.SharedLibrary( - target ='GL', - source = sources, - LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], -) + sources = [ + 'glxapi.c', + 'fakeglx.c', + 'xfonts.c', + 'xm_api.c', + 'xm_winsys.c', + 'xm_winsys_aub.c', + 'brw_aub.c', + ] + + drivers = [ + softpipe, + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='GL', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], + ) -- cgit v1.2.3 From 7cc23a9eaebc788ae34f6e06c6227524d08a7693 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 2 Jun 2008 17:22:45 +0200 Subject: i915: Implement and use the reworked batchbuffer code --- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 46 ++++++++++++------------ src/gallium/winsys/dri/intel/intel_batchbuffer.h | 19 +++++----- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 35 +++--------------- 3 files changed, 39 insertions(+), 61 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 09d4eef484..aa33c12045 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -65,8 +65,10 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch) driBOUnrefUserList(batch->list); driBOResetList(batch->list); - batch->size = batch->intel->intelScreen->max_batch_size; - driBOData(batch->buffer, batch->size, NULL, NULL, 0); + /* base.size is the size available to the i915simple driver */ + batch->base.size = batch->intel->intelScreen->max_batch_size - BATCH_RESERVED; + batch->base.actual_size = batch->intel->intelScreen->max_batch_size; + driBOData(batch->buffer, batch->base.actual_size, NULL, NULL, 0); /* * Add the batchbuffer to the validate list. @@ -105,9 +107,9 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch) batch->reloc[2] = 0; /* Only a single relocation list. */ batch->reloc[3] = 0; /* Only a single relocation list. */ - batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->base.map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); batch->poolOffset = driBOPoolOffset(batch->buffer); - batch->ptr = batch->map; + batch->base.ptr = batch->base.map; batch->dirty_state = ~0; batch->nr_relocs = 0; batch->flags = 0; @@ -142,9 +144,9 @@ intel_batchbuffer_free(struct intel_batchbuffer *batch) DRM_FENCE_TYPE_EXE, GL_FALSE); driFenceUnReference(&batch->last_fence); } - if (batch->map) { + if (batch->base.map) { driBOUnmap(batch->buffer); - batch->map = NULL; + batch->base.map = NULL; } driBOUnReference(batch->buffer); driBOFreeList(batch->list); @@ -191,7 +193,7 @@ intel_offset_relocation(struct intel_batchbuffer *batch, reloc = batch->reloc + (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); - reloc[0] = ((uint8_t *)batch->ptr - batch->drmBOVirtual); + reloc[0] = ((uint8_t *)batch->base.ptr - batch->drmBOVirtual); intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add); reloc[1] = pre_add; reloc[2] = itemLoc; @@ -382,7 +384,7 @@ struct _DriFenceObject * intel_batchbuffer_flush(struct intel_batchbuffer *batch) { struct intel_context *intel = batch->intel; - GLuint used = batch->ptr - batch->map; + GLuint used = batch->base.ptr - batch->base.map; GLboolean was_locked = intel->locked; struct _DriFenceObject *fence; @@ -396,32 +398,32 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) */ #if 0 /* ZZZ JB: what should we do here? */ if (used & 4) { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->base.ptr)[1] = 0; + ((int *) batch->base.ptr)[2] = MI_BATCH_BUFFER_END; used += 12; } else { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->base.ptr)[1] = MI_BATCH_BUFFER_END; used += 8; } #else if (used & 4) { - ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; + ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->base.ptr)[1] = 0; + ((int *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; used += 12; } else { - ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; + ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; used += 8; } #endif driBOUnmap(batch->buffer); - batch->ptr = NULL; - batch->map = NULL; + batch->base.ptr = NULL; + batch->base.map = NULL; /* TODO: Just pass the relocation list and dma buffer up to the * kernel. @@ -455,6 +457,6 @@ intel_batchbuffer_data(struct intel_batchbuffer *batch, { assert((bytes & 3) == 0); intel_batchbuffer_require_space(batch, bytes, flags); - memcpy(batch->ptr, data, bytes); - batch->ptr += bytes; + memcpy(batch->base.ptr, data, bytes); + batch->base.ptr += bytes; } diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h index 9e4b8043bf..dcb2121ddf 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -3,6 +3,7 @@ #include "mtypes.h" #include "ws_dri_bufmgr.h" +#include "i915simple/i915_batch.h" struct intel_context; @@ -17,7 +18,8 @@ struct intel_context; struct intel_batchbuffer { - struct bufmgr *bm; + struct i915_batchbuffer base; + struct intel_context *intel; struct _DriBufferObject *buffer; @@ -26,15 +28,11 @@ struct intel_batchbuffer struct _DriBufferList *list; GLuint list_count; - GLubyte *map; - GLubyte *ptr; uint32_t *reloc; GLuint reloc_size; GLuint nr_relocs; - GLuint size; - GLuint dirty_state; GLuint id; @@ -83,7 +81,7 @@ intel_offset_relocation(struct intel_batchbuffer *batch, static INLINE GLuint intel_batchbuffer_space(struct intel_batchbuffer *batch) { - return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); + return (batch->base.size - BATCH_RESERVED) - (batch->base.ptr - batch->base.map); } @@ -92,8 +90,8 @@ intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) { assert(batch->map); assert(intel_batchbuffer_space(batch) >= 4); - *(GLuint *) (batch->ptr) = dword; - batch->ptr += 4; + *(GLuint *) (batch->base.ptr) = dword; + batch->base.ptr += 4; } static INLINE void @@ -114,20 +112,25 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch, /* Here are the crusty old macros, to be removed: */ +#undef BATCH_LOCALS #define BATCH_LOCALS +#undef BEGIN_BATCH #define BEGIN_BATCH(n, flags) do { \ assert(!intel->prim.flush); \ intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ } while (0) +#undef OUT_BATCH #define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) +#undef OUT_RELOC #define OUT_RELOC(buf,flags,mask,delta) do { \ assert((delta) >= 0); \ intel_offset_relocation(intel->batch, delta, buf, flags, mask); \ } while (0) +#undef ADVANCE_BATCH #define ADVANCE_BATCH() do { } while(0) diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index a35825d36a..013291364a 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -63,28 +63,11 @@ intel_i915_winsys( struct i915_winsys *sws ) /* Simple batchbuffer interface: */ -static unsigned *intel_i915_batch_start( struct i915_winsys *sws, - unsigned dwords, - unsigned relocs ) +static struct i915_batchbuffer* +intel_i915_batch_get( struct i915_winsys *sws ) { struct intel_context *intel = intel_i915_winsys(sws)->intel; - - /* XXX: check relocs. - */ - if (intel_batchbuffer_space( intel->batch ) >= dwords * 4) { - /* XXX: Hmm, the driver can't really do much with this pointer: - */ - return (unsigned *)intel->batch->ptr; - } - else - return NULL; -} - -static void intel_i915_batch_dword( struct i915_winsys *sws, - unsigned dword ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - intel_batchbuffer_emit_dword( intel->batch, dword ); + return &intel->batch->base; } static void intel_i915_batch_reloc( struct i915_winsys *sws, @@ -106,22 +89,13 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws, mask |= DRM_BO_FLAG_READ; } -#if 0 /* JB old */ - intel_batchbuffer_emit_reloc( intel->batch, - dri_bo( buf ), - flags, mask, - delta ); -#else /* new */ intel_offset_relocation( intel->batch, delta, dri_bo( buf ), flags, mask ); -#endif } - - static void intel_i915_batch_flush( struct i915_winsys *sws, struct pipe_fence_handle **fence ) { @@ -166,8 +140,7 @@ intel_create_i915simple( struct intel_context *intel, /* Fill in this struct with callbacks that i915simple will need to * communicate with the window system, buffer manager, etc. */ - iws->winsys.batch_start = intel_i915_batch_start; - iws->winsys.batch_dword = intel_i915_batch_dword; + iws->winsys.batch_get = intel_i915_batch_get; iws->winsys.batch_reloc = intel_i915_batch_reloc; iws->winsys.batch_flush = intel_i915_batch_flush; iws->pws = winsys; -- cgit v1.2.3 From afd635a95056abc0909ebd1503131660d6e78cf6 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 3 Jun 2008 12:35:01 +0200 Subject: i915: Fix compile on linux-dri-debug --- src/gallium/winsys/dri/intel/intel_batchbuffer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h index dcb2121ddf..abb7a624f5 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -88,7 +88,7 @@ intel_batchbuffer_space(struct intel_batchbuffer *batch) static INLINE void intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) { - assert(batch->map); + assert(batch->base.map); assert(intel_batchbuffer_space(batch) >= 4); *(GLuint *) (batch->base.ptr) = dword; batch->base.ptr += 4; @@ -100,7 +100,7 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch, { struct _DriFenceObject *fence; - assert(sz < batch->size - 8); + assert(sz < batch->base.size - 8); if (intel_batchbuffer_space(batch) < sz || (batch->flags != 0 && flags != 0 && batch->flags != flags)) { fence = intel_batchbuffer_flush(batch); -- cgit v1.2.3 From 4ebfc3c8ffccadaed98c4e032b7691eaf299b0bc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 15:23:03 -0600 Subject: egl: prototype some multi-API code --- src/gallium/winsys/egl_xlib/egl_xlib.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 99389970f5..ce3a0ae0da 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -313,19 +313,21 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, return EGL_NO_CONTEXT; } - if (ctx->Base.ClientAPI != EGL_OPENGL_API) { - _eglError(EGL_BAD_MATCH, "eglCreateContext(only OpenGL API supported)"); + /* API-dependent context creation */ + switch (ctx->Base.ClientAPI) { + case EGL_OPENGL_API: + /* create a softpipe context */ + ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL); + /* Now do xlib / state tracker inits here */ + _eglConfigToContextModesRec(conf, &visual); + ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx); + break; + default: + _eglError(EGL_BAD_MATCH, "eglCreateContext(unsupported API)"); free(ctx); return EGL_NO_CONTEXT; } - /* create a softpipe context */ - ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL); - - /* Now do xlib / state tracker inits here */ - _eglConfigToContextModesRec(conf, &visual); - ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx); - _eglSaveContext(&ctx->Base); return _eglGetContextHandle(&ctx->Base); @@ -341,7 +343,14 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx) context->Base.DeletePending = EGL_TRUE; } else { - st_destroy_context(context->Context); + /* API-dependent clean-up */ + switch (context->Base.ClientAPI) { + case EGL_OPENGL_API: + st_destroy_context(context->Context); + break; + default: + assert(0); + } free(context); } return EGL_TRUE; -- cgit v1.2.3 From af31e5d42982088821bdf8deaeb33d45f01fd004 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 4 Jun 2008 11:35:41 -0600 Subject: egl: do proper setup/init of EGL configs --- src/gallium/winsys/egl_xlib/egl_xlib.c | 73 ++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 21 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index ce3a0ae0da..07b3c0eb00 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -115,34 +115,68 @@ lookup_context(EGLContext surf) } +static unsigned int +bitcount(unsigned int n) +{ + unsigned int bits; + for (bits = 0; n > 0; n = n >> 1) { + bits += (n & 1); + } + return bits; +} + + /** - * XXX temporary - * Need to query X server's GLX visuals. + * Create the EGLConfigs. (one per X visual) */ static void -init_configs(_EGLDriver *drv, EGLDisplay dpy) +create_configs(_EGLDriver *drv, EGLDisplay dpy) { _EGLDisplay *disp = _eglLookupDisplay(dpy); - int i; + XVisualInfo *visInfo, visTemplate; + int num_visuals, i; + + /* get list of all X visuals, create an EGL config for each */ + visTemplate.screen = DefaultScreen(disp->Xdpy); + visInfo = XGetVisualInfo(disp->Xdpy, VisualScreenMask, + &visTemplate, &num_visuals); + if (!visInfo) { + printf("egl_xlib.c: couldn't get any X visuals\n"); + abort(); + } - for (i = 0; i < 2; i++) { - _EGLConfig config; + for (i = 0; i < num_visuals; i++) { + _EGLConfig *config = calloc(1, sizeof(_EGLConfig)); int id = i + 1; - _eglInitConfig(&config, id); - SET_CONFIG_ATTRIB(&config, EGL_RED_SIZE, 8); - SET_CONFIG_ATTRIB(&config, EGL_GREEN_SIZE, 8); - SET_CONFIG_ATTRIB(&config, EGL_BLUE_SIZE, 8); - SET_CONFIG_ATTRIB(&config, EGL_ALPHA_SIZE, 8); - if (i > 0) { - SET_CONFIG_ATTRIB(&config, EGL_DEPTH_SIZE, 24); - SET_CONFIG_ATTRIB(&config, EGL_STENCIL_SIZE, 8); - } - _eglAddConfig(disp, &config); + int rbits = bitcount(visInfo[i].red_mask); + int gbits = bitcount(visInfo[i].green_mask); + int bbits = bitcount(visInfo[i].blue_mask); + int abits = bbits == 8 ? 8 : 0; + int zbits = 24; + int sbits = 8; + int visid = visInfo[i].visualid; +#if defined(__cplusplus) || defined(c_plusplus) + int vistype = visInfo[i].c_class; +#else + int vistype = visInfo[i].class; +#endif + + _eglInitConfig(config, id); + SET_CONFIG_ATTRIB(config, EGL_BUFFER_SIZE, rbits + gbits + bbits + abits); + SET_CONFIG_ATTRIB(config, EGL_RED_SIZE, rbits); + SET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE, gbits); + SET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE, bbits); + SET_CONFIG_ATTRIB(config, EGL_ALPHA_SIZE, abits); + SET_CONFIG_ATTRIB(config, EGL_DEPTH_SIZE, zbits); + SET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE, sbits); + SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_ID, visid); + SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, vistype); + + _eglAddConfig(disp, config); } } - /** * Called via eglInitialize(), drv->API.Initialize(). */ @@ -150,10 +184,7 @@ static EGLBoolean xlib_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *minor, EGLint *major) { - /* visual configs */ - - init_configs(drv, dpy); - + create_configs(drv, dpy); drv->Initialized = EGL_TRUE; -- cgit v1.2.3 From adbdabb85ae322d5c80cadcee931e36d5c688d98 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 6 Jun 2008 14:49:02 +0200 Subject: i915: Moved pipe_buffer and i915_winsys functions to a common folder --- src/gallium/winsys/common/Makefile | 20 + src/gallium/winsys/common/Makefile.template | 64 + src/gallium/winsys/common/intel_drm/Makefile | 23 + src/gallium/winsys/common/intel_drm/glthread.h | 359 ++++++ .../winsys/common/intel_drm/intel_be_batchbuffer.c | 429 +++++++ .../winsys/common/intel_drm/intel_be_batchbuffer.h | 69 ++ .../winsys/common/intel_drm/intel_be_context.c | 107 ++ .../winsys/common/intel_drm/intel_be_context.h | 40 + .../winsys/common/intel_drm/intel_be_device.c | 257 ++++ .../winsys/common/intel_drm/intel_be_device.h | 58 + .../winsys/common/intel_drm/ws_dri_bufmgr.c | 949 ++++++++++++++ .../winsys/common/intel_drm/ws_dri_bufmgr.h | 138 +++ .../winsys/common/intel_drm/ws_dri_bufpool.h | 102 ++ .../winsys/common/intel_drm/ws_dri_drmpool.c | 268 ++++ .../winsys/common/intel_drm/ws_dri_fencemgr.c | 377 ++++++ .../winsys/common/intel_drm/ws_dri_fencemgr.h | 115 ++ .../winsys/common/intel_drm/ws_dri_mallocpool.c | 161 +++ .../winsys/common/intel_drm/ws_dri_slabpool.c | 968 +++++++++++++++ src/gallium/winsys/dri/Makefile.template | 1 + src/gallium/winsys/dri/intel/Makefile | 17 +- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 462 ------- src/gallium/winsys/dri/intel/intel_batchbuffer.h | 131 +- src/gallium/winsys/dri/intel/intel_context.c | 71 +- src/gallium/winsys/dri/intel/intel_context.h | 17 +- src/gallium/winsys/dri/intel/intel_lock.c | 14 +- src/gallium/winsys/dri/intel/intel_reg.h | 10 +- src/gallium/winsys/dri/intel/intel_screen.c | 106 +- src/gallium/winsys/dri/intel/intel_screen.h | 25 +- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 33 +- src/gallium/winsys/dri/intel/intel_swapbuffers.h | 10 +- src/gallium/winsys/dri/intel/intel_winsys.h | 73 -- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 156 --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 318 ----- .../winsys/dri/intel/intel_winsys_softpipe.c | 20 +- .../winsys/dri/intel/intel_winsys_softpipe.h | 39 + src/gallium/winsys/dri/intel/server/i830_common.h | 8 +- src/gallium/winsys/dri/intel/server/i830_dri.h | 2 +- src/gallium/winsys/dri/intel/server/intel.h | 331 ----- src/gallium/winsys/dri/intel/server/intel_dri.c | 1306 -------------------- src/gallium/winsys/dri/intel/ws_dri_bufmgr.c | 953 -------------- src/gallium/winsys/dri/intel/ws_dri_bufmgr.h | 138 --- src/gallium/winsys/dri/intel/ws_dri_bufpool.h | 102 -- src/gallium/winsys/dri/intel/ws_dri_drmpool.c | 268 ---- src/gallium/winsys/dri/intel/ws_dri_fencemgr.c | 377 ------ src/gallium/winsys/dri/intel/ws_dri_fencemgr.h | 115 -- src/gallium/winsys/dri/intel/ws_dri_mallocpool.c | 162 --- src/gallium/winsys/dri/intel/ws_dri_slabpool.c | 968 --------------- 47 files changed, 4729 insertions(+), 6008 deletions(-) create mode 100644 src/gallium/winsys/common/Makefile create mode 100644 src/gallium/winsys/common/Makefile.template create mode 100644 src/gallium/winsys/common/intel_drm/Makefile create mode 100644 src/gallium/winsys/common/intel_drm/glthread.h create mode 100644 src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c create mode 100644 src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h create mode 100644 src/gallium/winsys/common/intel_drm/intel_be_context.c create mode 100644 src/gallium/winsys/common/intel_drm/intel_be_context.h create mode 100644 src/gallium/winsys/common/intel_drm/intel_be_device.c create mode 100644 src/gallium/winsys/common/intel_drm/intel_be_device.h create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c delete mode 100644 src/gallium/winsys/dri/intel/intel_batchbuffer.c delete mode 100644 src/gallium/winsys/dri/intel/intel_winsys.h delete mode 100644 src/gallium/winsys/dri/intel/intel_winsys_i915.c delete mode 100644 src/gallium/winsys/dri/intel/intel_winsys_pipe.c create mode 100644 src/gallium/winsys/dri/intel/intel_winsys_softpipe.h delete mode 100644 src/gallium/winsys/dri/intel/server/intel.h delete mode 100644 src/gallium/winsys/dri/intel/server/intel_dri.c delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_bufmgr.c delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_bufmgr.h delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_bufpool.h delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_drmpool.c delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_fencemgr.c delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_fencemgr.h delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_mallocpool.c delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_slabpool.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/common/Makefile b/src/gallium/winsys/common/Makefile new file mode 100644 index 0000000000..4c0f3545a5 --- /dev/null +++ b/src/gallium/winsys/common/Makefile @@ -0,0 +1,20 @@ +TOP = ../../../.. +include $(TOP)/configs/current + + +SUBDIRS = $(GALLIUM_WINSYS_COMMON_DIRS) + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` diff --git a/src/gallium/winsys/common/Makefile.template b/src/gallium/winsys/common/Makefile.template new file mode 100644 index 0000000000..67af778157 --- /dev/null +++ b/src/gallium/winsys/common/Makefile.template @@ -0,0 +1,64 @@ +# -*-makefile-*- + + +# We still have a dependency on the "dri" buffer manager. Most likely +# the interface can be reused in non-dri environments, and also as a +# frontend to simpler memory managers. +# +COMMON_SOURCES = + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(CPP_SOURCES:.cpp=.o) \ + $(ASM_SOURCES:.S=.o) + + +### Include directories +INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/include \ + $(DRIVER_INCLUDES) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) + + +$(LIBNAME): $(OBJECTS) Makefile $(TOP)/src/gallium/winsys/common/Makefile.template + $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) + + +depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean:: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +include depend diff --git a/src/gallium/winsys/common/intel_drm/Makefile b/src/gallium/winsys/common/intel_drm/Makefile new file mode 100644 index 0000000000..913dbeff20 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/Makefile @@ -0,0 +1,23 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = inteldrm + +C_SOURCES = \ + intel_be_batchbuffer.c \ + intel_be_context.c \ + intel_be_device.c \ + ws_dri_bufmgr.c \ + ws_dri_drmpool.c \ + ws_dri_fencemgr.c \ + ws_dri_mallocpool.c \ + ws_dri_slabpool.c + + +include ../Makefile.template + +DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \ + && pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") +symlinks: + diff --git a/src/gallium/winsys/common/intel_drm/glthread.h b/src/gallium/winsys/common/intel_drm/glthread.h new file mode 100644 index 0000000000..b8e9d5f59b --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/glthread.h @@ -0,0 +1,359 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.2 + * + * Copyright (C) 1999-2006 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + + +/* + * Thread support for gl dispatch. + * + * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) + * and Christoph Poliwoda (poliwoda@volumegraphics.com) + * Revised by Keith Whitwell + * Adapted for new gl dispatcher by Brian Paul + * + * + * + * DOCUMENTATION + * + * This thread module exports the following types: + * _glthread_TSD Thread-specific data area + * _glthread_Thread Thread datatype + * _glthread_Mutex Mutual exclusion lock + * + * Macros: + * _glthread_DECLARE_STATIC_MUTEX(name) Declare a non-local mutex + * _glthread_INIT_MUTEX(name) Initialize a mutex + * _glthread_LOCK_MUTEX(name) Lock a mutex + * _glthread_UNLOCK_MUTEX(name) Unlock a mutex + * + * Functions: + * _glthread_GetID(v) Get integer thread ID + * _glthread_InitTSD() Initialize thread-specific data + * _glthread_GetTSD() Get thread-specific data + * _glthread_SetTSD() Set thread-specific data + * + */ + +/* + * If this file is accidentally included by a non-threaded build, + * it should not cause the build to fail, or otherwise cause problems. + * In general, it should only be included when needed however. + */ + +#ifndef GLTHREAD_H +#define GLTHREAD_H + + +#if defined(USE_MGL_NAMESPACE) +#define _glapi_Dispatch _mglapi_Dispatch +#endif + + + +#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\ + defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \ + && !defined(THREADS) +# define THREADS +#endif + +#ifdef VMS +#include +#endif + +/* + * POSIX threads. This should be your choice in the Unix world + * whenever possible. When building with POSIX threads, be sure + * to enable any compiler flags which will cause the MT-safe + * libc (if one exists) to be used when linking, as well as any + * header macros for MT-safe errno, etc. For Solaris, this is the -mt + * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable + * proper compiling for MT-safe libc etc. + */ +#if defined(PTHREADS) +#include /* POSIX threads headers */ + +typedef struct { + pthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef pthread_t _glthread_Thread; + +typedef pthread_mutex_t _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = PTHREAD_MUTEX_INITIALIZER + +#define _glthread_INIT_MUTEX(name) \ + pthread_mutex_init(&(name), NULL) + +#define _glthread_DESTROY_MUTEX(name) \ + pthread_mutex_destroy(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) pthread_mutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) pthread_mutex_unlock(&(name)) + +typedef pthread_cond_t _glthread_Cond; + +#define _glthread_DECLARE_STATIC_COND(name) \ + static _glthread_Cond name = PTHREAD_COND_INITIALIZER + +#define _glthread_INIT_COND(cond) \ + pthread_cond_init(&(cond), NULL) + +#define _glthread_DESTROY_COND(name) \ + pthread_cond_destroy(&(name)) + +#define _glthread_COND_WAIT(cond, mutex) \ + pthread_cond_wait(&(cond), &(mutex)) + +#define _glthread_COND_SIGNAL(cond) \ + pthread_cond_signal(&(cond)) + +#define _glthread_COND_BROADCAST(cond) \ + pthread_cond_broadcast(&(cond)) + + +#else /* PTHREADS */ + +typedef unsigned int _glthread_Cond; +#define _glthread_DECLARE_STATIC_COND(name) \ +// #warning Condition variables not implemented. + +#define _glthread_INIT_COND(cond) \ + abort(); + +#define _glthread_DESTROY_COND(name) \ + abort(); + +#define _glthread_COND_WAIT(cond, mutex) \ + abort(); + +#define _glthread_COND_SIGNAL(cond) \ + abort(); + +#define _glthread_COND_BROADCAST(cond) \ + abort(); + +#endif + + +/* + * Solaris threads. Use only up to Solaris 2.4. + * Solaris 2.5 and higher provide POSIX threads. + * Be sure to compile with -mt on the Solaris compilers, or + * use -D_REENTRANT if using gcc. + */ +#ifdef SOLARIS_THREADS +#include + +typedef struct { + thread_key_t key; + mutex_t keylock; + int initMagic; +} _glthread_TSD; + +typedef thread_t _glthread_Thread; + +typedef mutex_t _glthread_Mutex; + +/* XXX need to really implement mutex-related macros */ +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 +#define _glthread_INIT_MUTEX(name) (void) name +#define _glthread_DESTROY_MUTEX(name) (void) name +#define _glthread_LOCK_MUTEX(name) (void) name +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* SOLARIS_THREADS */ + + + + +/* + * Windows threads. Should work with Windows NT and 95. + * IMPORTANT: Link with multithreaded runtime library when THREADS are + * used! + */ +#ifdef WIN32_THREADS +#include + +typedef struct { + DWORD key; + int initMagic; +} _glthread_TSD; + +typedef HANDLE _glthread_Thread; + +typedef CRITICAL_SECTION _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) /*static*/ _glthread_Mutex name = {0,0,0,0,0,0} +#define _glthread_INIT_MUTEX(name) InitializeCriticalSection(&name) +#define _glthread_DESTROY_MUTEX(name) DeleteCriticalSection(&name) +#define _glthread_LOCK_MUTEX(name) EnterCriticalSection(&name) +#define _glthread_UNLOCK_MUTEX(name) LeaveCriticalSection(&name) + +#endif /* WIN32_THREADS */ + + + + +/* + * XFree86 has its own thread wrapper, Xthreads.h + * We wrap it again for GL. + */ +#ifdef USE_XTHREADS +#include + +typedef struct { + xthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef xthread_t _glthread_Thread; + +typedef xmutex_rec _glthread_Mutex; + +#ifdef XMUTEX_INITIALIZER +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = XMUTEX_INITIALIZER +#else +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name +#endif + +#define _glthread_INIT_MUTEX(name) \ + xmutex_init(&(name)) + +#define _glthread_DESTROY_MUTEX(name) \ + xmutex_clear(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) xmutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) xmutex_unlock(&(name)) + +#endif /* USE_XTHREADS */ + + + +/* + * BeOS threads. R5.x required. + */ +#ifdef BEOS_THREADS + +#include +#include + +typedef struct { + int32 key; + int initMagic; +} _glthread_TSD; + +typedef thread_id _glthread_Thread; + +/* Use Benaphore, aka speeder semaphore */ +typedef struct { + int32 lock; + sem_id sem; +} benaphore; +typedef benaphore _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = { 0, 0 } +#define _glthread_INIT_MUTEX(name) name.sem = create_sem(0, #name"_benaphore"), name.lock = 0 +#define _glthread_DESTROY_MUTEX(name) delete_sem(name.sem), name.lock = 0 +#define _glthread_LOCK_MUTEX(name) if (name.sem == 0) _glthread_INIT_MUTEX(name); \ + if (atomic_add(&(name.lock), 1) >= 1) acquire_sem(name.sem) +#define _glthread_UNLOCK_MUTEX(name) if (atomic_add(&(name.lock), -1) > 1) release_sem(name.sem) + +#endif /* BEOS_THREADS */ + + + +#ifndef THREADS + +/* + * THREADS not defined + */ + +typedef GLuint _glthread_TSD; + +typedef GLuint _glthread_Thread; + +typedef GLuint _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 + +#define _glthread_INIT_MUTEX(name) (void) name + +#define _glthread_DESTROY_MUTEX(name) (void) name + +#define _glthread_LOCK_MUTEX(name) (void) name + +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* THREADS */ + + + +/* + * Platform independent thread specific data API. + */ + +extern unsigned long +_glthread_GetID(void); + + +extern void +_glthread_InitTSD(_glthread_TSD *); + + +extern void * +_glthread_GetTSD(_glthread_TSD *); + + +extern void +_glthread_SetTSD(_glthread_TSD *, void *); + +#if defined(GLX_USE_TLS) + +extern __thread struct _glapi_table * _glapi_tls_Dispatch + __attribute__((tls_model("initial-exec"))); + +#define GET_DISPATCH() _glapi_tls_Dispatch + +#elif !defined(GL_CALL) +# if defined(THREADS) +# define GET_DISPATCH() \ + ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ + ? _glapi_Dispatch : _glapi_get_dispatch()) +# else +# define GET_DISPATCH() _glapi_Dispatch +# endif /* defined(THREADS) */ +#endif /* ndef GL_CALL */ + + +#endif /* THREADS_H */ diff --git a/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c b/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c new file mode 100644 index 0000000000..bc13a5761e --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c @@ -0,0 +1,429 @@ + +#include "intel_be_batchbuffer.h" +#include "intel_be_context.h" +#include "intel_be_device.h" +#include + +#include "xf86drm.h" + +static void +intel_realloc_relocs(struct intel_be_batchbuffer *batch, int num_relocs) +{ + unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; + + size *= sizeof(uint32_t); + batch->reloc = realloc(batch->reloc, size); + batch->reloc_size = num_relocs; +} + + +void +intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch) +{ + /* + * Get a new, free batchbuffer. + */ + drmBO *bo; + struct drm_bo_info_req *req; + + driBOUnrefUserList(batch->list); + driBOResetList(batch->list); + + /* base.size is the size available to the i915simple driver */ + batch->base.size = batch->device->max_batch_size - BATCH_RESERVED; + batch->base.actual_size = batch->device->max_batch_size; + driBOData(batch->buffer, batch->base.actual_size, NULL, NULL, 0); + + /* + * Add the batchbuffer to the validate list. + */ + + driBOAddListItem(batch->list, batch->buffer, + DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, + &batch->dest_location, &batch->node); + + req = &batch->node->bo_arg.d.req.bo_req; + + /* + * Set up information needed for us to make relocations + * relative to the underlying drm buffer objects. + */ + + driReadLockKernelBO(); + bo = driBOKernel(batch->buffer); + req->presumed_offset = (uint64_t) bo->offset; + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + batch->drmBOVirtual = (uint8_t *) bo->virtual; + driReadUnlockKernelBO(); + + /* + * Adjust the relocation buffer size. + */ + + if (batch->reloc_size > INTEL_MAX_RELOCS || + batch->reloc == NULL) + intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); + + assert(batch->reloc != NULL); + batch->reloc[0] = 0; /* No relocs yet. */ + batch->reloc[1] = 1; /* Reloc type 1 */ + batch->reloc[2] = 0; /* Only a single relocation list. */ + batch->reloc[3] = 0; /* Only a single relocation list. */ + + batch->base.map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->poolOffset = driBOPoolOffset(batch->buffer); + batch->base.ptr = batch->base.map; + batch->dirty_state = ~0; + batch->nr_relocs = 0; + batch->flags = 0; + batch->id = 0;//batch->intel->intelScreen->batch_id++; +} + +/*====================================================================== + * Public functions + */ +struct intel_be_batchbuffer * +intel_be_batchbuffer_alloc(struct intel_be_context *intel) +{ + struct intel_be_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + batch->device = intel->device; + + driGenBuffers(intel->device->batchPool, "batchbuffer", 1, + &batch->buffer, 4096, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); + batch->last_fence = NULL; + batch->list = driBOCreateList(20); + batch->reloc = NULL; + intel_be_batchbuffer_reset(batch); + return batch; +} + +void +intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch) +{ + if (batch->last_fence) { + driFenceFinish(batch->last_fence, + DRM_FENCE_TYPE_EXE, FALSE); + driFenceUnReference(&batch->last_fence); + } + if (batch->base.map) { + driBOUnmap(batch->buffer); + batch->base.map = NULL; + } + driBOUnReference(batch->buffer); + driBOFreeList(batch->list); + if (batch->reloc) + free(batch->reloc); + batch->buffer = NULL; + free(batch); +} + +void +intel_be_offset_relocation(struct intel_be_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask) +{ + int itemLoc; + struct _drmBONode *node; + uint32_t *reloc; + struct drm_bo_info_req *req; + + driBOAddListItem(batch->list, driBO, val_flags, val_mask, + &itemLoc, &node); + req = &node->bo_arg.d.req.bo_req; + + if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { + + /* + * Stop other threads from tampering with the underlying + * drmBO while we're reading its offset. + */ + + driReadLockKernelBO(); + req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; + driReadUnlockKernelBO(); + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + } + + pre_add += driBOPoolOffset(driBO); + + if (batch->nr_relocs == batch->reloc_size) + intel_realloc_relocs(batch, batch->reloc_size * 2); + + reloc = batch->reloc + + (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); + + reloc[0] = ((uint8_t *)batch->base.ptr - batch->drmBOVirtual); + i915_batchbuffer_dword(&batch->base, req->presumed_offset + pre_add); + reloc[1] = pre_add; + reloc[2] = itemLoc; + reloc[3] = batch->dest_location; + batch->nr_relocs++; +} + +static void +i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) +{ + buf->handle = rep->handle; + buf->flags = rep->flags; + buf->size = rep->size; + buf->offset = rep->offset; + buf->mapHandle = rep->arg_handle; + buf->proposedFlags = rep->proposed_flags; + buf->start = rep->buffer_start; + buf->fenceFlags = rep->fence_flags; + buf->replyFlags = rep->rep_flags; + buf->pageAlignment = rep->page_alignment; +} + +static int +i915_execbuf(struct intel_be_batchbuffer *batch, + unsigned int used, + boolean ignore_cliprects, + drmBOList *list, + struct drm_i915_execbuffer *ea) +{ +// struct intel_be_context *intel = batch->intel; + drmBONode *node; + drmMMListHead *l; + struct drm_i915_op_arg *arg, *first; + struct drm_bo_op_req *req; + struct drm_bo_info_rep *rep; + uint64_t *prevNext = NULL; + drmBO *buf; + int ret = 0; + uint32_t count = 0; + + first = NULL; + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + + arg = &node->bo_arg; + req = &arg->d.req; + + if (!first) + first = arg; + + if (prevNext) + *prevNext = (unsigned long)arg; + + prevNext = &arg->next; + req->bo_req.handle = node->buf->handle; + req->op = drm_bo_validate; + req->bo_req.flags = node->arg0; + req->bo_req.mask = node->arg1; + req->bo_req.hint |= 0; + count++; + } + + memset(ea, 0, sizeof(*ea)); + ea->num_buffers = count; + ea->batch.start = batch->poolOffset; + ea->batch.used = used; +#if 0 /* ZZZ JB: no cliprects used */ + ea->batch.cliprects = intel->pClipRects; + ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); +#else + ea->batch.cliprects = NULL; + ea->batch.num_cliprects = 0; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0; +#endif + ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; + ea->ops_list = (unsigned long) first; + first->reloc_ptr = (unsigned long) batch->reloc; + batch->reloc[0] = batch->nr_relocs; + + //return -EFAULT; + do { + ret = drmCommandWriteRead(batch->device->fd, DRM_I915_EXECBUFFER, ea, + sizeof(*ea)); + } while (ret == -EAGAIN); + + if (ret != 0) + return ret; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + arg = &node->bo_arg; + rep = &arg->d.rep.bo_info; + + if (!arg->handled) { + return -EFAULT; + } + if (arg->d.rep.ret) + return arg->d.rep.ret; + + buf = node->buf; + i915_drm_copy_reply(rep, buf); + } + return 0; +} + +/* TODO: Push this whole function into bufmgr. + */ +static struct _DriFenceObject * +do_flush_locked(struct intel_be_batchbuffer *batch, + unsigned int used, + boolean ignore_cliprects, boolean allow_unlock) +{ + struct intel_be_context *intel = batch->intel; + struct _DriFenceObject *fo; + drmFence fence; + drmBOList *boList; + struct drm_i915_execbuffer ea; + int ret = 0; + + driBOValidateUserList(batch->list); + boList = driGetdrmBOList(batch->list); + +#if 0 /* ZZZ JB Allways run */ + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { +#else + if (1) { +#endif + ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); + } else { + driPutdrmBOList(batch->list); + fo = NULL; + goto out; + } + driPutdrmBOList(batch->list); + if (ret) + abort(); + + if (ea.fence_arg.error != 0) { + + /* + * The hardware has been idled by the kernel. + * Don't fence the driBOs. + */ + + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); +#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ + _mesa_printf("fence error\n"); +#endif + batch->last_fence = NULL; + fo = NULL; + goto out; + } + + fence.handle = ea.fence_arg.handle; + fence.fence_class = ea.fence_arg.fence_class; + fence.type = ea.fence_arg.type; + fence.flags = ea.fence_arg.flags; + fence.signaled = ea.fence_arg.signaled; + + fo = driBOFenceUserList(batch->device->fenceMgr, batch->list, + "SuperFence", &fence); + + if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); + /* + * FIXME: Context last fence?? + */ + batch->last_fence = fo; + driFenceReference(fo); + } + out: +#if 0 /* ZZZ JB: fix this */ + intel->vtbl.lost_hardware(intel); +#else + (void)intel; +#endif + return fo; +} + + +struct _DriFenceObject * +intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch) +{ + struct intel_be_context *intel = batch->intel; + unsigned int used = batch->base.ptr - batch->base.map; + boolean was_locked = batch->intel->hardware_locked(intel); + struct _DriFenceObject *fence; + + if (used == 0) { + driFenceReference(batch->last_fence); + return batch->last_fence; + } + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ +#if 0 /* ZZZ JB: what should we do here? */ + if (used & 4) { + ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->base.ptr)[1] = 0; + ((int *) batch->base.ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->base.ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } +#else + if (used & 4) { + ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->base.ptr)[1] = 0; + ((int *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 8; + } +#endif + driBOUnmap(batch->buffer); + batch->base.ptr = NULL; + batch->base.map = NULL; + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!was_locked) + intel->hardware_lock(intel); + + fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + FALSE); + + if (!was_locked) + intel->hardware_unlock(intel); + + /* Reset the buffer: + */ + intel_be_batchbuffer_reset(batch); + return fence; +} + +void +intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch) +{ + struct _DriFenceObject *fence = intel_be_batchbuffer_flush(batch); + driFenceFinish(fence, driFenceType(fence), FALSE); + driFenceUnReference(&fence); +} + +#if 0 +void +intel_be_batchbuffer_data(struct intel_be_batchbuffer *batch, + const void *data, unsigned int bytes, unsigned int flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + memcpy(batch->base.ptr, data, bytes); + batch->base.ptr += bytes; +} +#endif diff --git a/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h b/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h new file mode 100644 index 0000000000..f150e3a674 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h @@ -0,0 +1,69 @@ + +#ifndef INTEL_BE_BATCHBUFFER_H +#define INTEL_BE_BATCHBUFFER_H + +#include "i915simple/i915_batch.h" + +#include "ws_dri_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_batchbuffer +{ + struct i915_batchbuffer base; + + struct intel_be_context *intel; + struct intel_be_device *device; + + struct _DriBufferObject *buffer; + struct _DriFenceObject *last_fence; + uint32_t flags; + + struct _DriBufferList *list; + size_t list_count; + + uint32_t *reloc; + size_t reloc_size; + size_t nr_relocs; + + uint32_t dirty_state; + uint32_t id; + + uint32_t poolOffset; + uint8_t *drmBOVirtual; + struct _drmBONode *node; /* Validation list node for this buffer */ + int dest_location; /* Validation list sequence for this buffer */ +}; + +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); + +struct _DriFenceObject * +intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch); + +void +intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch); + +void +intel_be_offset_relocation(struct intel_be_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask); + +#endif diff --git a/src/gallium/winsys/common/intel_drm/intel_be_context.c b/src/gallium/winsys/common/intel_drm/intel_be_context.c new file mode 100644 index 0000000000..1af39674f4 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/intel_be_context.c @@ -0,0 +1,107 @@ + +/* + * Authors: Jakob Bornecrantz + */ + +#include "ws_dri_fencemgr.h" +#include "intel_be_device.h" +#include "intel_be_context.h" +#include "intel_be_batchbuffer.h" + +static INLINE struct intel_be_context * +intel_be_context(struct i915_winsys *sws) +{ + return (struct intel_be_context *)sws; +} + +/* Simple batchbuffer interface: + */ + +static struct i915_batchbuffer* +intel_i915_batch_get(struct i915_winsys *sws) +{ + struct intel_be_context *intel = intel_be_context(sws); + return &intel->batch->base; +} + +static void intel_i915_batch_reloc(struct i915_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta) +{ + struct intel_be_context *intel = intel_be_context(sws); + + unsigned flags = DRM_BO_FLAG_MEM_TT; + unsigned mask = DRM_BO_MASK_MEM; + + if (access_flags & I915_BUFFER_ACCESS_WRITE) { + flags |= DRM_BO_FLAG_WRITE; + mask |= DRM_BO_FLAG_WRITE; + } + + if (access_flags & I915_BUFFER_ACCESS_READ) { + flags |= DRM_BO_FLAG_READ; + mask |= DRM_BO_FLAG_READ; + } + + intel_be_offset_relocation(intel->batch, + delta, + dri_bo(buf), + flags, + mask); +} + +static void intel_i915_batch_flush(struct i915_winsys *sws, + struct pipe_fence_handle **fence) +{ + struct intel_be_context *intel = intel_be_context(sws); + + union { + struct _DriFenceObject *dri; + struct pipe_fence_handle *pipe; + } fu; + + if (fence) + assert(!*fence); + + fu.dri = intel_be_batchbuffer_flush(intel->batch); + + if (!fu.dri) { + assert(0); + *fence = NULL; + return; + } + + if (fu.dri) { + if (fence) + *fence = fu.pipe; + else + driFenceUnReference(&fu.dri); + } + +} + +boolean +intel_be_init_context(struct intel_be_context *intel, struct intel_be_device *device) +{ + assert(intel); + assert(device); + + intel->device = device; + + /* TODO move framebuffer createion to the driver */ + + intel->base.batch_get = intel_i915_batch_get; + intel->base.batch_reloc = intel_i915_batch_reloc; + intel->base.batch_flush = intel_i915_batch_flush; + + intel->batch = intel_be_batchbuffer_alloc(intel); + + return true; +} + +void +intel_be_destroy_context(struct intel_be_context *intel) +{ + intel_be_batchbuffer_free(intel->batch); +} diff --git a/src/gallium/winsys/common/intel_drm/intel_be_context.h b/src/gallium/winsys/common/intel_drm/intel_be_context.h new file mode 100644 index 0000000000..d5cbc93594 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/intel_be_context.h @@ -0,0 +1,40 @@ +/* These need to be diffrent from the intel winsys */ +#ifndef INTEL_BE_CONTEXT_H +#define INTEL_BE_CONTEXT_H + +#include "i915simple/i915_winsys.h" + +struct intel_be_context +{ + /** Interface to i915simple driver */ + struct i915_winsys base; + + struct intel_be_device *device; + struct intel_be_batchbuffer *batch; + + /* + * Hardware lock functions. + * + * Needs to be filled in by the winsys. + */ + void (*hardware_lock)(struct intel_be_context *context); + void (*hardware_unlock)(struct intel_be_context *context); + boolean (*hardware_locked)(struct intel_be_context *context); +}; + +/** + * Intialize a allocated intel_be_context struct. + * + * Remember to set the hardware_* functions. + */ +boolean +intel_be_init_context(struct intel_be_context *intel, + struct intel_be_device *device); + +/** + * Destroy a intel_be_context. + * Does not free the struct that is up to the winsys. + */ +void +intel_be_destroy_context(struct intel_be_context *intel); +#endif diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c new file mode 100644 index 0000000000..0fc1894eaa --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.c @@ -0,0 +1,257 @@ + + +/* + * Authors: Keith Whitwell + * Jakob Bornecrantz + */ + +#include "intel_be_device.h" +#include "ws_dri_bufmgr.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +/* Turn a pipe winsys into an intel/pipe winsys: + */ +static INLINE struct intel_be_device * +intel_be_device( struct pipe_winsys *winsys ) +{ + return (struct intel_be_device *)winsys; +} + + +/* + * Buffer functions. + * + * Most callbacks map direcly onto dri_bufmgr operations: + */ + +static void *intel_be_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags ) +{ + unsigned drm_flags = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + drm_flags |= DRM_BO_FLAG_WRITE; + + if (flags & PIPE_BUFFER_USAGE_CPU_READ) + drm_flags |= DRM_BO_FLAG_READ; + + return driBOMap( dri_bo(buf), drm_flags, 0 ); +} + +static void intel_be_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnmap( dri_bo(buf) ); +} + +static void +intel_be_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnReference( dri_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 *iws = intel_be_device(winsys); + unsigned flags = 0; + struct _DriBufferPool *pool; + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { + flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; + pool = iws->mallocPool; + } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { + /* For vertex buffers */ + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + pool = iws->vertexPool; + } else { + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + pool = iws->regionPool; + } + + if (usage & PIPE_BUFFER_USAGE_GPU_READ) + flags |= DRM_BO_FLAG_READ; + + if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) + flags |= DRM_BO_FLAG_WRITE; + + /* drm complains if we don't set any read/write flags. + */ + if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) + flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + buffer->pool = pool; + driGenBuffers( buffer->pool, + "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); + + driBOData( buffer->driBO, size, NULL, buffer->pool, 0 ); + + return &buffer->base; +} + + +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 *iws = intel_be_device(winsys); + + driGenUserBuffer( iws->regionPool, + "pipe user buffer", &buffer->driBO, ptr, bytes ); + + buffer->base.refcount = 1; + + return &buffer->base; +} + + +/* + * Surface functions. + * + * Deprecated! + */ + +static struct pipe_surface * +intel_i915_surface_alloc(struct pipe_winsys *winsys) +{ + assert((size_t)"intel_i915_surface_alloc is deprecated" & 0); + return NULL; +} + +static int +intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + assert((size_t)"intel_i915_surface_alloc_storage is deprecated" & 0); + return -1; +} + +static void +intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + assert((size_t)"intel_i915_surface_release is deprecated" & 0); +} + +/* + * Fence functions + */ + +static void +intel_be_fence_reference( struct pipe_winsys *sws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence ) +{ + if (*ptr) + driFenceUnReference((struct _DriFenceObject **)ptr); + + if (fence) + *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); +} + +static int +intel_be_fence_signalled( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + return driFenceSignaled((struct _DriFenceObject *)fence, flag); +} + +static int +intel_be_fence_finish( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); +} + +/* + * Misc functions + */ + +boolean +intel_be_init_device(struct intel_be_device *dev, int fd) +{ + dev->fd = fd; + dev->max_batch_size = 16 * 4096; + dev->max_vertex_size = 128 * 4096; + + dev->base.buffer_create = intel_be_buffer_create; + dev->base.user_buffer_create = intel_be_user_buffer_create; + dev->base.buffer_map = intel_be_buffer_map; + dev->base.buffer_unmap = intel_be_buffer_unmap; + dev->base.buffer_destroy = intel_be_buffer_destroy; + dev->base.surface_alloc = intel_i915_surface_alloc; + dev->base.surface_alloc_storage = intel_i915_surface_alloc_storage; + dev->base.surface_release = intel_i915_surface_release; + dev->base.fence_reference = intel_be_fence_reference; + dev->base.fence_signalled = intel_be_fence_signalled; + dev->base.fence_finish = intel_be_fence_finish; + +#if 0 /* Set by the winsys */ + dev->base.flush_frontbuffer = intel_flush_frontbuffer; + dev->base.get_name = intel_get_name; +#endif + + dev->fMan = driInitFreeSlabManager(10, 10); + dev->fenceMgr = driFenceMgrTTMInit(dev->fd); + + dev->mallocPool = driMallocPoolInit(); + dev->staticPool = driDRMPoolInit(dev->fd); + dev->regionPool = driDRMPoolInit(dev->fd); + dev->vertexPool = driSlabPoolInit(dev->fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + dev->max_vertex_size, + 1, 120, dev->max_vertex_size * 4, 0, + dev->fMan); + + dev->batchPool = driSlabPoolInit(dev->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + dev->max_batch_size, + 1, 40, dev->max_batch_size * 16, 0, + dev->fMan); + + return true; +} + +void +intel_be_destroy_device(struct intel_be_device *dev) +{ + driPoolTakeDown(dev->mallocPool); + driPoolTakeDown(dev->staticPool); + driPoolTakeDown(dev->regionPool); + driPoolTakeDown(dev->vertexPool); + driPoolTakeDown(dev->batchPool); + + /** TODO takedown fenceMgr and fMan */ +} diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.h b/src/gallium/winsys/common/intel_drm/intel_be_device.h new file mode 100644 index 0000000000..ec5cace71c --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.h @@ -0,0 +1,58 @@ +#ifndef INTEL_DRM_DEVICE_H +#define INTEL_DRM_DEVICE_H + +#include "pipe/p_winsys.h" +#include "pipe/p_context.h" + +/* + * Device + */ + +struct intel_be_device +{ + struct pipe_winsys base; + + int fd; /**< Drm file discriptor */ + + size_t max_batch_size; + size_t max_vertex_size; + + struct _DriFenceMgr *fenceMgr; + + struct _DriBufferPool *batchPool; + struct _DriBufferPool *regionPool; + struct _DriBufferPool *mallocPool; + struct _DriBufferPool *vertexPool; + struct _DriBufferPool *staticPool; + struct _DriFreeSlabManager *fMan; +}; + +boolean +intel_be_init_device(struct intel_be_device *device, int fd); + +void +intel_be_destroy_device(struct intel_be_device *dev); + +/* + * Buffer + */ + +struct intel_be_buffer { + struct pipe_buffer base; + struct _DriBufferPool *pool; + struct _DriBufferObject *driBO; +}; + +static INLINE struct intel_be_buffer * +intel_be_buffer( struct pipe_buffer *buf ) +{ + return (struct intel_be_buffer *)buf; +} + +static INLINE struct _DriBufferObject * +dri_bo( struct pipe_buffer *buf ) +{ + return intel_be_buffer(buf)->driBO; +} + +#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c b/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c new file mode 100644 index 0000000000..b6d901f85e --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c @@ -0,0 +1,949 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + * Keith Whitwell + */ + +#include +#include +#include +#include "glthread.h" +#include "errno.h" +#include "ws_dri_bufmgr.h" +#include "string.h" +#include "pipe/p_debug.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" + + +/* + * This lock is here to protect drmBO structs changing underneath us during a + * validate list call, since validatelist cannot take individiual locks for + * each drmBO. Validatelist takes this lock in write mode. Any access to an + * individual drmBO should take this lock in read mode, since in that case, the + * driBufferObject mutex will protect the access. Locking order is + * driBufferObject mutex - > this rw lock. + */ + +_glthread_DECLARE_STATIC_MUTEX(bmMutex); +_glthread_DECLARE_STATIC_COND(bmCond); + +static int kernelReaders = 0; +static int num_buffers = 0; +static int num_user_buffers = 0; + +static drmBO *drmBOListBuf(void *iterator) +{ + drmBONode *node; + drmMMListHead *l = (drmMMListHead *) iterator; + node = DRMLISTENTRY(drmBONode, l, head); + return node->buf; +} + +static void *drmBOListIterator(drmBOList *list) +{ + void *ret = list->list.next; + + if (ret == &list->list) + return NULL; + return ret; +} + +static void *drmBOListNext(drmBOList *list, void *iterator) +{ + void *ret; + + drmMMListHead *l = (drmMMListHead *) iterator; + ret = l->next; + if (ret == &list->list) + return NULL; + return ret; +} + +static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, + uint64_t arg0, + uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } + else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADD(&node->head, &list->list); + list->numOnList++; + return node; +} + +static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, + uint64_t mask, int *newItem) +{ + drmBONode *node, *cur; + drmMMListHead *l; + + *newItem = 0; + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + } + if (!cur) { + cur = drmAddListItem(list, buf, flags, mask); + if (!cur) { + return -ENOMEM; + } + *newItem = 1; + cur->arg0 = flags; + cur->arg1 = mask; + } + else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + return 0; +} + +static void drmBOFreeList(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->list.next; + while(l != &list->list) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->list.next; + list->numCurrent--; + list->numOnList--; + } + + l = list->free.next; + while(l != &list->free) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->free.next; + list->numCurrent--; + } +} + +static int drmAdjustListNodes(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + int ret = 0; + + while(list->numCurrent < list->numTarget) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + ret = -ENOMEM; + break; + } + list->numCurrent++; + DRMLISTADD(&node->head, &list->free); + } + + while(list->numCurrent > list->numTarget) { + l = list->free.next; + if (l == &list->free) + break; + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + list->numCurrent--; + } + return ret; +} + +static int drmBOCreateList(int numTarget, drmBOList *list) +{ + DRMINITLISTHEAD(&list->list); + DRMINITLISTHEAD(&list->free); + list->numTarget = numTarget; + list->numCurrent = 0; + list->numOnList = 0; + return drmAdjustListNodes(list); +} + +static int drmBOResetList(drmBOList *list) +{ + drmMMListHead *l; + int ret; + + ret = drmAdjustListNodes(list); + if (ret) + return ret; + + l = list->list.next; + while (l != &list->list) { + DRMLISTDEL(l); + DRMLISTADD(l, &list->free); + list->numOnList--; + l = list->list.next; + } + return drmAdjustListNodes(list); +} + +void driWriteLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + while(kernelReaders != 0) + _glthread_COND_WAIT(bmCond, bmMutex); +} + +void driWriteUnlockKernelBO(void) +{ + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + kernelReaders++; + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadUnlockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + if (--kernelReaders == 0) + _glthread_COND_BROADCAST(bmCond); + _glthread_UNLOCK_MUTEX(bmMutex); +} + + + + +/* + * TODO: Introduce fence pools in the same way as + * buffer object pools. + */ + +typedef struct _DriBufferObject +{ + DriBufferPool *pool; + _glthread_Mutex mutex; + int refCount; + const char *name; + uint64_t flags; + unsigned hint; + unsigned alignment; + unsigned createdByReference; + void *private; + /* user-space buffer: */ + unsigned userBuffer; + void *userData; + unsigned userSize; +} DriBufferObject; + +typedef struct _DriBufferList { + drmBOList drmBuffers; /* List of kernel buffers needing validation */ + drmBOList driBuffers; /* List of user-space buffers needing validation */ +} DriBufferList; + + +void +bmError(int val, const char *file, const char *function, int line) +{ + printf("Fatal video memory manager error \"%s\".\n" + "Check kernel logs or set the LIBGL_DEBUG\n" + "environment variable to \"verbose\" for more info.\n" + "Detected in file %s, line %d, function %s.\n", + strerror(-val), file, line, function); +#ifndef NDEBUG + abort(); +#else + abort(); +#endif +} + +extern drmBO * +driBOKernel(struct _DriBufferObject *buf) +{ + drmBO *ret; + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + ret = buf->pool->kernel(buf->pool, buf->private); + if (!ret) + BM_CKFATAL(-EINVAL); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + + return ret; +} + +void +driBOWaitIdle(struct _DriBufferObject *buf, int lazy) +{ + + /* + * This function may block. Is it sane to keep the mutex held during + * that time?? + */ + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void * +driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) +{ + void *virtual; + int retval; + + if (buf->userBuffer) { + return buf->userData; + } + + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + retval = buf->pool->map(buf->pool, buf->private, flags, hint, + &buf->mutex, &virtual); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval == 0 ? virtual : NULL; +} + +void +driBOUnmap(struct _DriBufferObject *buf) +{ + if (buf->userBuffer) + return; + + assert(buf->private != NULL); + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +unsigned long +driBOOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->offset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +unsigned long +driBOPoolOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->poolOffset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +uint64_t +driBOFlags(struct _DriBufferObject *buf) +{ + uint64_t ret; + + assert(buf->private != NULL); + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->flags(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + return ret; +} + +struct _DriBufferObject * +driBOReference(struct _DriBufferObject *buf) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (++buf->refCount == 1) { + _glthread_UNLOCK_MUTEX(buf->mutex); + BM_CKFATAL(-EINVAL); + } + _glthread_UNLOCK_MUTEX(buf->mutex); + return buf; +} + +void +driBOUnReference(struct _DriBufferObject *buf) +{ + int tmp; + + if (!buf) + return; + + _glthread_LOCK_MUTEX(buf->mutex); + tmp = --buf->refCount; + if (!tmp) { + _glthread_UNLOCK_MUTEX(buf->mutex); + if (buf->private) { + if (buf->createdByReference) + buf->pool->unreference(buf->pool, buf->private); + else + buf->pool->destroy(buf->pool, buf->private); + } + if (buf->userBuffer) + num_user_buffers--; + else + num_buffers--; + free(buf); + } else + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + + +int +driBOData(struct _DriBufferObject *buf, + unsigned size, const void *data, + DriBufferPool *newPool, + uint64_t flags) +{ + void *virtual = NULL; + int newBuffer; + int retval = 0; + struct _DriBufferPool *pool; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + pool = buf->pool; + + if (pool == NULL && newPool != NULL) { + buf->pool = newPool; + pool = newPool; + } + if (newPool == NULL) + newPool = pool; + + if (!pool->create) { + assert((size_t)"driBOData called on invalid buffer\n" & 0); + BM_CKFATAL(-EINVAL); + } + + newBuffer = (!buf->private || pool != newPool || + pool->size(pool, buf->private) < size); + + if (!flags) + flags = buf->flags; + + if (newBuffer) { + + if (buf->createdByReference) { + assert((size_t)"driBOData requiring resizing called on shared buffer.\n" & 0); + BM_CKFATAL(-EINVAL); + } + + if (buf->private) + buf->pool->destroy(buf->pool, buf->private); + + pool = newPool; + buf->pool = newPool; + buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (!buf->private) + retval = -ENOMEM; + + if (retval == 0) + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); + } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { + /* + * Buffer is busy. need to create a new one. + */ + + void *newBuf; + + newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (newBuf) { + buf->pool->destroy(buf->pool, buf->private); + buf->private = newBuf; + } + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } else { + uint64_t flag_diff = flags ^ buf->flags; + + /* + * We might need to change buffer flags. + */ + + if (flag_diff){ + assert(pool->setStatus != NULL); + BM_CKFATAL(pool->unmap(pool, buf->private)); + BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, + buf->flags)); + if (!data) + goto out; + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } + } + + if (retval == 0) { + if (data) + memcpy(virtual, data, size); + + BM_CKFATAL(pool->unmap(pool, buf->private)); + } + + out: + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval; +} + +void +driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, const void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, + &virtual)); + memcpy((unsigned char *) virtual + offset, data, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); + memcpy(data, (unsigned char *) virtual + offset, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->private != NULL) { + assert((size_t)"Invalid buffer for setReferenced\n" & 0); + BM_CKFATAL(-EINVAL); + + } + if (buf->pool->reference == NULL) { + assert((size_t)"Invalid buffer pool for setReferenced\n" & 0); + BM_CKFATAL(-EINVAL); + } + buf->private = buf->pool->reference(buf->pool, handle); + if (!buf->private) { + assert((size_t)"Invalid buffer pool for setStatic\n" & 0); + BM_CKFATAL(-ENOMEM); + } + buf->createdByReference = TRUE; + buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +int +driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint) +{ + struct _DriBufferObject *buf; + int i; + + flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + ++num_buffers; + + assert(pool); + + for (i = 0; i < n; ++i) { + buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); + if (!buf) + return -ENOMEM; + + _glthread_INIT_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(buf->mutex); + buf->refCount = 1; + buf->flags = flags; + buf->hint = hint; + buf->name = name; + buf->alignment = alignment; + buf->pool = pool; + buf->createdByReference = 0; + _glthread_UNLOCK_MUTEX(buf->mutex); + buffers[i] = buf; + } + return 0; +} + +void +driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject **buffers, + void *ptr, unsigned bytes) +{ + const unsigned alignment = 1, flags = 0, hint = 0; + + --num_buffers; /* JB: is inced in GenBuffes */ + driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); + ++num_user_buffers; + + (*buffers)->userBuffer = 1; + (*buffers)->userData = ptr; + (*buffers)->userSize = bytes; +} + +void +driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) +{ + int i; + + for (i = 0; i < n; ++i) { + driBOUnReference(buffers[i]); + } +} + + +void +driInitBufMgr(int fd) +{ + ; +} + +/* + * Note that lists are per-context and don't need mutex protection. + */ + +struct _DriBufferList * +driBOCreateList(int target) +{ + struct _DriBufferList *list = calloc(sizeof(*list), 1); + + BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); + BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); + return list; +} + +int +driBOResetList(struct _DriBufferList * list) +{ + int ret; + ret = drmBOResetList(&list->drmBuffers); + if (ret) + return ret; + ret = drmBOResetList(&list->driBuffers); + return ret; +} + +void +driBOFreeList(struct _DriBufferList * list) +{ + drmBOFreeList(&list->drmBuffers); + drmBOFreeList(&list->driBuffers); + free(list); +} + + +/* + * Copied from libdrm, because it is needed by driAddValidateItem. + */ + +static drmBONode * +driAddListItem(drmBOList * list, drmBO * item, + uint64_t arg0, uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + memset(&node->bo_arg, 0, sizeof(node->bo_arg)); + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADDTAIL(&node->head, &list->list); + list->numOnList++; + return node; +} + +/* + * Slightly modified version compared to the libdrm version. + * This one returns the list index of the buffer put on the list. + */ + +static int +driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, + uint64_t mask, int *itemLoc, + struct _drmBONode **pnode) +{ + drmBONode *node, *cur; + drmMMListHead *l; + int count = 0; + + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + count++; + } + if (!cur) { + cur = driAddListItem(list, buf, flags, mask); + if (!cur) + return -ENOMEM; + + cur->arg0 = flags; + cur->arg1 = mask; + } else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + *itemLoc = count; + *pnode = cur; + return 0; +} + + +void +driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node) +{ + int newItem; + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(driAddValidateItem(&list->drmBuffers, + buf->pool->kernel(buf->pool, buf->private), + flags, mask, itemLoc, node)); + BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, + flags, mask, &newItem)); + if (newItem) + buf->refCount++; + + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +drmBOList *driGetdrmBOList(struct _DriBufferList *list) +{ + driWriteLockKernelBO(); + return &list->drmBuffers; +} + +void driPutdrmBOList(struct _DriBufferList *list) +{ + driWriteUnlockKernelBO(); +} + + +void +driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->fence) + BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + +void +driBOUnrefUserList(struct _DriBufferList *list) +{ + struct _DriBufferObject *buf; + void *curBuf; + + curBuf = drmBOListIterator(&list->driBuffers); + while (curBuf) { + buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + +struct _DriFenceObject * +driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, const char *name, + drmFence *kFence) +{ + struct _DriFenceObject *fence; + struct _DriBufferObject *buf; + void *curBuf; + + fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, + kFence, sizeof(*kFence)); + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space fencing callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + driBOFence(buf, fence); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } + + driBOResetList(list); + return fence; +} + +void +driBOValidateUserList(struct _DriBufferList * list) +{ + void *curBuf; + struct _DriBufferObject *buf; + + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space validation callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->validate) + BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); + _glthread_UNLOCK_MUTEX(buf->mutex); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + + +void +driPoolTakeDown(struct _DriBufferPool *pool) +{ + pool->takeDown(pool); + +} + +unsigned long +driBOSize(struct _DriBufferObject *buf) +{ + unsigned long size; + + _glthread_LOCK_MUTEX(buf->mutex); + size = buf->pool->size(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return size; + +} + +drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) +{ + return &list->drmBuffers; +} + +drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) +{ + return &list->driBuffers; +} + diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h b/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h new file mode 100644 index 0000000000..e6c0cff0a0 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + * Keith Whitwell + */ + +#ifndef _PSB_BUFMGR_H_ +#define _PSB_BUFMGR_H_ +#include +#include "i915_drm.h" +#include "ws_dri_fencemgr.h" + +typedef struct _drmBONode +{ + drmMMListHead head; + drmBO *buf; + struct drm_i915_op_arg bo_arg; + uint64_t arg0; + uint64_t arg1; +} drmBONode; + +typedef struct _drmBOList { + unsigned numTarget; + unsigned numCurrent; + unsigned numOnList; + drmMMListHead list; + drmMMListHead free; +} drmBOList; + + +struct _DriFenceObject; +struct _DriBufferObject; +struct _DriBufferPool; +struct _DriBufferList; + +/* + * Return a pointer to the libdrm buffer object this DriBufferObject + * uses. + */ + +extern drmBO *driBOKernel(struct _DriBufferObject *buf); +extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, + unsigned hint); +extern void driBOUnmap(struct _DriBufferObject *buf); +extern unsigned long driBOOffset(struct _DriBufferObject *buf); +extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); + +extern uint64_t driBOFlags(struct _DriBufferObject *buf); +extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); +extern void driBOUnReference(struct _DriBufferObject *buf); + +extern int driBOData(struct _DriBufferObject *r_buf, + unsigned size, const void *data, + struct _DriBufferPool *pool, uint64_t flags); + +extern void driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + const void *data); +extern void driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + void *data); +extern int driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint); +extern void driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject *buffers[], + void *ptr, unsigned bytes); +extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); +extern void driInitBufMgr(int fd); +extern struct _DriBufferList *driBOCreateList(int target); +extern int driBOResetList(struct _DriBufferList * list); +extern void driBOAddListItem(struct _DriBufferList * list, + struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node); + +extern void driBOValidateList(int fd, struct _DriBufferList * list); +extern void driBOFreeList(struct _DriBufferList * list); +extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, + const char *name, + drmFence *kFence); +extern void driBOUnrefUserList(struct _DriBufferList *list); +extern void driBOValidateUserList(struct _DriBufferList * list); +extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); +extern void driPutdrmBOList(struct _DriBufferList *list); + +extern void driBOFence(struct _DriBufferObject *buf, + struct _DriFenceObject *fence); + +extern void driPoolTakeDown(struct _DriBufferPool *pool); +extern void driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle); +unsigned long driBOSize(struct _DriBufferObject *buf); +extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); +extern void driPoolTakeDown(struct _DriBufferPool *pool); + +extern void driReadLockKernelBO(void); +extern void driReadUnlockKernelBO(void); +extern void driWriteLockKernelBO(void); +extern void driWriteUnlockKernelBO(void); + +/* + * For debugging purposes. + */ + +extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); +extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); +#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h b/src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h new file mode 100644 index 0000000000..bf60798924 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +#ifndef _PSB_BUFPOOL_H_ +#define _PSB_BUFPOOL_H_ + +#include +#include +struct _DriFenceObject; + +typedef struct _DriBufferPool +{ + int fd; + int (*map) (struct _DriBufferPool * pool, void *private, + unsigned flags, int hint, _glthread_Mutex *mutex, + void **virtual); + int (*unmap) (struct _DriBufferPool * pool, void *private); + int (*destroy) (struct _DriBufferPool * pool, void *private); + unsigned long (*offset) (struct _DriBufferPool * pool, void *private); + unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); + uint64_t (*flags) (struct _DriBufferPool * pool, void *private); + unsigned long (*size) (struct _DriBufferPool * pool, void *private); + void *(*create) (struct _DriBufferPool * pool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment); + void *(*reference) (struct _DriBufferPool * pool, unsigned handle); + int (*unreference) (struct _DriBufferPool * pool, void *private); + int (*fence) (struct _DriBufferPool * pool, void *private, + struct _DriFenceObject * fence); + drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); + int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy); + int (*setStatus) (struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags); + void (*takeDown) (struct _DriBufferPool * pool); + void *data; +} DriBufferPool; + +extern void bmError(int val, const char *file, const char *function, + int line); +#define BM_CKFATAL(val) \ + do{ \ + int tstVal = (val); \ + if (tstVal) \ + bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ + } while(0); + + +/* + * Builtin pools. + */ + +/* + * Kernel buffer objects. Size in multiples of page size. Page size aligned. + */ + +extern struct _DriBufferPool *driDRMPoolInit(int fd); +extern struct _DriBufferPool *driMallocPoolInit(void); + +struct _DriFreeSlabManager; +extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan); +extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); +extern struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); + + +#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c b/src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c new file mode 100644 index 0000000000..40929efa2f --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c @@ -0,0 +1,268 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" +#include "assert.h" + +/* + * Buffer pool implementation using DRM buffer objects as DRI buffer objects. + */ + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + unsigned pageSize = getpagesize(); + + if (!buf) + return NULL; + + if ((alignment > pageSize) && (alignment % pageSize)) { + free(buf); + return NULL; + } + + ret = drmBOCreate(pool->fd, size, alignment / pageSize, + NULL, + flags, hint, buf); + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static void * +pool_reference(struct _DriBufferPool *pool, unsigned handle) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + + if (!buf) + return NULL; + + ret = drmBOReference(pool->fd, handle, buf); + + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unreference(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOMap(pool->fd, buf, flags, hint, virtual); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOUnmap(pool->fd, buf); + driReadUnlockKernelBO(); + + return ret; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long offset; + + driReadLockKernelBO(); + assert(buf->flags & DRM_BO_FLAG_NO_MOVE); + offset = buf->offset; + driReadUnlockKernelBO(); + + return buf->offset; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + uint64_t flags; + + driReadLockKernelBO(); + flags = buf->flags; + driReadUnlockKernelBO(); + + return flags; +} + + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long size; + + driReadLockKernelBO(); + size = buf->size; + driReadUnlockKernelBO(); + + return buf->size; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + /* + * Noop. The kernel handles all fencing. + */ + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + return (drmBO *) private; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); + driReadUnlockKernelBO(); + + return ret; +} + + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + +/*static int +pool_setStatus(struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags) +{ + drmBO *buf = (drmBO *) private; + uint64_t new_flags = old_flags ^ flag_diff; + int ret; + + driReadLockKernelBO(); + ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, + 0, 0, 0); + driReadUnlockKernelBO(); + return ret; +}*/ + +struct _DriBufferPool * +driDRMPoolInit(int fd) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + + if (!pool) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + pool->reference = &pool_reference; + pool->unreference = &pool_unreference; + pool->data = NULL; + return pool; +} diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c b/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c new file mode 100644 index 0000000000..b56bc269da --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c @@ -0,0 +1,377 @@ +#include "ws_dri_fencemgr.h" +#include "glthread.h" +#include +#include +#include + +/* + * Note: Locking order is + * _DriFenceObject::mutex + * _DriFenceMgr::mutex + */ + +struct _DriFenceMgr { + /* + * Constant members. Need no mutex protection. + */ + struct _DriFenceMgrCreateInfo info; + void *private; + + /* + * These members are protected by this->mutex + */ + _glthread_Mutex mutex; + int refCount; + drmMMListHead *heads; + int num_fences; +}; + +struct _DriFenceObject { + + /* + * These members are constant and need no mutex protection. + */ + struct _DriFenceMgr *mgr; + uint32_t fence_class; + uint32_t fence_type; + + /* + * These members are protected by mgr->mutex. + */ + drmMMListHead head; + int refCount; + + /* + * These members are protected by this->mutex. + */ + _glthread_Mutex mutex; + uint32_t signaled_type; + void *private; +}; + +uint32_t +driFenceType(struct _DriFenceObject *fence) +{ + return fence->fence_type; +} + +struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) +{ + struct _DriFenceMgr *tmp; + uint32_t i; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->refCount = 1; + tmp->info = *info; + tmp->num_fences = 0; + tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); + if (!tmp->heads) + goto out_err; + + for (i=0; iinfo.num_classes; ++i) { + DRMINITLISTHEAD(&tmp->heads[i]); + } + _glthread_UNLOCK_MUTEX(tmp->mutex); + return tmp; + + out_err: + if (tmp) + free(tmp); + return NULL; +} + +static void +driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) +{ + struct _DriFenceMgr *mgr = *pMgr; + + *pMgr = NULL; + if (--mgr->refCount == 0) + free(mgr); + else + _glthread_UNLOCK_MUTEX(mgr->mutex); +} + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr) +{ + _glthread_LOCK_MUTEX((*pMgr)->mutex); + driFenceMgrUnrefUnlock(pMgr); +} + +static void +driFenceUnReferenceLocked(struct _DriFenceObject **pFence) +{ + struct _DriFenceObject *fence = *pFence; + struct _DriFenceMgr *mgr = fence->mgr; + + *pFence = NULL; + if (--fence->refCount == 0) { + DRMLISTDELINIT(&fence->head); + if (fence->private) + mgr->info.unreference(mgr, &fence->private); + --mgr->num_fences; + fence->mgr = NULL; + --mgr->refCount; + free(fence); + + } +} + + +static void +driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, + drmMMListHead *list, + uint32_t fence_class, + uint32_t fence_type) +{ + struct _DriFenceObject *entry; + drmMMListHead *prev; + + while(list != &mgr->heads[fence_class]) { + entry = DRMLISTENTRY(struct _DriFenceObject, list, head); + + /* + * Up refcount so that entry doesn't disappear from under us + * when we unlock-relock mgr to get the correct locking order. + */ + + ++entry->refCount; + _glthread_UNLOCK_MUTEX(mgr->mutex); + _glthread_LOCK_MUTEX(entry->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + + prev = list->prev; + + + + if (list->prev == list) { + + /* + * Somebody else removed the entry from the list. + */ + + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + return; + } + + entry->signaled_type |= (fence_type & entry->fence_type); + if (entry->signaled_type == entry->fence_type) { + DRMLISTDELINIT(list); + mgr->info.unreference(mgr, &entry->private); + } + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + list = prev; + } +} + + +int +driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint) +{ + struct _DriFenceMgr *mgr = fence->mgr; + int ret = 0; + + _glthread_LOCK_MUTEX(fence->mutex); + + if ((fence->signaled_type & fence_type) == fence_type) + goto out0; + + ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); + if (ret) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + fence_type); + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) +{ + uint32_t ret; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = fence->signaled_type; + _glthread_UNLOCK_MUTEX(fence->mutex); + + return ret; +} + +int +driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, + uint32_t *signaled) +{ + int ret = 0; + struct _DriFenceMgr *mgr; + + _glthread_LOCK_MUTEX(fence->mutex); + mgr = fence->mgr; + *signaled = fence->signaled_type; + if ((fence->signaled_type & flush_type) == flush_type) + goto out0; + + ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); + if (ret) { + *signaled = fence->signaled_type; + goto out0; + } + + if ((fence->signaled_type | *signaled) == fence->signaled_type) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + *signaled); + + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +struct _DriFenceObject * +driFenceReference(struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(fence->mgr->mutex); + ++fence->refCount; + _glthread_UNLOCK_MUTEX(fence->mgr->mutex); + return fence; +} + +void +driFenceUnReference(struct _DriFenceObject **pFence) +{ + struct _DriFenceMgr *mgr; + + if (*pFence == NULL) + return; + + mgr = (*pFence)->mgr; + _glthread_LOCK_MUTEX(mgr->mutex); + ++mgr->refCount; + driFenceUnReferenceLocked(pFence); + driFenceMgrUnrefUnlock(&mgr); +} + +struct _DriFenceObject +*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, + uint32_t fence_type, void *private, size_t private_size) +{ + struct _DriFenceObject *fence; + size_t fence_size = sizeof(*fence); + + if (private_size) + fence_size = ((fence_size + 15) & ~15); + + fence = calloc(1, fence_size + private_size); + + if (!fence) { + int ret = mgr->info.finish(mgr, private, fence_type, 0); + + if (ret) + usleep(10000000); + + return NULL; + } + + _glthread_INIT_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + fence->refCount = 1; + DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); + fence->mgr = mgr; + ++mgr->refCount; + ++mgr->num_fences; + _glthread_UNLOCK_MUTEX(mgr->mutex); + fence->fence_class = fence_class; + fence->fence_type = fence_type; + fence->signaled_type = 0; + fence->private = private; + if (private_size) { + fence->private = (void *)(((uint8_t *) fence) + fence_size); + memcpy(fence->private, private, private_size); + } + + _glthread_UNLOCK_MUTEX(fence->mutex); + return fence; +} + + +static int +tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type) +{ + long fd = (long) mgr->private; + int dummy; + drmFence *fence = (drmFence *) private; + int ret; + + *signaled_type = 0; + ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); + if (ret) + return ret; + + *signaled_type = fence->signaled; + + return 0; +} + +static int +tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, + int lazy_hint) +{ + long fd = (long) mgr->private; + unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; + + return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); +} + +static int +tUnref(struct _DriFenceMgr *mgr, void **private) +{ + long fd = (long) mgr->private; + drmFence *fence = (drmFence *) *private; + *private = NULL; + + return drmFenceUnreference(fd, fence); +} + +struct _DriFenceMgr *driFenceMgrTTMInit(int fd) +{ + struct _DriFenceMgrCreateInfo info; + struct _DriFenceMgr *mgr; + + info.flags = DRI_FENCE_CLASS_ORDERED; + info.num_classes = 4; + info.signaled = tSignaled; + info.finish = tFinish; + info.unreference = tUnref; + + mgr = driFenceMgrCreate(&info); + if (mgr == NULL) + return NULL; + + mgr->private = (void *) (long) fd; + return mgr; +} + diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h b/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h new file mode 100644 index 0000000000..4ea58dfe18 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h @@ -0,0 +1,115 @@ +#ifndef DRI_FENCEMGR_H +#define DRI_FENCEMGR_H + +#include +#include + +struct _DriFenceObject; +struct _DriFenceMgr; + +/* + * Do a quick check to see if the fence manager has registered the fence + * object as signaled. Note that this function may return a false negative + * answer. + */ +extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); + +/* + * Check if the fence object is signaled. This function can be substantially + * more expensive to call than the above function, but will not return a false + * negative answer. The argument "flush_type" sets the types that the + * underlying mechanism must make sure will eventually signal. + */ +extern int driFenceSignaledType(struct _DriFenceObject *fence, + uint32_t flush_type, uint32_t *signaled); + +/* + * Convenience functions. + */ + +static inline int driFenceSignaled(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types; + int ret = driFenceSignaledType(fence, flush_type, &signaled_types); + if (ret) + return 0; + return ((signaled_types & flush_type) == flush_type); +} + +static inline int driFenceSignaledCached(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types = + driFenceSignaledTypeCached(fence); + + return ((signaled_types & flush_type) == flush_type); +} + +/* + * Reference a fence object. + */ +extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); + +/* + * Unreference a fence object. The fence object pointer will be reset to NULL. + */ + +extern void driFenceUnReference(struct _DriFenceObject **pFence); + + +/* + * Wait for a fence to signal the indicated fence_type. + * If "lazy_hint" is true, it indicates that the wait may sleep to avoid + * busy-wait polling. + */ +extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint); + +/* + * Create a DriFenceObject for manager "mgr". + * + * "private" is a pointer that should be used for the callbacks in + * struct _DriFenceMgrCreateInfo. + * + * if private_size is nonzero, then the info stored at *private, with size + * private size will be copied and the fence manager will instead use a + * pointer to the copied data for the callbacks in + * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by + * "private" may be destroyed after the call to driFenceCreate. + */ +extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, + uint32_t fence_class, + uint32_t fence_type, + void *private, + size_t private_size); + +extern uint32_t driFenceType(struct _DriFenceObject *fence); + +/* + * Fence creations are ordered. If a fence signals a fence_type, + * it is safe to assume that all fences of the same class that was + * created before that fence has signaled the same type. + */ + +#define DRI_FENCE_CLASS_ORDERED (1 << 0) + +struct _DriFenceMgrCreateInfo { + uint32_t flags; + uint32_t num_classes; + int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type); + int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); + int (*unreference) (struct _DriFenceMgr *mgr, void **private); +}; + +extern struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr); + +extern struct _DriFenceMgr * +driFenceMgrTTMInit(int fd); + +#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c b/src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c new file mode 100644 index 0000000000..a80555c9c7 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c @@ -0,0 +1,161 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +#include +#include +#include +#include "pipe/p_debug.h" +#include "glthread.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + unsigned long *private = malloc(size + 2*sizeof(unsigned long)); + if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) + abort(); + + *private = size; + return (void *)private; +} + + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + free(private); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + *virtual = (void *)((unsigned long *)private + 2); + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); + return 0UL; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + return *(unsigned long *) private; +} + + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + abort(); + return 0UL; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + abort(); + return NULL; +} + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + + +struct _DriBufferPool * +driMallocPoolInit(void) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + if (!pool) + return NULL; + + pool->data = NULL; + pool->fd = -1; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + return pool; +} diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c b/src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c new file mode 100644 index 0000000000..dfcf6d6b19 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c @@ -0,0 +1,968 @@ +/************************************************************************** + * + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#include +#include +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" +#include "ws_dri_bufmgr.h" +#include "glthread.h" + +#define DRI_SLABPOOL_ALLOC_RETRIES 100 + +struct _DriSlab; + +struct _DriSlabBuffer { + int isSlabBuffer; + drmBO *bo; + struct _DriFenceObject *fence; + struct _DriSlab *parent; + drmMMListHead head; + uint32_t mapCount; + uint32_t start; + uint32_t fenceType; + int unFenced; + _glthread_Cond event; +}; + +struct _DriKernelBO { + int fd; + drmBO bo; + drmMMListHead timeoutHead; + drmMMListHead head; + struct timeval timeFreed; + uint32_t pageAlignment; + void *virtual; +}; + +struct _DriSlab{ + drmMMListHead head; + drmMMListHead freeBuffers; + uint32_t numBuffers; + uint32_t numFree; + struct _DriSlabBuffer *buffers; + struct _DriSlabSizeHeader *header; + struct _DriKernelBO *kbo; +}; + + +struct _DriSlabSizeHeader { + drmMMListHead slabs; + drmMMListHead freeSlabs; + drmMMListHead delayedBuffers; + uint32_t numDelayed; + struct _DriSlabPool *slabPool; + uint32_t bufSize; + _glthread_Mutex mutex; +}; + +struct _DriFreeSlabManager { + struct timeval slabTimeout; + struct timeval checkInterval; + struct timeval nextCheck; + drmMMListHead timeoutList; + drmMMListHead unCached; + drmMMListHead cached; + _glthread_Mutex mutex; +}; + + +struct _DriSlabPool { + + /* + * The data of this structure remains constant after + * initialization and thus needs no mutex protection. + */ + + struct _DriFreeSlabManager *fMan; + uint64_t proposedFlags; + uint64_t validMask; + uint32_t *bucketSizes; + uint32_t numBuckets; + uint32_t pageSize; + int fd; + int pageAlignment; + int maxSlabSize; + int desiredNumBuffers; + struct _DriSlabSizeHeader *headers; +}; + +/* + * FIXME: Perhaps arrange timeout slabs in size buckets for fast + * retreival?? + */ + + +static inline int +driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) +{ + return ((arg1->tv_sec > arg2->tv_sec) || + ((arg1->tv_sec == arg2->tv_sec) && + (arg1->tv_usec > arg2->tv_usec))); +} + +static inline void +driTimeAdd(struct timeval *arg, struct timeval *add) +{ + unsigned int sec; + + arg->tv_sec += add->tv_sec; + arg->tv_usec += add->tv_usec; + sec = arg->tv_usec / 1000000; + arg->tv_sec += sec; + arg->tv_usec -= sec*1000000; +} + +static void +driFreeKernelBO(struct _DriKernelBO *kbo) +{ + if (!kbo) + return; + + (void) drmBOUnreference(kbo->fd, &kbo->bo); + free(kbo); +} + + +static void +driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, + struct timeval *time) +{ + drmMMListHead *list, *next; + struct _DriKernelBO *kbo; + + if (!driTimeAfterEq(time, &fMan->nextCheck)) + return; + + for (list = fMan->timeoutList.next, next = list->next; + list != &fMan->timeoutList; + list = next, next = list->next) { + + kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); + + if (!driTimeAfterEq(time, &kbo->timeFreed)) + break; + + DRMLISTDELINIT(&kbo->timeoutHead); + DRMLISTDELINIT(&kbo->head); + driFreeKernelBO(kbo); + } + + fMan->nextCheck = *time; + driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); +} + + +/* + * Add a _DriKernelBO to the free slab manager. + * This means that it is available for reuse, but if it's not + * reused in a while, it will be freed. + */ + +static void +driSetKernelBOFree(struct _DriFreeSlabManager *fMan, + struct _DriKernelBO *kbo) +{ + struct timeval time; + + _glthread_LOCK_MUTEX(fMan->mutex); + gettimeofday(&time, NULL); + driTimeAdd(&time, &fMan->slabTimeout); + + kbo->timeFreed = time; + + if (kbo->bo.flags & DRM_BO_FLAG_CACHED) + DRMLISTADD(&kbo->head, &fMan->cached); + else + DRMLISTADD(&kbo->head, &fMan->unCached); + + DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); + driFreeTimeoutKBOsLocked(fMan, &time); + + _glthread_UNLOCK_MUTEX(fMan->mutex); +} + +/* + * Get a _DriKernelBO for us to use as storage for a slab. + * + */ + +static struct _DriKernelBO * +driAllocKernelBO(struct _DriSlabSizeHeader *header) + +{ + struct _DriSlabPool *slabPool = header->slabPool; + struct _DriFreeSlabManager *fMan = slabPool->fMan; + drmMMListHead *list, *next, *head; + uint32_t size = header->bufSize * slabPool->desiredNumBuffers; + struct _DriKernelBO *kbo; + struct _DriKernelBO *kboTmp; + int ret; + + /* + * FIXME: We should perhaps allow some variation in slabsize in order + * to efficiently reuse slabs. + */ + + size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; + size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); + _glthread_LOCK_MUTEX(fMan->mutex); + + kbo = NULL; + + retry: + head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? + &fMan->cached : &fMan->unCached; + + for (list = head->next, next = list->next; + list != head; + list = next, next = list->next) { + + kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); + + if ((kboTmp->bo.size == size) && + (slabPool->pageAlignment == 0 || + (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { + + if (!kbo) + kbo = kboTmp; + + if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) + break; + + } + } + + if (kbo) { + DRMLISTDELINIT(&kbo->head); + DRMLISTDELINIT(&kbo->timeoutHead); + } + + _glthread_UNLOCK_MUTEX(fMan->mutex); + + if (kbo) { + uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; + + ret = 0; + if (new_mask) { + ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, + new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); + } + if (ret == 0) + return kbo; + + driFreeKernelBO(kbo); + kbo = NULL; + goto retry; + } + + kbo = calloc(1, sizeof(struct _DriKernelBO)); + if (!kbo) + return NULL; + + kbo->fd = slabPool->fd; + DRMINITLISTHEAD(&kbo->head); + DRMINITLISTHEAD(&kbo->timeoutHead); + ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, + slabPool->proposedFlags, + DRM_BO_HINT_DONT_FENCE, &kbo->bo); + if (ret) + goto out_err0; + + ret = drmBOMap(kbo->fd, &kbo->bo, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &kbo->virtual); + + if (ret) + goto out_err1; + + ret = drmBOUnmap(kbo->fd, &kbo->bo); + if (ret) + goto out_err1; + + return kbo; + + out_err1: + drmBOUnreference(kbo->fd, &kbo->bo); + out_err0: + free(kbo); + return NULL; +} + + +static int +driAllocSlab(struct _DriSlabSizeHeader *header) +{ + struct _DriSlab *slab; + struct _DriSlabBuffer *buf; + uint32_t numBuffers; + int ret; + int i; + + slab = calloc(1, sizeof(*slab)); + if (!slab) + return -ENOMEM; + + slab->kbo = driAllocKernelBO(header); + if (!slab->kbo) { + ret = -ENOMEM; + goto out_err0; + } + + numBuffers = slab->kbo->bo.size / header->bufSize; + + slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); + if (!slab->buffers) { + ret = -ENOMEM; + goto out_err1; + } + + DRMINITLISTHEAD(&slab->head); + DRMINITLISTHEAD(&slab->freeBuffers); + slab->numBuffers = numBuffers; + slab->numFree = 0; + slab->header = header; + + buf = slab->buffers; + for (i=0; i < numBuffers; ++i) { + buf->parent = slab; + buf->start = i* header->bufSize; + buf->mapCount = 0; + buf->isSlabBuffer = 1; + _glthread_INIT_COND(buf->event); + DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); + slab->numFree++; + buf++; + } + + DRMLISTADDTAIL(&slab->head, &header->slabs); + + return 0; + + out_err1: + driSetKernelBOFree(header->slabPool->fMan, slab->kbo); + free(slab->buffers); + out_err0: + free(slab); + return ret; +} + +/* + * Delete a buffer from the slab header delayed list and put + * it on the slab free list. + */ + +static void +driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) +{ + struct _DriSlab *slab = buf->parent; + struct _DriSlabSizeHeader *header = slab->header; + drmMMListHead *list = &buf->head; + + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &slab->freeBuffers); + slab->numFree++; + + if (slab->head.next == &slab->head) + DRMLISTADDTAIL(&slab->head, &header->slabs); + + if (slab->numFree == slab->numBuffers) { + list = &slab->head; + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &header->freeSlabs); + } + + if (header->slabs.next == &header->slabs || + slab->numFree != slab->numBuffers) { + + drmMMListHead *next; + struct _DriFreeSlabManager *fMan = header->slabPool->fMan; + + for (list = header->freeSlabs.next, next = list->next; + list != &header->freeSlabs; + list = next, next = list->next) { + + slab = DRMLISTENTRY(struct _DriSlab, list, head); + + DRMLISTDELINIT(list); + driSetKernelBOFree(fMan, slab->kbo); + free(slab->buffers); + free(slab); + } + } +} + +static void +driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) +{ + drmMMListHead *list, *prev, *first; + struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + int firstWasSignaled = 1; + int signaled; + int i; + int ret; + + /* + * Rerun the freeing test if the youngest tested buffer + * was signaled, since there might be more idle buffers + * in the delay list. + */ + + while (firstWasSignaled) { + firstWasSignaled = 0; + signaled = 0; + first = header->delayedBuffers.next; + + /* Only examine the oldest 1/3 of delayed buffers: + */ + if (header->numDelayed > 3) { + for (i = 0; i < header->numDelayed; i += 3) { + first = first->next; + } + } + + for (list = first, prev = list->prev; + list != &header->delayedBuffers; + list = prev, prev = list->prev) { + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + slab = buf->parent; + + if (!signaled) { + if (wait) { + ret = driFenceFinish(buf->fence, buf->fenceType, 0); + if (ret) + break; + signaled = 1; + wait = 0; + } else { + signaled = driFenceSignaled(buf->fence, buf->fenceType); + } + if (signaled) { + if (list == first) + firstWasSignaled = 1; + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } + } +} + + +static struct _DriSlabBuffer * +driSlabAllocBuffer(struct _DriSlabSizeHeader *header) +{ + static struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + drmMMListHead *list; + int count = DRI_SLABPOOL_ALLOC_RETRIES; + + _glthread_LOCK_MUTEX(header->mutex); + while(header->slabs.next == &header->slabs && count > 0) { + driSlabCheckFreeLocked(header, 0); + if (header->slabs.next != &header->slabs) + break; + + _glthread_UNLOCK_MUTEX(header->mutex); + if (count != DRI_SLABPOOL_ALLOC_RETRIES) + usleep(1); + _glthread_LOCK_MUTEX(header->mutex); + (void) driAllocSlab(header); + count--; + } + + list = header->slabs.next; + if (list == &header->slabs) { + _glthread_UNLOCK_MUTEX(header->mutex); + return NULL; + } + slab = DRMLISTENTRY(struct _DriSlab, list, head); + if (--slab->numFree == 0) + DRMLISTDELINIT(list); + + list = slab->freeBuffers.next; + DRMLISTDELINIT(list); + + _glthread_UNLOCK_MUTEX(header->mutex); + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + return buf; +} + +static void * +pool_create(struct _DriBufferPool *driPool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment) +{ + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + struct _DriSlabSizeHeader *header; + struct _DriSlabBuffer *buf; + void *dummy; + int i; + int ret; + + /* + * FIXME: Check for compatibility. + */ + + header = pool->headers; + for (i=0; inumBuckets; ++i) { + if (header->bufSize >= size) + break; + header++; + } + + if (i < pool->numBuckets) + return driSlabAllocBuffer(header); + + + /* + * Fall back to allocate a buffer object directly from DRM. + * and wrap it in a driBO structure. + */ + + + buf = calloc(1, sizeof(*buf)); + + if (!buf) + return NULL; + + buf->bo = calloc(1, sizeof(*buf->bo)); + if (!buf->bo) + goto out_err0; + + if (alignment) { + if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) + goto out_err1; + if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) + goto out_err1; + } + + ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, + flags, hint, buf->bo); + if (ret) + goto out_err1; + + ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &dummy); + if (ret) + goto out_err2; + + ret = drmBOUnmap(pool->fd, buf->bo); + if (ret) + goto out_err2; + + return buf; + out_err2: + drmBOUnreference(pool->fd, buf->bo); + out_err1: + free(buf->bo); + out_err0: + free(buf); + return NULL; +} + +static int +pool_destroy(struct _DriBufferPool *driPool, void *private) +{ + struct _DriSlabBuffer *buf = + (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + int ret; + + ret = drmBOUnreference(pool->fd, buf->bo); + free(buf->bo); + free(buf); + return ret; + } + + slab = buf->parent; + header = slab->header; + + _glthread_LOCK_MUTEX(header->mutex); + buf->unFenced = 0; + buf->mapCount = 0; + + if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { + DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); + header->numDelayed++; + } else { + if (buf->fence) + driFenceUnReference(&buf->fence); + driSlabFreeBufferLocked(buf); + } + + _glthread_UNLOCK_MUTEX(header->mutex); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *driPool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + while(buf->unFenced) + _glthread_COND_WAIT(buf->event, *mutex); + + if (!buf->fence) + return 0; + + driFenceFinish(buf->fence, buf->fenceType, lazy); + driFenceUnReference(&buf->fence); + + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + int busy; + + if (buf->isSlabBuffer) + busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); + else + busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); + + + if (busy) { + if (hint & DRM_BO_HINT_DONT_BLOCK) + return -EBUSY; + else { + (void) pool_waitIdle(pool, private, mutex, 0); + } + } + + ++buf->mapCount; + *virtual = (buf->isSlabBuffer) ? + (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : + (void *) buf->bo->virtual; + + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + --buf->mapCount; + if (buf->mapCount == 0 && buf->isSlabBuffer) + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return buf->bo->offset; + } + + slab = buf->parent; + header = slab->header; + + (void) header; + assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return slab->kbo->bo.offset + buf->start; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return buf->start; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return buf->bo->flags; + + return buf->parent->kbo->bo.flags; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + if (!buf->isSlabBuffer) + return buf->bo->size; + + return buf->parent->header->bufSize; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + drmBO *bo; + + if (buf->fence) + driFenceUnReference(&buf->fence); + + buf->fence = driFenceReference(fence); + bo = (buf->isSlabBuffer) ? + &buf->parent->kbo->bo: + buf->bo; + buf->fenceType = bo->fenceFlags; + + buf->unFenced = 0; + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; +} + +static int +pool_validate(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return 0; + + while(buf->mapCount != 0) + _glthread_COND_WAIT(buf->event, *mutex); + + buf->unFenced = 1; + return 0; +} + + +struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) +{ + struct _DriFreeSlabManager *tmp; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; + tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; + tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; + + tmp->checkInterval.tv_usec = checkIntervalMsec*1000; + tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; + tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; + + gettimeofday(&tmp->nextCheck, NULL); + driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); + DRMINITLISTHEAD(&tmp->timeoutList); + DRMINITLISTHEAD(&tmp->unCached); + DRMINITLISTHEAD(&tmp->cached); + _glthread_UNLOCK_MUTEX(tmp->mutex); + + return tmp; +} + +void +driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) +{ + struct timeval time; + + time = fMan->nextCheck; + driTimeAdd(&time, &fMan->checkInterval); + + _glthread_LOCK_MUTEX(fMan->mutex); + driFreeTimeoutKBOsLocked(fMan, &time); + _glthread_UNLOCK_MUTEX(fMan->mutex); + + assert(fMan->timeoutList.next == &fMan->timeoutList); + assert(fMan->unCached.next == &fMan->unCached); + assert(fMan->cached.next == &fMan->cached); + + free(fMan); +} + +static void +driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, + struct _DriSlabSizeHeader *header) +{ + _glthread_INIT_MUTEX(header->mutex); + _glthread_LOCK_MUTEX(header->mutex); + + DRMINITLISTHEAD(&header->slabs); + DRMINITLISTHEAD(&header->freeSlabs); + DRMINITLISTHEAD(&header->delayedBuffers); + + header->numDelayed = 0; + header->slabPool = pool; + header->bufSize = size; + + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +driFinishSizeHeader(struct _DriSlabSizeHeader *header) +{ + drmMMListHead *list, *next; + struct _DriSlabBuffer *buf; + + _glthread_LOCK_MUTEX(header->mutex); + for (list = header->delayedBuffers.next, next = list->next; + list != &header->delayedBuffers; + list = next, next = list->next) { + + buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); + if (buf->fence) { + (void) driFenceFinish(buf->fence, buf->fenceType, 0); + driFenceUnReference(&buf->fence); + } + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +pool_takedown(struct _DriBufferPool *driPool) +{ + struct _DriSlabPool *pool = driPool->data; + int i; + + for (i=0; inumBuckets; ++i) { + driFinishSizeHeader(&pool->headers[i]); + } + + free(pool->headers); + free(pool->bucketSizes); + free(pool); + free(driPool); +} + +struct _DriBufferPool * +driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan) +{ + struct _DriBufferPool *driPool; + struct _DriSlabPool *pool; + uint32_t i; + + driPool = calloc(1, sizeof(*driPool)); + if (!driPool) + return NULL; + + pool = calloc(1, sizeof(*pool)); + if (!pool) + goto out_err0; + + pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); + if (!pool->bucketSizes) + goto out_err1; + + pool->headers = calloc(numSizes, sizeof(*pool->headers)); + if (!pool->headers) + goto out_err2; + + pool->fMan = fMan; + pool->proposedFlags = flags; + pool->validMask = validMask; + pool->numBuckets = numSizes; + pool->pageSize = getpagesize(); + pool->fd = fd; + pool->pageAlignment = pageAlignment; + pool->maxSlabSize = maxSlabSize; + pool->desiredNumBuffers = desiredNumBuffers; + + for (i=0; inumBuckets; ++i) { + pool->bucketSizes[i] = (smallestSize << i); + driInitSizeHeader(pool, pool->bucketSizes[i], + &pool->headers[i]); + } + + driPool->data = (void *) pool; + driPool->map = &pool_map; + driPool->unmap = &pool_unmap; + driPool->destroy = &pool_destroy; + driPool->offset = &pool_offset; + driPool->poolOffset = &pool_poolOffset; + driPool->flags = &pool_flags; + driPool->size = &pool_size; + driPool->create = &pool_create; + driPool->fence = &pool_fence; + driPool->kernel = &pool_kernel; + driPool->validate = &pool_validate; + driPool->waitIdle = &pool_waitIdle; + driPool->takeDown = &pool_takedown; + + return driPool; + + out_err2: + free(pool->bucketSizes); + out_err1: + free(pool); + out_err0: + free(driPool); + + return NULL; +} diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index 3bc1fdd4d4..07abfa53f3 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -54,6 +54,7 @@ SHARED_INCLUDES = \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/winsys/common \ -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/main \ -I$(TOP)/src/mesa/glapi \ diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index c0ce2f927b..00ce21f690 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -4,26 +4,17 @@ include $(TOP)/configs/current LIBNAME = i915_dri.so -MINIGLX_SOURCES = server/intel_dri.c - PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ + $(TOP)/src/gallium/winsys/common/intel_drm/libinteldrm.a DRIVER_SOURCES = \ - intel_winsys_pipe.c \ intel_winsys_softpipe.c \ - intel_winsys_i915.c \ - intel_batchbuffer.c \ intel_swapbuffers.c \ intel_context.c \ intel_lock.c \ - intel_screen.c \ - ws_dri_bufmgr.c \ - ws_dri_drmpool.c \ - ws_dri_fencemgr.c \ - ws_dri_mallocpool.c \ - ws_dri_slabpool.c + intel_screen.c C_SOURCES = \ $(COMMON_GALLIUM_SOURCES) \ @@ -36,6 +27,6 @@ DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm - include ../Makefile.template -intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c +#intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c symlinks: diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c deleted file mode 100644 index aa33c12045..0000000000 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ /dev/null @@ -1,462 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 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 "intel_batchbuffer.h" -#include "intel_context.h" -#include - -#if 0 -static void -intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) -{ - int i; - fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); - for (i = 0; i < count / 4; i += 4) - fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", - offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); - fprintf(stderr, "END BATCH\n\n\n"); -} -#endif - -static void -intel_realloc_relocs(struct intel_batchbuffer *batch, int num_relocs) -{ - unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; - - size *= sizeof(uint32_t); - batch->reloc = realloc(batch->reloc, size); - batch->reloc_size = num_relocs; -} - - -void -intel_batchbuffer_reset(struct intel_batchbuffer *batch) -{ - /* - * Get a new, free batchbuffer. - */ - drmBO *bo; - struct drm_bo_info_req *req; - - driBOUnrefUserList(batch->list); - driBOResetList(batch->list); - - /* base.size is the size available to the i915simple driver */ - batch->base.size = batch->intel->intelScreen->max_batch_size - BATCH_RESERVED; - batch->base.actual_size = batch->intel->intelScreen->max_batch_size; - driBOData(batch->buffer, batch->base.actual_size, NULL, NULL, 0); - - /* - * Add the batchbuffer to the validate list. - */ - - driBOAddListItem(batch->list, batch->buffer, - DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, - &batch->dest_location, &batch->node); - - req = &batch->node->bo_arg.d.req.bo_req; - - /* - * Set up information needed for us to make relocations - * relative to the underlying drm buffer objects. - */ - - driReadLockKernelBO(); - bo = driBOKernel(batch->buffer); - req->presumed_offset = (uint64_t) bo->offset; - req->hint = DRM_BO_HINT_PRESUMED_OFFSET; - batch->drmBOVirtual = (uint8_t *) bo->virtual; - driReadUnlockKernelBO(); - - /* - * Adjust the relocation buffer size. - */ - - if (batch->reloc_size > INTEL_MAX_RELOCS || - batch->reloc == NULL) - intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); - - assert(batch->reloc != NULL); - batch->reloc[0] = 0; /* No relocs yet. */ - batch->reloc[1] = 1; /* Reloc type 1 */ - batch->reloc[2] = 0; /* Only a single relocation list. */ - batch->reloc[3] = 0; /* Only a single relocation list. */ - - batch->base.map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); - batch->poolOffset = driBOPoolOffset(batch->buffer); - batch->base.ptr = batch->base.map; - batch->dirty_state = ~0; - batch->nr_relocs = 0; - batch->flags = 0; - batch->id = 0;//batch->intel->intelScreen->batch_id++; -} - -/*====================================================================== - * Public functions - */ -struct intel_batchbuffer * -intel_batchbuffer_alloc(struct intel_context *intel) -{ - struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); - - batch->intel = intel; - - driGenBuffers(intel->intelScreen->batchPool, "batchbuffer", 1, - &batch->buffer, 4096, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); - batch->last_fence = NULL; - batch->list = driBOCreateList(20); - batch->reloc = NULL; - intel_batchbuffer_reset(batch); - return batch; -} - -void -intel_batchbuffer_free(struct intel_batchbuffer *batch) -{ - if (batch->last_fence) { - driFenceFinish(batch->last_fence, - DRM_FENCE_TYPE_EXE, GL_FALSE); - driFenceUnReference(&batch->last_fence); - } - if (batch->base.map) { - driBOUnmap(batch->buffer); - batch->base.map = NULL; - } - driBOUnReference(batch->buffer); - driBOFreeList(batch->list); - if (batch->reloc) - free(batch->reloc); - batch->buffer = NULL; - free(batch); -} - -void -intel_offset_relocation(struct intel_batchbuffer *batch, - unsigned pre_add, - struct _DriBufferObject *driBO, - uint64_t val_flags, - uint64_t val_mask) -{ - int itemLoc; - struct _drmBONode *node; - uint32_t *reloc; - struct drm_bo_info_req *req; - - driBOAddListItem(batch->list, driBO, val_flags, val_mask, - &itemLoc, &node); - req = &node->bo_arg.d.req.bo_req; - - if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { - - /* - * Stop other threads from tampering with the underlying - * drmBO while we're reading its offset. - */ - - driReadLockKernelBO(); - req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; - driReadUnlockKernelBO(); - req->hint = DRM_BO_HINT_PRESUMED_OFFSET; - } - - pre_add += driBOPoolOffset(driBO); - - if (batch->nr_relocs == batch->reloc_size) - intel_realloc_relocs(batch, batch->reloc_size * 2); - - reloc = batch->reloc + - (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); - - reloc[0] = ((uint8_t *)batch->base.ptr - batch->drmBOVirtual); - intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add); - reloc[1] = pre_add; - reloc[2] = itemLoc; - reloc[3] = batch->dest_location; - batch->nr_relocs++; -} - -static void -i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) -{ - buf->handle = rep->handle; - buf->flags = rep->flags; - buf->size = rep->size; - buf->offset = rep->offset; - buf->mapHandle = rep->arg_handle; - buf->proposedFlags = rep->proposed_flags; - buf->start = rep->buffer_start; - buf->fenceFlags = rep->fence_flags; - buf->replyFlags = rep->rep_flags; - buf->pageAlignment = rep->page_alignment; -} - -static int -i915_execbuf(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, - drmBOList *list, - struct drm_i915_execbuffer *ea) -{ - struct intel_context *intel = batch->intel; - drmBONode *node; - drmMMListHead *l; - struct drm_i915_op_arg *arg, *first; - struct drm_bo_op_req *req; - struct drm_bo_info_rep *rep; - uint64_t *prevNext = NULL; - drmBO *buf; - int ret = 0; - uint32_t count = 0; - - first = NULL; - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - - arg = &node->bo_arg; - req = &arg->d.req; - - if (!first) - first = arg; - - if (prevNext) - *prevNext = (unsigned long)arg; - - prevNext = &arg->next; - req->bo_req.handle = node->buf->handle; - req->op = drm_bo_validate; - req->bo_req.flags = node->arg0; - req->bo_req.mask = node->arg1; - req->bo_req.hint |= 0; - count++; - } - - memset(ea, 0, sizeof(*ea)); - ea->num_buffers = count; - ea->batch.start = batch->poolOffset; - ea->batch.used = used; -#if 0 /* ZZZ JB: no cliprects used */ - ea->batch.cliprects = intel->pClipRects; - ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; - ea->batch.DR1 = 0; - ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | - (((GLuint) intel->drawY) << 16)); -#else - ea->batch.cliprects = NULL; - ea->batch.num_cliprects = 0; - ea->batch.DR1 = 0; - ea->batch.DR4 = 0; -#endif - ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; - ea->ops_list = (unsigned long) first; - first->reloc_ptr = (unsigned long) batch->reloc; - batch->reloc[0] = batch->nr_relocs; - - //return -EFAULT; - do { - ret = drmCommandWriteRead(intel->driFd, DRM_I915_EXECBUFFER, ea, - sizeof(*ea)); - } while (ret == -EAGAIN); - - if (ret != 0) - return ret; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - arg = &node->bo_arg; - rep = &arg->d.rep.bo_info; - - if (!arg->handled) { - return -EFAULT; - } - if (arg->d.rep.ret) - return arg->d.rep.ret; - - buf = node->buf; - i915_drm_copy_reply(rep, buf); - } - return 0; -} - -/* TODO: Push this whole function into bufmgr. - */ -static struct _DriFenceObject * -do_flush_locked(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock) -{ - struct intel_context *intel = batch->intel; - struct _DriFenceObject *fo; - drmFence fence; - drmBOList *boList; - struct drm_i915_execbuffer ea; - int ret = 0; - - driBOValidateUserList(batch->list); - boList = driGetdrmBOList(batch->list); - -#if 0 /* ZZZ JB Allways run */ - if (!(intel->numClipRects == 0 && !ignore_cliprects)) { -#else - if (1) { -#endif - ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); - } else { - driPutdrmBOList(batch->list); - fo = NULL; - goto out; - } - driPutdrmBOList(batch->list); - if (ret) - abort(); - - if (ea.fence_arg.error != 0) { - - /* - * The hardware has been idled by the kernel. - * Don't fence the driBOs. - */ - - if (batch->last_fence) - driFenceUnReference(&batch->last_fence); -#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ - _mesa_printf("fence error\n"); -#endif - batch->last_fence = NULL; - fo = NULL; - goto out; - } - - fence.handle = ea.fence_arg.handle; - fence.fence_class = ea.fence_arg.fence_class; - fence.type = ea.fence_arg.type; - fence.flags = ea.fence_arg.flags; - fence.signaled = ea.fence_arg.signaled; - - fo = driBOFenceUserList(batch->intel->intelScreen->mgr, batch->list, - "SuperFence", &fence); - - if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { - if (batch->last_fence) - driFenceUnReference(&batch->last_fence); - /* - * FIXME: Context last fence?? - */ - batch->last_fence = fo; - driFenceReference(fo); - } - out: -#if 0 /* ZZZ JB: fix this */ - intel->vtbl.lost_hardware(intel); -#else - (void)intel; -#endif - return fo; -} - - -struct _DriFenceObject * -intel_batchbuffer_flush(struct intel_batchbuffer *batch) -{ - struct intel_context *intel = batch->intel; - GLuint used = batch->base.ptr - batch->base.map; - GLboolean was_locked = intel->locked; - struct _DriFenceObject *fence; - - if (used == 0) { - driFenceReference(batch->last_fence); - return batch->last_fence; - } - - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a - * performance drain that we would like to avoid. - */ -#if 0 /* ZZZ JB: what should we do here? */ - if (used & 4) { - ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->base.ptr)[1] = 0; - ((int *) batch->base.ptr)[2] = MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->base.ptr)[1] = MI_BATCH_BUFFER_END; - used += 8; - } -#else - if (used & 4) { - ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->base.ptr)[1] = 0; - ((int *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; - used += 8; - } -#endif - driBOUnmap(batch->buffer); - batch->base.ptr = NULL; - batch->base.map = NULL; - - /* TODO: Just pass the relocation list and dma buffer up to the - * kernel. - */ - if (!was_locked) - LOCK_HARDWARE(intel); - - fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), - GL_FALSE); - - if (!was_locked) - UNLOCK_HARDWARE(intel); - - /* Reset the buffer: - */ - intel_batchbuffer_reset(batch); - return fence; -} - -void -intel_batchbuffer_finish(struct intel_batchbuffer *batch) -{ - struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); - driFenceFinish(fence, driFenceType(fence), GL_FALSE); - driFenceUnReference(&fence); -} - -void -intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags) -{ - assert((bytes & 3) == 0); - intel_batchbuffer_require_space(batch, bytes, flags); - memcpy(batch->base.ptr, data, bytes); - batch->base.ptr += bytes; -} diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h index abb7a624f5..1fa2719845 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -1,137 +1,24 @@ #ifndef INTEL_BATCHBUFFER_H #define INTEL_BATCHBUFFER_H -#include "mtypes.h" -#include "ws_dri_bufmgr.h" -#include "i915simple/i915_batch.h" +#include "intel_drm/intel_be_batchbuffer.h" -struct intel_context; - -#define BATCH_SZ 16384 -#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_batchbuffer -{ - struct i915_batchbuffer base; - - struct intel_context *intel; - - struct _DriBufferObject *buffer; - struct _DriFenceObject *last_fence; - GLuint flags; - - struct _DriBufferList *list; - GLuint list_count; - - uint32_t *reloc; - GLuint reloc_size; - GLuint nr_relocs; - - GLuint dirty_state; - GLuint id; - - uint32_t poolOffset; - uint8_t *drmBOVirtual; - struct _drmBONode *node; /* Validation list node for this buffer */ - int dest_location; /* Validation list sequence for this buffer */ -}; - -struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context - *intel); - -void intel_batchbuffer_free(struct intel_batchbuffer *batch); - - -void intel_batchbuffer_finish(struct intel_batchbuffer *batch); - -struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer - *batch); - -void intel_batchbuffer_reset(struct intel_batchbuffer *batch); - - -/* Unlike bmBufferData, this currently requires the buffer be mapped. - * Consider it a convenience function wrapping multple - * intel_buffer_dword() calls. - */ -void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags); - -void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, - GLuint bytes); - -void -intel_offset_relocation(struct intel_batchbuffer *batch, - unsigned pre_add, - struct _DriBufferObject *driBO, - uint64_t val_flags, - uint64_t val_mask); - -/* Inline functions - might actually be better off with these - * non-inlined. Certainly better off switching all command packets to - * be passed as structs rather than dwords, but that's a little bit of - * work... - */ -static INLINE GLuint -intel_batchbuffer_space(struct intel_batchbuffer *batch) -{ - return (batch->base.size - BATCH_RESERVED) - (batch->base.ptr - batch->base.map); -} - - -static INLINE void -intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) -{ - assert(batch->base.map); - assert(intel_batchbuffer_space(batch) >= 4); - *(GLuint *) (batch->base.ptr) = dword; - batch->base.ptr += 4; -} - -static INLINE void -intel_batchbuffer_require_space(struct intel_batchbuffer *batch, - GLuint sz, GLuint flags) -{ - struct _DriFenceObject *fence; - - assert(sz < batch->base.size - 8); - if (intel_batchbuffer_space(batch) < sz || - (batch->flags != 0 && flags != 0 && batch->flags != flags)) { - fence = intel_batchbuffer_flush(batch); - driFenceUnReference(&fence); - } - - batch->flags |= flags; -} - -/* Here are the crusty old macros, to be removed: +/* + * Need to redefine the BATCH defines */ -#undef BATCH_LOCALS -#define BATCH_LOCALS #undef BEGIN_BATCH -#define BEGIN_BATCH(n, flags) do { \ - assert(!intel->prim.flush); \ - intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ -} while (0) +#define BEGIN_BATCH(dwords, relocs) \ + (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) #undef OUT_BATCH -#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) +#define OUT_BATCH(d) \ + i915_batchbuffer_dword(&intel->base.batch->base, d) #undef OUT_RELOC -#define OUT_RELOC(buf,flags,mask,delta) do { \ +#define OUT_RELOC(buf,flags,mask,delta) do { \ assert((delta) >= 0); \ - intel_offset_relocation(intel->batch, delta, buf, flags, mask); \ + intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ } while (0) -#undef ADVANCE_BATCH -#define ADVANCE_BATCH() do { } while(0) - - #endif diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 6a0c381849..8284e0edbb 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,7 +22,7 @@ * 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. - * + * **************************************************************************/ @@ -31,8 +31,10 @@ #include "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" -#include "intel_winsys.h" #include "intel_batchbuffer.h" +#include "intel_winsys_softpipe.h" + +#include "i915simple/i915_screen.h" #include "state_tracker/st_public.h" #include "state_tracker/st_context.h" @@ -132,6 +134,46 @@ static const struct dri_debug_control debug_control[] = { +/** + * Create i915 hardware rendering context. + */ +static struct pipe_context * +intel_create_i915simple(struct intel_context *intel, + struct pipe_winsys *winsys) +{ + struct pipe_screen *screen; + + /* Fill in this struct with callbacks that i915simple will need to + * communicate with the window system, buffer manager, etc. + */ + screen = i915_create_screen(winsys, intel->intelScreen->deviceID); + + /* Create the i915simple context: + */ + return i915_create_context(screen, winsys, &intel->base.base ); +} + +static void +intel_lock_hardware(struct intel_be_context *context) +{ + struct intel_context *intel = (struct intel_context *)context; + LOCK_HARDWARE(intel); +} + +static void +intel_unlock_hardware(struct intel_be_context *context) +{ + struct intel_context *intel = (struct intel_context *)context; + UNLOCK_HARDWARE(intel); +} + +static boolean +intel_locked_hardware(struct intel_be_context *context) +{ + struct intel_context *intel = (struct intel_context *)context; + return intel->locked ? TRUE : FALSE; +} + GLboolean intelCreateContext(const __GLcontextModes * visual, __DRIcontextPrivate * driContextPriv, @@ -179,20 +221,24 @@ intelCreateContext(const __GLcontextModes * visual, intel->iw.irq_seq = -1; intel->irqsEmitted = 0; - intel->batch = intel_batchbuffer_alloc(intel); intel->last_swap_fence = NULL; intel->first_swap_fence = NULL; #ifdef DEBUG __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); #endif + intel->base.hardware_lock = intel_lock_hardware; + intel->base.hardware_unlock = intel_unlock_hardware; + intel->base.hardware_locked = intel_locked_hardware; + + intel_be_init_context(&intel->base, &intelScreen->base); /* * Pipe-related setup */ if (getenv("INTEL_SP")) { /* use softpipe driver instead of hw */ - pipe = intel_create_softpipe( intel, intelScreen->winsys ); + pipe = intel_create_softpipe( intel, &intelScreen->base.base ); } else { switch (intel->intelScreen->deviceID) { @@ -204,13 +250,13 @@ intelCreateContext(const __GLcontextModes * visual, case PCI_CHIP_Q35_G: case PCI_CHIP_I915_G: case PCI_CHIP_I915_GM: - pipe = intel_create_i915simple( intel, intelScreen->winsys ); + pipe = intel_create_i915simple( intel, &intelScreen->base.base ); break; default: - fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", + fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", intel->intelScreen->deviceID, __FUNCTION__); - pipe = intel_create_softpipe( intel, intelScreen->winsys ); + pipe = intel_create_softpipe( intel, &intelScreen->base.base ); break; } } @@ -234,8 +280,6 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) if (intel) { st_finish(intel->st); - intel_batchbuffer_free(intel->batch); - if (intel->last_swap_fence) { driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); driFenceUnReference(&intel->last_swap_fence); @@ -251,6 +295,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) intel->intelScreen->dummyContext = NULL; st_destroy_context(intel->st); + intel_be_destroy_context(&intel->base); free(intel); } } diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h index 597dc13830..ced18da143 100644 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,7 +22,7 @@ * 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. - * + * **************************************************************************/ #ifndef INTEL_CONTEXT_H @@ -36,6 +36,8 @@ #include "intel_screen.h" #include "i915_drm.h" +#include "intel_drm/intel_be_context.h" + struct pipe_context; struct intel_context; @@ -50,12 +52,13 @@ struct st_context; */ struct intel_context { + struct intel_be_context base; struct st_context *st; struct _DriFenceObject *last_swap_fence; struct _DriFenceObject *first_swap_fence; - struct intel_batchbuffer *batch; +// struct intel_batchbuffer *batch; boolean locked; char *prevLockFile; @@ -123,7 +126,7 @@ extern int __intel_debug; } while(0) #else -#define DBG(flag, ...) +#define DBG(flag, ...) #endif diff --git a/src/gallium/winsys/dri/intel/intel_lock.c b/src/gallium/winsys/dri/intel/intel_lock.c index 70aa7ea5f4..406284c98f 100644 --- a/src/gallium/winsys/dri/intel/intel_lock.c +++ b/src/gallium/winsys/dri/intel/intel_lock.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,7 +22,7 @@ * 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. - * + * **************************************************************************/ @@ -87,7 +87,7 @@ void LOCK_HARDWARE( struct intel_context *intel ) } -/* Unlock the hardware using the global current context +/* Unlock the hardware using the global current context */ void UNLOCK_HARDWARE( struct intel_context *intel ) { @@ -99,4 +99,4 @@ void UNLOCK_HARDWARE( struct intel_context *intel ) _glthread_UNLOCK_MUTEX(lockMutex); DBG(LOCK, "%s - unlocked\n", __progname); -} +} diff --git a/src/gallium/winsys/dri/intel/intel_reg.h b/src/gallium/winsys/dri/intel/intel_reg.h index f37c24fda9..4f33bee438 100644 --- a/src/gallium/winsys/dri/intel/intel_reg.h +++ b/src/gallium/winsys/dri/intel/intel_reg.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,7 +22,7 @@ * 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. - * + * **************************************************************************/ diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 0be88974f4..8817a80a5a 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,7 +22,7 @@ * 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 "utils.h" @@ -32,12 +32,10 @@ #include "intel_context.h" #include "intel_screen.h" #include "intel_batchbuffer.h" -//#include "intel_batchpool.h" #include "intel_swapbuffers.h" -#include "intel_winsys.h" #include "i830_dri.h" -#include "ws_dri_bufpool.h" +#include "intel_drm/ws_dri_bufpool.h" #include "pipe/p_context.h" #include "state_tracker/st_public.h" @@ -152,16 +150,16 @@ intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - driBOSetStatic(intelScreen->front.buffer, - intelScreen->front.offset, - intelScreen->front.pitch * intelScreen->front.height, + driBOSetStatic(intelScreen->front.buffer, + intelScreen->front.offset, + intelScreen->front.pitch * intelScreen->front.height, intelScreen->front.map, 0); } #else - if (intelScreen->staticPool) { + if (intelScreen->base.staticPool) { if (intelScreen->front.buffer) driBOUnReference(intelScreen->front.buffer); - driGenBuffers(intelScreen->staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); + driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle); } #endif @@ -177,33 +175,6 @@ intelCreatePools(__DRIscreenPrivate * sPriv) if (intelScreen->havePools) return GL_TRUE; -#if 0 /* ZZZ JB fix this */ - intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); - if (!intelScreen->staticPool) - return GL_FALSE; - - batchPoolSize /= BATCH_SZ; - intelScreen->batchPool = driBatchPoolInit(sPriv->fd, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_MEM_LOCAL, - BATCH_SZ, - batchPoolSize, 5); - if (!intelScreen->batchPool) { - fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); - return GL_FALSE; - } -#else - intelScreen->staticPool = driDRMPoolInit(sPriv->fd); - intelScreen->batchPool = driSlabPoolInit(sPriv->fd, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - intelScreen->max_batch_size, - 1, 40, intelScreen->max_batch_size * 16, 0, - intelScreen->fMan); -#endif intelScreen->havePools = GL_TRUE; intelUpdateScreenRotation(sPriv, intelScreen->sarea); @@ -211,6 +182,27 @@ intelCreatePools(__DRIscreenPrivate * sPriv) return GL_TRUE; } +static const char * +intel_get_name( struct pipe_winsys *winsys ) +{ + return "Intel/DRI/ttm"; +} + +/* + * The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +intel_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + intelDisplaySurface(dPriv, surf, NULL); +} static boolean intelInitDriver(__DRIscreenPrivate * sPriv) @@ -231,7 +223,7 @@ intelInitDriver(__DRIscreenPrivate * sPriv) /* Allocate the private area */ intelScreen = CALLOC_STRUCT(intel_screen); - if (!intelScreen) + if (!intelScreen) return GL_FALSE; /* parse information in __driConfigOptions */ @@ -262,26 +254,9 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - intelScreen->max_batch_size = 16 * 4096; - -#if 1 // ZZZ JB - intelScreen->mgr = driFenceMgrTTMInit(sPriv->fd); - if (!intelScreen->mgr) { - fprintf(stderr, "Failed to create fence manager.\n"); - return GL_FALSE; - } - - intelScreen->fMan = driInitFreeSlabManager(10, 10); - if (!intelScreen->fMan) { - fprintf(stderr, "Failed to create free slab manager.\n"); - return GL_FALSE; - } - - if (!intelCreatePools(sPriv)) - return GL_FALSE; -#endif - - intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd, intelScreen->fMan); + intel_be_init_device(&intelScreen->base, sPriv->fd); + intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; + intelScreen->base.base.get_name = intel_get_name; return GL_TRUE; } @@ -292,12 +267,9 @@ intelDestroyScreen(__DRIscreenPrivate * sPriv) { struct intel_screen *intelScreen = intel_screen(sPriv); + intel_be_destroy_device(&intelScreen->base); /* intelUnmapScreenRegions(intelScreen); */ - if (intelScreen->havePools) { - driPoolTakeDown(intelScreen->staticPool); - driPoolTakeDown(intelScreen->batchPool); - } FREE(intelScreen); sPriv->private = NULL; } @@ -518,8 +490,8 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, * This routine also fills in the linked list pointed to by \c driver_modes * with the \c __GLcontextModes that the driver can support for windows or * pbuffers. - * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on * failure. */ PUBLIC void * diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index 1db0502b13..8036917903 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,7 +22,7 @@ * 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. - * + * **************************************************************************/ #ifndef _INTEL_SCREEN_H_ @@ -31,13 +31,16 @@ #include "dri_util.h" #include "i830_common.h" #include "xmlconfig.h" -#include "ws_dri_bufpool.h" +#include "intel_drm/ws_dri_bufpool.h" #include "pipe/p_compiler.h" +#include "intel_drm/intel_be_device.h" struct intel_screen { + struct intel_be_device base; + struct { drm_handle_t handle; @@ -51,7 +54,7 @@ struct intel_screen int width; int height; int size; - int cpp; /* for front and back buffers */ + int cpp; /* for front and back buffers */ } front; int deviceID; @@ -64,8 +67,6 @@ struct intel_screen */ driOptionCache optionCache; - struct _DriBufferPool *batchPool; - struct _DriBufferPool *staticPool; /** for the X screen/framebuffer */ boolean havePools; /** @@ -74,13 +75,11 @@ struct intel_screen */ struct intel_context *dummyContext; - /* + /* * New stuff form the i915tex integration */ - struct _DriFenceMgr *mgr; - struct _DriFreeSlabManager *fMan; unsigned batch_id; - unsigned max_batch_size; + struct pipe_winsys *winsys; }; diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 923b542771..7f3babd98e 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,21 +22,22 @@ * 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 "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" -#include "intel_batchbuffer.h" + #include "intel_reg.h" -#include "intel_winsys.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 "intel_drm/ws_dri_bufmgr.h" +#include "intel_batchbuffer.h" /** * Display a colorbuffer surface in an X window. @@ -114,7 +115,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, if (pbox->x1 > pbox->x2 || pbox->y1 > pbox->y2 || - pbox->x2 > intelScreen->front.width || + pbox->x2 > intelScreen->front.width || pbox->y2 > intelScreen->front.height) { /* invalid cliprect, skip it */ continue; @@ -159,13 +160,22 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, assert(box.y1 < box.y2); /* XXX this could be done with pipe->surface_copy() */ - BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + /* XXX should have its own batch buffer */ + if (!BEGIN_BATCH(8, 2)) { + /* + * Since we share this batch buffer with a context + * we can't flush it since that risks a GPU lockup + */ + assert(0); + continue; + } + OUT_BATCH(CMD); OUT_BATCH(BR13); OUT_BATCH((box.y1 << 16) | box.x1); OUT_BATCH((box.y2 << 16) | box.x2); - OUT_RELOC(intelScreen->front.buffer, + OUT_RELOC(intelScreen->front.buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); OUT_BATCH((sbox.y1 << 16) | sbox.x1); @@ -174,12 +184,11 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - ADVANCE_BATCH(); } if (intel->first_swap_fence) driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); + intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); } UNLOCK_HARDWARE(intel); diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.h b/src/gallium/winsys/dri/intel/intel_swapbuffers.h index 7ae5fd15a5..46c9bab3af 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.h +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2006 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 @@ -10,11 +10,11 @@ * 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. @@ -22,7 +22,7 @@ * 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. - * + * **************************************************************************/ #ifndef INTEL_SWAPBUFFERS_H diff --git a/src/gallium/winsys/dri/intel/intel_winsys.h b/src/gallium/winsys/dri/intel/intel_winsys.h deleted file mode 100644 index 3d32db10a4..0000000000 --- a/src/gallium/winsys/dri/intel/intel_winsys.h +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 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. - * - **************************************************************************/ - -#ifndef INTEL_WINSYS_H -#define INTEL_WINSYS_H - -#include "pipe/p_state.h" - -struct intel_context; -struct pipe_context; -struct pipe_winsys; -struct pipe_buffer; -struct _DriBufferObject; - -struct pipe_winsys * -intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ); - -void -intel_destroy_pipe_winsys( struct pipe_winsys *winsys ); - -struct pipe_context * -intel_create_softpipe( struct intel_context *intel, - struct pipe_winsys *winsys ); - -struct pipe_context * -intel_create_i915simple( struct intel_context *intel, - struct pipe_winsys *winsys ); - - -struct intel_buffer { - struct pipe_buffer base; - struct _DriBufferPool *pool; - struct _DriBufferObject *driBO; -}; - -static INLINE struct intel_buffer * -intel_buffer( struct pipe_buffer *buf ) -{ - return (struct intel_buffer *)buf; -} - -static INLINE struct _DriBufferObject * -dri_bo( struct pipe_buffer *buf ) -{ - return intel_buffer(buf)->driBO; -} - - -#endif diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c deleted file mode 100644 index 013291364a..0000000000 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ /dev/null @@ -1,156 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" - -#include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_winsys.h" - -#include "pipe/p_util.h" -#include "pipe/p_winsys.h" -#include "i915simple/i915_winsys.h" -#include "i915simple/i915_screen.h" - - -struct intel_i915_winsys { - struct i915_winsys winsys; /**< batch buffer funcs */ - struct pipe_winsys *pws; - struct intel_context *intel; -}; - - -/* Turn a i915simple winsys into an intel/i915simple winsys: - */ -static inline struct intel_i915_winsys * -intel_i915_winsys( struct i915_winsys *sws ) -{ - return (struct intel_i915_winsys *)sws; -} - - -/* Simple batchbuffer interface: - */ - -static struct i915_batchbuffer* -intel_i915_batch_get( struct i915_winsys *sws ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - return &intel->batch->base; -} - -static void intel_i915_batch_reloc( struct i915_winsys *sws, - struct pipe_buffer *buf, - unsigned access_flags, - unsigned delta ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - unsigned flags = DRM_BO_FLAG_MEM_TT; - unsigned mask = DRM_BO_MASK_MEM; - - if (access_flags & I915_BUFFER_ACCESS_WRITE) { - flags |= DRM_BO_FLAG_WRITE; - mask |= DRM_BO_FLAG_WRITE; - } - - if (access_flags & I915_BUFFER_ACCESS_READ) { - flags |= DRM_BO_FLAG_READ; - mask |= DRM_BO_FLAG_READ; - } - - intel_offset_relocation( intel->batch, - delta, - dri_bo( buf ), - flags, - mask ); -} - -static void intel_i915_batch_flush( struct i915_winsys *sws, - struct pipe_fence_handle **fence ) -{ - struct intel_i915_winsys *iws = intel_i915_winsys(sws); - struct intel_context *intel = iws->intel; - union { - struct _DriFenceObject *dri; - struct pipe_fence_handle *pipe; - } fu; - - if (fence) - assert(!*fence); - - fu.dri = intel_batchbuffer_flush( intel->batch ); - - if (!fu.dri) { - assert(0); - *fence = NULL; - return; - } - - if (fu.dri) { - if (fence) - *fence = fu.pipe; - else - driFenceUnReference(&fu.dri); - } - -} - - -/** - * Create i915 hardware rendering context. - */ -struct pipe_context * -intel_create_i915simple( struct intel_context *intel, - struct pipe_winsys *winsys ) -{ - struct intel_i915_winsys *iws = CALLOC_STRUCT( intel_i915_winsys ); - struct pipe_screen *screen; - - /* Fill in this struct with callbacks that i915simple will need to - * communicate with the window system, buffer manager, etc. - */ - iws->winsys.batch_get = intel_i915_batch_get; - iws->winsys.batch_reloc = intel_i915_batch_reloc; - iws->winsys.batch_flush = intel_i915_batch_flush; - iws->pws = winsys; - iws->intel = intel; - - screen = i915_create_screen(winsys, intel->intelScreen->deviceID); - - /* Create the i915simple context: - */ - return i915_create_context( screen, - winsys, - &iws->winsys ); -} diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c deleted file mode 100644 index 51a79ca535..0000000000 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ /dev/null @@ -1,318 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include -#include - -#include "intel_context.h" -#include "intel_winsys.h" -#include "intel_swapbuffers.h" -#include "intel_batchbuffer.h" - -#include "pipe/p_winsys.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" - -struct intel_pipe_winsys { - struct pipe_winsys winsys; - struct _DriBufferPool *regionPool; - struct _DriBufferPool *mallocPool; - struct _DriBufferPool *vertexPool; - struct _DriFreeSlabManager *fMan; /** shared between all pipes */ -}; - - -/* Turn a pipe winsys into an intel/pipe winsys: - */ -static inline struct intel_pipe_winsys * -intel_pipe_winsys( struct pipe_winsys *winsys ) -{ - return (struct intel_pipe_winsys *)winsys; -} - - -/* - * Buffer functions. - * - * Most callbacks map direcly onto dri_bufmgr operations: - */ - -static void *intel_buffer_map(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned flags ) -{ - unsigned drm_flags = 0; - - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) - drm_flags |= DRM_BO_FLAG_WRITE; - - if (flags & PIPE_BUFFER_USAGE_CPU_READ) - drm_flags |= DRM_BO_FLAG_READ; - - return driBOMap( dri_bo(buf), drm_flags, 0 ); -} - -static void intel_buffer_unmap(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - driBOUnmap( dri_bo(buf) ); -} - -static void -intel_buffer_destroy(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - driBOUnReference( dri_bo(buf) ); - FREE(buf); -} - -static struct pipe_buffer * -intel_buffer_create(struct pipe_winsys *winsys, - unsigned alignment, - unsigned usage, - unsigned size ) -{ - struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); - struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); - unsigned flags = 0; - struct _DriBufferPool *pool; - - buffer->base.refcount = 1; - buffer->base.alignment = alignment; - buffer->base.usage = usage; - buffer->base.size = size; - - if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { - flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; - pool = iws->mallocPool; - } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { - /* For vertex buffers */ - flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; - pool = iws->vertexPool; - } else { - flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; - pool = iws->regionPool; - } - - if (usage & PIPE_BUFFER_USAGE_GPU_READ) - flags |= DRM_BO_FLAG_READ; - - if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) - flags |= DRM_BO_FLAG_WRITE; - - /* drm complains if we don't set any read/write flags. - */ - if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) - flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - -#if 0 - if (flags & IWS_BUFFER_USAGE_EXE) - flags |= DRM_BO_FLAG_EXE; - - if (usage & IWS_BUFFER_USAGE_CACHED) - flags |= DRM_BO_FLAG_CACHED; -#endif - - buffer->pool = pool; - driGenBuffers( buffer->pool, - "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); - - driBOData( buffer->driBO, size, NULL, buffer->pool, 0 ); - - return &buffer->base; -} - - -static struct pipe_buffer * -intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) -{ - struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); - struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); - - driGenUserBuffer( iws->regionPool, - "pipe user buffer", &buffer->driBO, ptr, bytes ); - - buffer->base.refcount = 1; - - return &buffer->base; -} - - -/* - * Surface functions. - * - * Deprecated! - */ - -static struct pipe_surface * -intel_i915_surface_alloc(struct pipe_winsys *winsys) -{ - assert("intel_i915_surface_alloc is deprecated" & 0); - return NULL; -} - -static int -intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, - unsigned width, unsigned height, - enum pipe_format format, - unsigned flags, - unsigned tex_usage) -{ - assert("intel_i915_surface_alloc_storage is deprecated" & 0); - return -1; -} - -static void -intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - assert("intel_i915_surface_release is deprecated" & 0); -} - -/* - * Fence functions - */ - -static void -intel_fence_reference( struct pipe_winsys *sws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence ) -{ - if (*ptr) - driFenceUnReference((struct _DriFenceObject **)ptr); - - if (fence) - *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); -} - -static int -intel_fence_signalled( struct pipe_winsys *sws, - struct pipe_fence_handle *fence, - unsigned flag ) -{ - return driFenceSignaled((struct _DriFenceObject *)fence, flag); -} - -static int -intel_fence_finish( struct pipe_winsys *sws, - struct pipe_fence_handle *fence, - unsigned flag ) -{ - return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); -} - - -/* - * Mixed functions - */ - -static const char * -intel_get_name( struct pipe_winsys *winsys ) -{ - return "Intel/DRI/ttm"; -} - -/* - * The state tracker (should!) keep track of whether the fake - * frontbuffer has been touched by any rendering since the last time - * we copied its contents to the real frontbuffer. Our task is easy: - */ -static void -intel_flush_frontbuffer( struct pipe_winsys *winsys, - struct pipe_surface *surf, - void *context_private) -{ - struct intel_context *intel = (struct intel_context *) context_private; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - intelDisplaySurface(dPriv, surf, NULL); -} - -struct pipe_winsys * -intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) -{ - struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys ); - - /* Fill in this struct with callbacks that pipe will need to - * communicate with the window system, buffer manager, etc. - * - * Pipe would be happy with a malloc based memory manager, but - * the SwapBuffers implementation in this winsys driver requires - * that rendering be done to an appropriate _DriBufferObject. - */ - iws->winsys.buffer_create = intel_buffer_create; - iws->winsys.user_buffer_create = intel_user_buffer_create; - iws->winsys.buffer_map = intel_buffer_map; - iws->winsys.buffer_unmap = intel_buffer_unmap; - iws->winsys.buffer_destroy = intel_buffer_destroy; - iws->winsys.flush_frontbuffer = intel_flush_frontbuffer; - iws->winsys.get_name = intel_get_name; - iws->winsys.surface_alloc = intel_i915_surface_alloc; - iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; - iws->winsys.surface_release = intel_i915_surface_release; - - iws->winsys.fence_reference = intel_fence_reference; - iws->winsys.fence_signalled = intel_fence_signalled; - iws->winsys.fence_finish = intel_fence_finish; - - if (fd) { - iws->regionPool = driDRMPoolInit(fd); - iws->vertexPool = driSlabPoolInit(fd, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - 128 * 4096, - 1, 120, 128 * 4096 * 4, 0, - fMan); - } - - iws->mallocPool = driMallocPoolInit(); - - return &iws->winsys; -} - -void -intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) -{ - struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); - if (iws->regionPool) { - driPoolTakeDown(iws->regionPool); - } - if (iws->mallocPool) { - driPoolTakeDown(iws->mallocPool); - } - free(iws); -} diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c index 0bc2dc4002..0d98d16cf1 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA * 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,27 +10,27 @@ * 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 + * 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. * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * - * + * + * **************************************************************************/ /* * Authors: Keith Whitwell */ #include "intel_context.h" -#include "intel_winsys.h" +#include "intel_winsys_softpipe.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" #include "pipe/p_format.h" @@ -69,9 +69,9 @@ intel_create_softpipe( struct intel_context *intel, { struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); struct pipe_screen *screen = softpipe_create_screen(winsys); - + /* Fill in this struct with callbacks that softpipe will need to - * communicate with the window system, buffer manager, etc. + * communicate with the window system, buffer manager, etc. */ isws->sws.is_format_supported = intel_is_format_supported; isws->intel = intel; diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.h b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.h new file mode 100644 index 0000000000..5fa14cb749 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.h @@ -0,0 +1,39 @@ +/************************************************************************** + * + * Copyright 2006 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. + * + **************************************************************************/ + +#ifndef INTEL_SOFTPIPE_H +#define INTEL_SOFTPIPE_H + +struct pipe_winsys; +struct pipe_context; +struct intel_context; + +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ); + +#endif diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h index f84f453309..3452ddb3c9 100644 --- a/src/gallium/winsys/dri/intel/server/i830_common.h +++ b/src/gallium/winsys/dri/intel/server/i830_common.h @@ -88,9 +88,9 @@ typedef struct { /** Last context that used the buffer manager. */ int texAge; int pf_enabled; /* is pageflipping allowed? */ - int pf_active; + int pf_active; int pf_current_page; /* which buffer is being displayed? */ - int perf_boxes; /* performance boxes to be displayed */ + int perf_boxes; /* performance boxes to be displayed */ int width, height; /* screen size in pixels */ drm_handle_t front_handle; @@ -173,7 +173,7 @@ typedef struct { int num_cliprects; /* mulitpass with multiple cliprects? */ drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ } drmI830CmdBuffer; - + typedef struct { int *irq_seq; } drmI830IrqEmit; @@ -188,7 +188,7 @@ typedef struct { } drmI830GetParam; #define I830_PARAM_IRQ_ACTIVE 1 -#define I830_PARAM_ALLOW_BATCHBUFFER 2 +#define I830_PARAM_ALLOW_BATCHBUFFER 2 typedef struct { int param; diff --git a/src/gallium/winsys/dri/intel/server/i830_dri.h b/src/gallium/winsys/dri/intel/server/i830_dri.h index 685de4a551..0d514b6c38 100644 --- a/src/gallium/winsys/dri/intel/server/i830_dri.h +++ b/src/gallium/winsys/dri/intel/server/i830_dri.h @@ -40,7 +40,7 @@ typedef struct _I830DRIRec { int bitsPerPixel; int unused11[8]; /* was front/back/depth/rotated offset/pitch */ - + int unused12; /* logTextureGranularity */ int unused13; /* textureOffset */ diff --git a/src/gallium/winsys/dri/intel/server/intel.h b/src/gallium/winsys/dri/intel/server/intel.h deleted file mode 100644 index 6ea72499c1..0000000000 --- a/src/gallium/winsys/dri/intel/server/intel.h +++ /dev/null @@ -1,331 +0,0 @@ -#ifndef _INTEL_H_ -#define _INTEL_H_ - -#include "xf86drm.h" /* drm_handle_t, etc */ - -/* Intel */ -#ifndef PCI_CHIP_I810 -#define PCI_CHIP_I810 0x7121 -#define PCI_CHIP_I810_DC100 0x7123 -#define PCI_CHIP_I810_E 0x7125 -#define PCI_CHIP_I815 0x1132 -#define PCI_CHIP_I810_BRIDGE 0x7120 -#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 -#define PCI_CHIP_I810_E_BRIDGE 0x7124 -#define PCI_CHIP_I815_BRIDGE 0x1130 -#endif - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 - -#ifndef PCI_CHIP_I855_GM -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I855_GM_BRIDGE 0x3580 -#endif - -#ifndef PCI_CHIP_I865_G -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I865_G_BRIDGE 0x2570 -#endif - -#ifndef PCI_CHIP_I915_G -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I915_GM -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I915_GM_BRIDGE 0x2590 -#endif - -#ifndef PCI_CHIP_E7221_G -#define PCI_CHIP_E7221_G 0x258A -/* Same as I915_G_BRIDGE */ -#define PCI_CHIP_E7221_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I945_G -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_G_BRIDGE 0x2770 -#endif - -#ifndef PCI_CHIP_I945_GM -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 -#endif - -#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \ - pI810->Chipset == PCI_CHIP_I810_DC100 || \ - pI810->Chipset == PCI_CHIP_I810_E) -#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815) -#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M) -#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G) -#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM) -#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) -#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) -#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G) - -#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G) -#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM) -#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G) -#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM) -#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) - -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) - -#define I830_GMCH_CTRL 0x52 - -#define I830_GMCH_MEM_MASK 0x1 -#define I830_GMCH_MEM_64M 0x1 -#define I830_GMCH_MEM_128M 0 - -#define I830_GMCH_GMS_MASK 0x70 -#define I830_GMCH_GMS_DISABLED 0x00 -#define I830_GMCH_GMS_LOCAL 0x10 -#define I830_GMCH_GMS_STOLEN_512 0x20 -#define I830_GMCH_GMS_STOLEN_1024 0x30 -#define I830_GMCH_GMS_STOLEN_8192 0x40 - -#define I855_GMCH_GMS_MASK (0x7 << 4) -#define I855_GMCH_GMS_DISABLED 0x00 -#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) -#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) -#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) -#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) -#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) -#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) -#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) - -typedef unsigned char Bool; -#define TRUE 1 -#define FALSE 0 - -#define PIPE_NONE 0<<0 -#define PIPE_CRT 1<<0 -#define PIPE_TV 1<<1 -#define PIPE_DFP 1<<2 -#define PIPE_LFP 1<<3 -#define PIPE_CRT2 1<<4 -#define PIPE_TV2 1<<5 -#define PIPE_DFP2 1<<6 -#define PIPE_LFP2 1<<7 - -typedef struct _I830MemPool *I830MemPoolPtr; -typedef struct _I830MemRange *I830MemRangePtr; -typedef struct _I830MemRange { - long Start; - long End; - long Size; - unsigned long Physical; - unsigned long Offset; /* Offset of AGP-allocated portion */ - unsigned long Alignment; - drm_handle_t Key; - unsigned long Pitch; // add pitch - I830MemPoolPtr Pool; -} I830MemRange; - -typedef struct _I830MemPool { - I830MemRange Total; - I830MemRange Free; - I830MemRange Fixed; - I830MemRange Allocated; -} I830MemPool; - -typedef struct { - int tail_mask; - I830MemRange mem; - unsigned char *virtual_start; - int head; - int tail; - int space; -} I830RingBuffer; - -typedef struct _I830Rec { - unsigned char *MMIOBase; - unsigned char *FbBase; - int cpp; - uint32_t aper_size; - unsigned int bios_version; - - /* These are set in PreInit and never changed. */ - long FbMapSize; - long TotalVideoRam; - I830MemRange StolenMemory; /* pre-allocated memory */ - long BIOSMemorySize; /* min stolen pool size */ - int BIOSMemSizeLoc; - - /* These change according to what has been allocated. */ - long FreeMemory; - I830MemRange MemoryAperture; - I830MemPool StolenPool; - long allocatedMemory; - - /* Regions allocated either from the above pools, or from agpgart. */ - /* for single and dual head configurations */ - I830MemRange FrontBuffer; - I830MemRange FrontBuffer2; - I830MemRange Scratch; - I830MemRange Scratch2; - - I830RingBuffer *LpRing; - - I830MemRange BackBuffer; - I830MemRange DepthBuffer; - I830MemRange TexMem; - int TexGranularity; - I830MemRange ContextMem; - int drmMinor; - Bool have3DWindows; - - Bool NeedRingBufferLow; - Bool allowPageFlip; - Bool disableTiling; - - int Chipset; - unsigned long LinearAddr; - unsigned long MMIOAddr; - - drmSize registerSize; /**< \brief MMIO register map size */ - drm_handle_t registerHandle; /**< \brief MMIO register map handle */ - // IOADDRESS ioBase; - int irq; /**< \brief IRQ number */ - int GttBound; - - drm_handle_t ring_map; - unsigned int Fence[8]; - -} I830Rec; - -/* - * 12288 is set as the maximum, chosen because it is enough for - * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. - */ -#define I830_MAXIMUM_VBIOS_MEM 12288 -#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024) -#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024) - -/* Flags for memory allocation function */ -#define FROM_ANYWHERE 0x00000000 -#define FROM_POOL_ONLY 0x00000001 -#define FROM_NEW_ONLY 0x00000002 -#define FROM_MASK 0x0000000f - -#define ALLOCATE_AT_TOP 0x00000010 -#define ALLOCATE_AT_BOTTOM 0x00000020 -#define FORCE_GAPS 0x00000040 - -#define NEED_PHYSICAL_ADDR 0x00000100 -#define ALIGN_BOTH_ENDS 0x00000200 -#define FORCE_LOW 0x00000400 - -#define ALLOC_NO_TILING 0x00001000 -#define ALLOC_INITIAL 0x00002000 - -#define ALLOCATE_DRY_RUN 0x80000000 - -/* Chipset registers for VIDEO BIOS memory RW access */ -#define _855_DRAM_RW_CONTROL 0x58 -#define _845_DRAM_RW_CONTROL 0x90 -#define DRAM_WRITE 0x33330000 - -#define KB(x) ((x) * 1024) -#define MB(x) ((x) * KB(1024)) - -#define GTT_PAGE_SIZE KB(4) -#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) -#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) -#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) -#define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) -#define PRIMARY_RINGBUFFER_SIZE KB(128) - - -/* Ring buffer registers, p277, overview p19 - */ -#define LP_RING 0x2030 -#define HP_RING 0x2040 - -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x000FFFF8 -#define I830_TAIL_MASK 0x001FFFF8 - -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define I830_HEAD_MASK 0x001FFFFC - -#define RING_START 0x08 -#define START_ADDR 0x03FFFFF8 -#define I830_RING_START_MASK 0xFFFFF000 - -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x001FF000 -#define I830_RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - - -/* Fence/Tiling ranges [0..7] - */ -#define FENCE 0x2000 -#define FENCE_NR 8 - -#define I915G_FENCE_START_MASK 0x0ff00000 - -#define I830_FENCE_START_MASK 0x07f80000 - -#define FENCE_START_MASK 0x03F80000 -#define FENCE_X_MAJOR 0x00000000 -#define FENCE_Y_MAJOR 0x00001000 -#define FENCE_SIZE_MASK 0x00000700 -#define FENCE_SIZE_512K 0x00000000 -#define FENCE_SIZE_1M 0x00000100 -#define FENCE_SIZE_2M 0x00000200 -#define FENCE_SIZE_4M 0x00000300 -#define FENCE_SIZE_8M 0x00000400 -#define FENCE_SIZE_16M 0x00000500 -#define FENCE_SIZE_32M 0x00000600 -#define FENCE_SIZE_64M 0x00000700 -#define I915G_FENCE_SIZE_1M 0x00000000 -#define I915G_FENCE_SIZE_2M 0x00000100 -#define I915G_FENCE_SIZE_4M 0x00000200 -#define I915G_FENCE_SIZE_8M 0x00000300 -#define I915G_FENCE_SIZE_16M 0x00000400 -#define I915G_FENCE_SIZE_32M 0x00000500 -#define I915G_FENCE_SIZE_64M 0x00000600 -#define I915G_FENCE_SIZE_128M 0x00000700 -#define FENCE_PITCH_1 0x00000000 -#define FENCE_PITCH_2 0x00000010 -#define FENCE_PITCH_4 0x00000020 -#define FENCE_PITCH_8 0x00000030 -#define FENCE_PITCH_16 0x00000040 -#define FENCE_PITCH_32 0x00000050 -#define FENCE_PITCH_64 0x00000060 -#define FENCE_VALID 0x00000001 - -#include - -# define MMIO_IN8(base, offset) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) -# define MMIO_IN32(base, offset) \ - read_MMIO_LE32(base, offset) -# define MMIO_OUT8(base, offset, val) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) -# define MMIO_OUT32(base, offset, val) \ - *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val) - - - /* Memory mapped register access macros */ -#define INREG8(addr) MMIO_IN8(MMIO, addr) -#define INREG(addr) MMIO_IN32(MMIO, addr) -#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val) -#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val) - -#define DSPABASE 0x70184 - -#endif diff --git a/src/gallium/winsys/dri/intel/server/intel_dri.c b/src/gallium/winsys/dri/intel/server/intel_dri.c deleted file mode 100644 index e49c4214ad..0000000000 --- a/src/gallium/winsys/dri/intel/server/intel_dri.c +++ /dev/null @@ -1,1306 +0,0 @@ -/** - * \file server/intel_dri.c - * \brief File to perform the device-specific initialization tasks typically - * done in the X server. - * - * Here they are converted to run in the client (or perhaps a standalone - * process), and to work with the frame buffer device rather than the X - * server infrastructure. - * - * Copyright (C) 2006 Dave Airlie (airlied@linux.ie) - - 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 THE COPYRIGHT HOLDERS AND/OR THEIR 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 -#include -#include -#include -#include - -#include "driver.h" -#include "drm.h" - -#include "intel.h" -#include "i830_dri.h" - -#include "memops.h" -#include "pciaccess.h" - -static size_t drm_page_size; -static int nextTile = 0; -#define xf86DrvMsg(...) do {} while(0) - -static const int pitches[] = { - 128 * 8, - 128 * 16, - 128 * 32, - 128 * 64, - 0 -}; - -static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea); - -static unsigned long -GetBestTileAlignment(unsigned long size) -{ - unsigned long i; - - for (i = KB(512); i < size; i <<= 1) - ; - - if (i > MB(64)) - i = MB(64); - - return i; -} - -static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - unsigned char *MMIO = ctx->MMIOAddress; - - for (i = 0; i < 8; i++) { - OUTREG(FENCE + i * 4, pI830->Fence[i]); - // if (I810_DEBUG & DEBUG_VERBOSE_VGA) - fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]); - } -} - -/* Tiled memory is good... really, really good... - * - * Need to make it less likely that we miss out on this - probably - * need to move the frontbuffer away from the 'guarenteed' alignment - * of the first memory segment, or perhaps allocate a discontigous - * framebuffer to get more alignment 'sweet spots'. - */ -static void -SetFence(const DRIDriverContext *ctx, I830Rec *pI830, - int nr, unsigned int start, unsigned int pitch, - unsigned int size) -{ - unsigned int val; - unsigned int fence_mask = 0; - unsigned int fence_pitch; - - if (nr < 0 || nr > 7) { - fprintf(stderr, - "SetFence: fence %d out of range\n",nr); - return; - } - - pI830->Fence[nr] = 0; - - if (IS_I9XX(pI830)) - fence_mask = ~I915G_FENCE_START_MASK; - else - fence_mask = ~I830_FENCE_START_MASK; - - if (start & fence_mask) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not %s aligned\n", - nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); - return; - } - - if (start % size) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", - nr, start, size / 1024); - return; - } - - if (pitch & 127) { - fprintf(stderr, - "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", - nr, pitch); - return; - } - - val = (start | FENCE_X_MAJOR | FENCE_VALID); - - if (IS_I9XX(pI830)) { - switch (size) { - case MB(1): - val |= I915G_FENCE_SIZE_1M; - break; - case MB(2): - val |= I915G_FENCE_SIZE_2M; - break; - case MB(4): - val |= I915G_FENCE_SIZE_4M; - break; - case MB(8): - val |= I915G_FENCE_SIZE_8M; - break; - case MB(16): - val |= I915G_FENCE_SIZE_16M; - break; - case MB(32): - val |= I915G_FENCE_SIZE_32M; - break; - case MB(64): - val |= I915G_FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } else { - switch (size) { - case KB(512): - val |= FENCE_SIZE_512K; - break; - case MB(1): - val |= FENCE_SIZE_1M; - break; - case MB(2): - val |= FENCE_SIZE_2M; - break; - case MB(4): - val |= FENCE_SIZE_4M; - break; - case MB(8): - val |= FENCE_SIZE_8M; - break; - case MB(16): - val |= FENCE_SIZE_16M; - break; - case MB(32): - val |= FENCE_SIZE_32M; - break; - case MB(64): - val |= FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } - - if (IS_I9XX(pI830)) - fence_pitch = pitch / 512; - else - fence_pitch = pitch / 128; - - switch (fence_pitch) { - case 1: - val |= FENCE_PITCH_1; - break; - case 2: - val |= FENCE_PITCH_2; - break; - case 4: - val |= FENCE_PITCH_4; - break; - case 8: - val |= FENCE_PITCH_8; - break; - case 16: - val |= FENCE_PITCH_16; - break; - case 32: - val |= FENCE_PITCH_32; - break; - case 64: - val |= FENCE_PITCH_64; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal pitch (%d)\n", nr, pitch); - return; - } - - pI830->Fence[nr] = val; -} - -static Bool -MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem) -{ - int pitch, ntiles, i; - - pitch = pMem->Pitch * ctx->cpp; - /* - * Simply try to break the region up into at most four pieces of size - * equal to the alignment. - */ - ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; - if (ntiles >= 4) { - return FALSE; - } - - for (i = 0; i < ntiles; i++, nextTile++) { - SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment, - pitch, pMem->Alignment); - } - return TRUE; -} - -static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - - /* Clear out */ - for (i = 0; i < 8; i++) - pI830->Fence[i] = 0; - - nextTile = 0; - - if (pI830->BackBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) { - fprintf(stderr, - "Activating tiled memory for the back buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the back buffer.\n"); - pI830->allowPageFlip = FALSE; - } - } - - if (pI830->DepthBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) { - fprintf(stderr, - "Activating tiled memory for the depth buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the depth buffer.\n"); - } - } - - return; -} - -static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - struct pci_device host_bridge, ig_dev; - uint32_t gmch_ctrl; - int memsize = 0; - int range; - uint32_t aper_size; - uint32_t membase2 = 0; - - memset(&host_bridge, 0, sizeof(host_bridge)); - memset(&ig_dev, 0, sizeof(ig_dev)); - - ig_dev.dev = 2; - - pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL); - - if (IS_I830(pI830) || IS_845G(pI830)) { - if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { - aper_size = 0x80000000; - } else { - aper_size = 0x40000000; - } - } else { - if (IS_I9XX(pI830)) { - int ret; - ret = pci_device_cfg_read_u32(&ig_dev, &membase2, 0x18); - if (membase2 & 0x08000000) - aper_size = 0x8000000; - else - aper_size = 0x10000000; - - fprintf(stderr,"aper size is %08X %08x %d\n", aper_size, membase2, ret); - } else - aper_size = 0x8000000; - } - - pI830->aper_size = aper_size; - - - /* We need to reduce the stolen size, by the GTT and the popup. - * The GTT varying according the the FbMapSize and the popup is 4KB */ - range = (ctx->shared.fbSize / (1024*1024)) + 4; - - if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I855_GMCH_GMS_STOLEN_1M: - memsize = MB(1) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_4M: - memsize = MB(4) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_8M: - memsize = MB(8) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_16M: - memsize = MB(16) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_32M: - memsize = MB(32) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_48M: - if (IS_I9XX(pI830)) - memsize = MB(48) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_64M: - if (IS_I9XX(pI830)) - memsize = MB(64) - KB(range); - break; - } - } else { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I830_GMCH_GMS_STOLEN_512: - memsize = KB(512) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_1024: - memsize = MB(1) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_8192: - memsize = MB(8) - KB(range); - break; - case I830_GMCH_GMS_LOCAL: - memsize = 0; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Local memory found, but won't be used.\n"); - break; - } - } - if (memsize > 0) { - fprintf(stderr, - "detected %d kB stolen memory.\n", memsize / 1024); - } else { - fprintf(stderr, - "no video memory detected.\n"); - } - return memsize; -} - -static int AgpInit(const DRIDriverContext *ctx, I830Rec *info) -{ - unsigned long mode = 0x4; - - if (drmAgpAcquire(ctx->drmFD) < 0) { - fprintf(stderr, "[gart] AGP not available\n"); - return 0; - } - - if (drmAgpEnable(ctx->drmFD, mode) < 0) { - fprintf(stderr, "[gart] AGP not enabled\n"); - drmAgpRelease(ctx->drmFD); - return 0; - } - else - fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); - - return 1; -} - -/* - * Allocate memory from the given pool. Grow the pool if needed and if - * possible. - */ -static unsigned long -AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830, - I830MemRange *result, I830MemPool *pool, - long size, unsigned long alignment, int flags) -{ - long needed, start, end; - - if (!result || !pool || !size) - return 0; - - /* Calculate how much space is needed. */ - if (alignment <= GTT_PAGE_SIZE) - needed = size; - else { - start = ROUND_TO(pool->Free.Start, alignment); - end = ROUND_TO(start + size, alignment); - needed = end - pool->Free.Start; - } - if (needed > pool->Free.Size) { - return 0; - } - - result->Start = ROUND_TO(pool->Free.Start, alignment); - pool->Free.Start += needed; - result->End = pool->Free.Start; - - pool->Free.Size = pool->Free.End - pool->Free.Start; - result->Size = result->End - result->Start; - result->Pool = pool; - result->Alignment = alignment; - return needed; -} - -static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result) -{ - unsigned long start, end; - unsigned long newApStart, newApEnd; - int ret; - if (!result || !size) - return 0; - - if (!alignment) - alignment = 4; - - start = ROUND_TO(pI830->MemoryAperture.Start, alignment); - end = ROUND_TO(start + size, alignment); - newApStart = end; - newApEnd = pI830->MemoryAperture.End; - - ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key)); - - if (ret) - { - fprintf(stderr,"drmAgpAlloc failed %d\n", ret); - return 0; - } - pI830->allocatedMemory += size; - pI830->MemoryAperture.Start = newApStart; - pI830->MemoryAperture.End = newApEnd; - pI830->MemoryAperture.Size = newApEnd - newApStart; - // pI830->FreeMemory -= size; - result->Start = start; - result->End = start + size; - result->Size = size; - result->Offset = start; - result->Alignment = alignment; - result->Pool = NULL; - - return size; -} - -unsigned long -I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, - I830MemRange *result, I830MemPool *pool, long size, - unsigned long alignment, int flags) -{ - unsigned long ret; - - if (!result) - return 0; - - /* Make sure these are initialised. */ - result->Size = 0; - result->Key = -1; - - if (!size) { - return 0; - } - - if (pool->Free.Size < size) { - ret = AllocFromAGP(ctx, pI830, size, alignment, result); - } - else { - ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags); - if (ret == 0) - ret = AllocFromAGP(ctx, pI830, size, alignment, result); - } - return ret; -} - -static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem) -{ - if (!mem) - return FALSE; - - if (mem->Key == -1) - return TRUE; - - return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset); -} - -/* simple memory allocation routines needed */ -/* put ring buffer in low memory */ -/* need to allocate front, back, depth buffers aligned correctly, - allocate ring buffer, -*/ - -/* */ -static Bool -I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned long size, ret; - unsigned long lines, lineSize, align; - - /* allocate ring buffer */ - memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); - pI830->LpRing->mem.Key = -1; - - size = PRIMARY_RINGBUFFER_SIZE; - - ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0); - - if (ret != size) - { - fprintf(stderr,"unable to allocate ring buffer %ld\n", ret); - return FALSE; - } - - pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; - - - /* allocate front buffer */ - memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); - pI830->FrontBuffer.Key = -1; - pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth; - - align = KB(512); - - lineSize = ctx->shared.virtualWidth * ctx->cpp; - lines = (ctx->shared.virtualHeight + 15) / 16 * 16; - size = lineSize * lines; - size = ROUND_TO_PAGE(size); - - align = GetBestTileAlignment(size); - - ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate front buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); - pI830->BackBuffer.Key = -1; - pI830->BackBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate back buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); - pI830->DepthBuffer.Key = -1; - pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate depth buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); - pI830->ContextMem.Key = -1; - size = KB(32); - - ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate context buffer %ld\n", ret); - return FALSE; - } - -#if 0 - memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); - pI830->TexMem.Key = -1; - - size = 32768 * 1024; - ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem); - if (ret < size) - { - fprintf(stderr,"unable to allocate texture memory %ld\n", ret); - return FALSE; - } -#endif - - return TRUE; -} - -static Bool -I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - if (!BindAgpRange(ctx, &pI830->LpRing->mem)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->FrontBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->BackBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->DepthBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->ContextMem)) - return FALSE; -#if 0 - if (!BindAgpRange(ctx, &pI830->TexMem)) - return FALSE; -#endif - return TRUE; -} - -static void SetupDRIMM(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned long aperEnd = ROUND_DOWN_TO(pI830->aper_size, GTT_PAGE_SIZE) / GTT_PAGE_SIZE; - unsigned long aperStart = ROUND_TO(pI830->aper_size - KB(32768), GTT_PAGE_SIZE) / GTT_PAGE_SIZE; - - fprintf(stderr, "aper size is %08X\n", ctx->shared.fbSize); - if (drmMMInit(ctx->drmFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) { - fprintf(stderr, - "DRM MM Initialization Failed\n"); - } else { - fprintf(stderr, - "DRM MM Initialized at offset 0x%lx length %d page\n", aperStart, aperEnd-aperStart); - } - -} - -static Bool -I830CleanupDma(const DRIDriverContext *ctx) -{ - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_CLEANUP_DMA; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, "I830 Dma Cleanup Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830) -{ - I830RingBuffer *ring = pI830->LpRing; - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_INIT_DMA; - - info.ring_start = ring->mem.Start + pI830->LinearAddr; - info.ring_end = ring->mem.End + pI830->LinearAddr; - info.ring_size = ring->mem.Size; - - info.mmio_offset = (unsigned int)ctx->MMIOStart; - - info.sarea_priv_offset = sizeof(drm_sarea_t); - - info.front_offset = pI830->FrontBuffer.Start; - info.back_offset = pI830->BackBuffer.Start; - info.depth_offset = pI830->DepthBuffer.Start; - info.w = ctx->shared.virtualWidth; - info.h = ctx->shared.virtualHeight; - info.pitch = ctx->shared.virtualWidth; - info.back_pitch = pI830->BackBuffer.Pitch; - info.depth_pitch = pI830->DepthBuffer.Pitch; - info.cpp = ctx->cpp; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, - "I830 Dma Initialization Failed\n"); - return FALSE; - } - - return TRUE; -} - -static int I830CheckDRMVersion( const DRIDriverContext *ctx, - I830Rec *pI830 ) -{ - drmVersionPtr version; - - version = drmGetVersion(ctx->drmFD); - - if (version) { - int req_minor, req_patch; - - req_minor = 4; - req_patch = 0; - - if (version->version_major != 1 || - version->version_minor < req_minor || - (version->version_minor == req_minor && - version->version_patchlevel < req_patch)) { - /* Incompatible drm version */ - fprintf(stderr, - "[dri] I830DRIScreenInit failed because of a version " - "mismatch.\n" - "[dri] i915.o kernel module version is %d.%d.%d " - "but version 1.%d.%d or newer is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel, - req_minor, - req_patch); - drmFreeVersion(version); - return 0; - } - - pI830->drmMinor = version->version_minor; - drmFreeVersion(version); - } - return 1; -} - -static void -I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned int itemp; - unsigned char *MMIO = ctx->MMIOAddress; - - OUTREG(LP_RING + RING_LEN, 0); - OUTREG(LP_RING + RING_TAIL, 0); - OUTREG(LP_RING + RING_HEAD, 0); - - if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != - pI830->LpRing->mem.Start) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer start (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; - OUTREG(LP_RING + RING_START, itemp); - - if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != - pI830->LpRing->mem.Size - 4096) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Size - 4096, - I830_RING_NR_PAGES); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; - itemp |= (RING_NO_REPORT | RING_VALID); - OUTREG(LP_RING + RING_LEN, itemp); - - pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; - pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); - pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); - if (pI830->LpRing->space < 0) - pI830->LpRing->space += pI830->LpRing->mem.Size; - - SetFenceRegs(ctx, pI830); - - /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky - hacky hacky */ - OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr); - -} - -static Bool -I830SetParam(const DRIDriverContext *ctx, int param, int value) -{ - drmI830SetParam sp; - - memset(&sp, 0, sizeof(sp)); - sp.param = param; - sp.value = value; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { - fprintf(stderr, "I830 SetParam Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - fprintf(stderr, - "[drm] Mapping front buffer\n"); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), - sarea->front_size, - DRM_FRAME_BUFFER, /*DRM_AGP,*/ - 0, - &sarea->front_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); - return FALSE; - } - ctx->shared.hFrameBuffer = sarea->front_handle; - ctx->shared.fbSize = sarea->front_size; - fprintf(stderr, "[drm] Front Buffer = 0x%08x\n", - sarea->front_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->back_offset), - sarea->back_size, DRM_AGP, 0, - &sarea->back_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Back Buffer = 0x%08x\n", - sarea->back_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->depth_offset, - sarea->depth_size, DRM_AGP, 0, - &sarea->depth_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n", - sarea->depth_handle); - -#if 0 - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->tex_offset, - sarea->tex_size, DRM_AGP, 0, - &sarea->tex_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] textures = 0x%08x\n", - sarea->tex_handle); -#endif - return TRUE; -} - - -static void -I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ -#if 1 - if (sarea->front_handle) { - drmRmMap(ctx->drmFD, sarea->front_handle); - sarea->front_handle = 0; - } -#endif - if (sarea->back_handle) { - drmRmMap(ctx->drmFD, sarea->back_handle); - sarea->back_handle = 0; - } - if (sarea->depth_handle) { - drmRmMap(ctx->drmFD, sarea->depth_handle); - sarea->depth_handle = 0; - } - if (sarea->tex_handle) { - drmRmMap(ctx->drmFD, sarea->tex_handle); - sarea->tex_handle = 0; - } -} - -static Bool -I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - if (drmAddMap(ctx->drmFD, - (drm_handle_t)pI830->LpRing->mem.Start, - pI830->LpRing->mem.Size, DRM_AGP, 0, - &pI830->ring_map) < 0) { - fprintf(stderr, - "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] ring buffer = 0x%08x\n", - pI830->ring_map); - - if (I830InitDma(ctx, pI830) == FALSE) { - return FALSE; - } - - /* init to zero to be safe */ - - I830DRIMapScreenRegions(ctx, pI830, sarea); - SetupDRIMM(ctx, pI830); - - if (ctx->pciDevice != PCI_CHIP_845_G && - ctx->pciDevice != PCI_CHIP_I830_M) { - I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); - } - - /* Okay now initialize the dma engine */ - { - pI830->irq = drmGetInterruptFromBusID(ctx->drmFD, - ctx->pciBus, - ctx->pciDevice, - ctx->pciFunc); - - if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) { - fprintf(stderr, - "[drm] failure adding irq handler\n"); - pI830->irq = 0; - return FALSE; - } - else - fprintf(stderr, - "[drm] dma control initialized, using IRQ %d\n", - pI830->irq); - } - - fprintf(stderr, "[dri] visual configs initialized\n"); - - return TRUE; -} - -static Bool -I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - /* need to drmMap front and back buffers and zero them */ - drmAddress map_addr; - int ret; - - ret = drmMap(ctx->drmFD, - sarea->front_handle, - sarea->front_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map front buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->front_size); - drmUnmap(map_addr, sarea->front_size); - - - ret = drmMap(ctx->drmFD, - sarea->back_handle, - sarea->back_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map back buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->back_size); - drmUnmap(map_addr, sarea->back_size); - - return TRUE; -} - -static Bool -I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830) - -{ - I830DRIPtr pI830DRI; - drmI830Sarea *pSAREAPriv; - int err; - - drm_page_size = getpagesize(); - - pI830->registerSize = ctx->MMIOSize; - /* This is a hack for now. We have to have more than a 4k page here - * because of the size of the state. However, the state should be - * in a per-context mapping. This will be added in the Mesa 3.5 port - * of the I830 driver. - */ - ctx->shared.SAREASize = SAREA_MAX; - - /* Note that drmOpen will try to load the kernel module, if needed. */ - ctx->drmFD = drmOpen("i915", NULL ); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - if (drmAddMap( ctx->drmFD, - 0, - ctx->shared.SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &ctx->shared.hSAREA) < 0) - { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap( ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - - } - - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - - if (drmAddMap(ctx->drmFD, - ctx->MMIOStart, - ctx->MMIOSize, - DRM_REGISTERS, - DRM_READ_ONLY, - &pI830->registerHandle) < 0) { - fprintf(stderr, "[drm] drmAddMap mmio failed\n"); - return 0; - } - fprintf(stderr, - "[drm] register handle = 0x%08x\n", pI830->registerHandle); - - - if (!I830CheckDRMVersion(ctx, pI830)) { - return FALSE; - } - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - /* Initialize the SAREA private data structure */ - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - - pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830); - pI830->StolenMemory.Start = 0; - pI830->StolenMemory.End = pI830->StolenMemory.Size; - - pI830->MemoryAperture.Start = pI830->StolenMemory.End; - pI830->MemoryAperture.End = KB(40000); - pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; - - pI830->StolenPool.Fixed = pI830->StolenMemory; - pI830->StolenPool.Total = pI830->StolenMemory; - pI830->StolenPool.Free = pI830->StolenPool.Total; - pI830->FreeMemory = pI830->StolenPool.Total.Size; - - if (!AgpInit(ctx, pI830)) - return FALSE; - - if (I830AllocateMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - if (I830BindMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - pSAREAPriv->rotated_offset = -1; - pSAREAPriv->rotated_size = 0; - pSAREAPriv->rotated_pitch = ctx->shared.virtualWidth; - - pSAREAPriv->front_offset = pI830->FrontBuffer.Start; - pSAREAPriv->front_size = pI830->FrontBuffer.Size; - pSAREAPriv->width = ctx->shared.virtualWidth; - pSAREAPriv->height = ctx->shared.virtualHeight; - pSAREAPriv->pitch = ctx->shared.virtualWidth; - pSAREAPriv->virtualX = ctx->shared.virtualWidth; - pSAREAPriv->virtualY = ctx->shared.virtualHeight; - pSAREAPriv->back_offset = pI830->BackBuffer.Start; - pSAREAPriv->back_size = pI830->BackBuffer.Size; - pSAREAPriv->depth_offset = pI830->DepthBuffer.Start; - pSAREAPriv->depth_size = pI830->DepthBuffer.Size; -#if 0 - pSAREAPriv->tex_offset = pI830->TexMem.Start; - pSAREAPriv->tex_size = pI830->TexMem.Size; -#endif - pSAREAPriv->log_tex_granularity = pI830->TexGranularity; - - ctx->driverClientMsg = malloc(sizeof(I830DRIRec)); - ctx->driverClientMsgSize = sizeof(I830DRIRec); - pI830DRI = (I830DRIPtr)ctx->driverClientMsg; - pI830DRI->deviceID = pI830->Chipset; - pI830DRI->regsSize = I830_REG_SIZE; - pI830DRI->width = ctx->shared.virtualWidth; - pI830DRI->height = ctx->shared.virtualHeight; - pI830DRI->mem = ctx->shared.fbSize; - pI830DRI->cpp = ctx->cpp; - - pI830DRI->bitsPerPixel = ctx->bpp; - pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t); - - err = I830DRIDoMappings(ctx, pI830, pSAREAPriv); - if (err == FALSE) - return FALSE; - - I830SetupMemoryTiling(ctx, pI830); - - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - I830ClearScreen(ctx, pI830, pSAREAPriv); - - I830SetRingRegs(ctx, pI830); - - return TRUE; -} - - -/** - * \brief Validate the fbdev mode. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Saves some registers and returns 1. - * - * \sa radeonValidateMode(). - */ -static int i830ValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - -/** - * \brief Examine mode returned by fbdev. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Restores registers that fbdev has clobbered and returns 1. - * - * \sa i810ValidateMode(). - */ -static int i830PostValidateMode( const DRIDriverContext *ctx ) -{ - I830Rec *pI830 = ctx->driverPrivate; - - I830SetRingRegs(ctx, pI830); - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p ctx - * and then calls I810ScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int i830InitFBDev( DRIDriverContext *ctx ) -{ - I830Rec *pI830 = calloc(1, sizeof(I830Rec)); - int i; - - { - int dummy = ctx->shared.virtualWidth; - - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; - } - - ctx->shared.virtualWidth = dummy; - ctx->shared.Width = ctx->shared.virtualWidth; - } - - - for (i = 0; pitches[i] != 0; i++) { - if (pitches[i] >= ctx->shared.virtualWidth) { - ctx->shared.virtualWidth = pitches[i]; - break; - } - } - - ctx->driverPrivate = (void *)pI830; - - pI830->LpRing = calloc(1, sizeof(I830RingBuffer)); - pI830->Chipset = ctx->chipset; - pI830->LinearAddr = ctx->FBStart; - - if (!I830ScreenInit( ctx, pI830 )) - return 0; - - - return 1; -} - - -/** - * \brief The screen is being closed, so clean up any state and free any - * resources used by the DRI. - * - * \param ctx display handle. - * - * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver - * private data. - */ -static void i830HaltFBDev( DRIDriverContext *ctx ) -{ - drmI830Sarea *pSAREAPriv; - I830Rec *pI830 = ctx->driverPrivate; - - if (pI830->irq) { - drmCtlUninstHandler(ctx->drmFD); - pI830->irq = 0; } - - I830CleanupDma(ctx); - - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - - I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv); - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = 0; - } -} - - -extern void i810NotifyFocus( int ); - -/** - * \brief Exported driver interface for Mini GLX. - * - * \sa DRIDriverRec. - */ -const struct DRIDriverRec __driDriver = { - i830ValidateMode, - i830PostValidateMode, - i830InitFBDev, - i830HaltFBDev, - NULL,//I830EngineShutdown, - NULL, //I830EngineRestore, -#ifndef _EMBEDDED - 0, -#else - i810NotifyFocus, -#endif -}; diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c deleted file mode 100644 index 1bc1089352..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c +++ /dev/null @@ -1,953 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - * Keith Whitwell - */ - -#include -#include -#include "glthread.h" -#include "errno.h" -#include "ws_dri_bufmgr.h" -#include "string.h" -#include "imports.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" - -/* - * This lock is here to protect drmBO structs changing underneath us during a - * validate list call, since validatelist cannot take individiual locks for - * each drmBO. Validatelist takes this lock in write mode. Any access to an - * individual drmBO should take this lock in read mode, since in that case, the - * driBufferObject mutex will protect the access. Locking order is - * driBufferObject mutex - > this rw lock. - */ - -_glthread_DECLARE_STATIC_MUTEX(bmMutex); -_glthread_DECLARE_STATIC_COND(bmCond); - -static int kernelReaders = 0; -static int num_buffers = 0; -static int num_user_buffers = 0; - -static drmBO *drmBOListBuf(void *iterator) -{ - drmBONode *node; - drmMMListHead *l = (drmMMListHead *) iterator; - node = DRMLISTENTRY(drmBONode, l, head); - return node->buf; -} - -static void *drmBOListIterator(drmBOList *list) -{ - void *ret = list->list.next; - - if (ret == &list->list) - return NULL; - return ret; -} - -static void *drmBOListNext(drmBOList *list, void *iterator) -{ - void *ret; - - drmMMListHead *l = (drmMMListHead *) iterator; - ret = l->next; - if (ret == &list->list) - return NULL; - return ret; -} - -static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, - uint64_t arg0, - uint64_t arg1) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->free.next; - if (l == &list->free) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - return NULL; - } - list->numCurrent++; - } - else { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - } - node->buf = item; - node->arg0 = arg0; - node->arg1 = arg1; - DRMLISTADD(&node->head, &list->list); - list->numOnList++; - return node; -} - -static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, - uint64_t mask, int *newItem) -{ - drmBONode *node, *cur; - drmMMListHead *l; - - *newItem = 0; - cur = NULL; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - if (node->buf == buf) { - cur = node; - break; - } - } - if (!cur) { - cur = drmAddListItem(list, buf, flags, mask); - if (!cur) { - return -ENOMEM; - } - *newItem = 1; - cur->arg0 = flags; - cur->arg1 = mask; - } - else { - uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; - uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; - - if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { - return -EINVAL; - } - - cur->arg1 |= mask; - cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); - - if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && - (cur->arg0 & DRM_BO_MASK_MEM) == 0) { - return -EINVAL; - } - } - return 0; -} - -static void drmBOFreeList(drmBOList *list) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->list.next; - while(l != &list->list) { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - l = list->list.next; - list->numCurrent--; - list->numOnList--; - } - - l = list->free.next; - while(l != &list->free) { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - l = list->free.next; - list->numCurrent--; - } -} - -static int drmAdjustListNodes(drmBOList *list) -{ - drmBONode *node; - drmMMListHead *l; - int ret = 0; - - while(list->numCurrent < list->numTarget) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - ret = -ENOMEM; - break; - } - list->numCurrent++; - DRMLISTADD(&node->head, &list->free); - } - - while(list->numCurrent > list->numTarget) { - l = list->free.next; - if (l == &list->free) - break; - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - list->numCurrent--; - } - return ret; -} - -static int drmBOCreateList(int numTarget, drmBOList *list) -{ - DRMINITLISTHEAD(&list->list); - DRMINITLISTHEAD(&list->free); - list->numTarget = numTarget; - list->numCurrent = 0; - list->numOnList = 0; - return drmAdjustListNodes(list); -} - -static int drmBOResetList(drmBOList *list) -{ - drmMMListHead *l; - int ret; - - ret = drmAdjustListNodes(list); - if (ret) - return ret; - - l = list->list.next; - while (l != &list->list) { - DRMLISTDEL(l); - DRMLISTADD(l, &list->free); - list->numOnList--; - l = list->list.next; - } - return drmAdjustListNodes(list); -} - -void driWriteLockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - while(kernelReaders != 0) - _glthread_COND_WAIT(bmCond, bmMutex); -} - -void driWriteUnlockKernelBO(void) -{ - _glthread_UNLOCK_MUTEX(bmMutex); -} - -void driReadLockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - kernelReaders++; - _glthread_UNLOCK_MUTEX(bmMutex); -} - -void driReadUnlockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - if (--kernelReaders == 0) - _glthread_COND_BROADCAST(bmCond); - _glthread_UNLOCK_MUTEX(bmMutex); -} - - - - -/* - * TODO: Introduce fence pools in the same way as - * buffer object pools. - */ - -typedef struct _DriBufferObject -{ - DriBufferPool *pool; - _glthread_Mutex mutex; - int refCount; - const char *name; - uint64_t flags; - unsigned hint; - unsigned alignment; - unsigned createdByReference; - void *private; - /* user-space buffer: */ - unsigned userBuffer; - void *userData; - unsigned userSize; -} DriBufferObject; - -typedef struct _DriBufferList { - drmBOList drmBuffers; /* List of kernel buffers needing validation */ - drmBOList driBuffers; /* List of user-space buffers needing validation */ -} DriBufferList; - - -void -bmError(int val, const char *file, const char *function, int line) -{ - _mesa_printf("Fatal video memory manager error \"%s\".\n" - "Check kernel logs or set the LIBGL_DEBUG\n" - "environment variable to \"verbose\" for more info.\n" - "Detected in file %s, line %d, function %s.\n", - strerror(-val), file, line, function); -#ifndef NDEBUG - abort(); -#else - abort(); -#endif -} - -extern drmBO * -driBOKernel(struct _DriBufferObject *buf) -{ - drmBO *ret; - - driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); - assert(buf->private != NULL); - ret = buf->pool->kernel(buf->pool, buf->private); - if (!ret) - BM_CKFATAL(-EINVAL); - _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); - - return ret; -} - -void -driBOWaitIdle(struct _DriBufferObject *buf, int lazy) -{ - - /* - * This function may block. Is it sane to keep the mutex held during - * that time?? - */ - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void * -driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) -{ - void *virtual; - int retval; - - if (buf->userBuffer) { - return buf->userData; - } - - _glthread_LOCK_MUTEX(buf->mutex); - assert(buf->private != NULL); - retval = buf->pool->map(buf->pool, buf->private, flags, hint, - &buf->mutex, &virtual); - _glthread_UNLOCK_MUTEX(buf->mutex); - - return retval == 0 ? virtual : NULL; -} - -void -driBOUnmap(struct _DriBufferObject *buf) -{ - if (buf->userBuffer) - return; - - assert(buf->private != NULL); - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -unsigned long -driBOOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->offset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -unsigned long -driBOPoolOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->poolOffset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -uint64_t -driBOFlags(struct _DriBufferObject *buf) -{ - uint64_t ret; - - assert(buf->private != NULL); - - driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->flags(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); - return ret; -} - -struct _DriBufferObject * -driBOReference(struct _DriBufferObject *buf) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (++buf->refCount == 1) { - _glthread_UNLOCK_MUTEX(buf->mutex); - BM_CKFATAL(-EINVAL); - } - _glthread_UNLOCK_MUTEX(buf->mutex); - return buf; -} - -void -driBOUnReference(struct _DriBufferObject *buf) -{ - int tmp; - - if (!buf) - return; - - _glthread_LOCK_MUTEX(buf->mutex); - tmp = --buf->refCount; - if (!tmp) { - _glthread_UNLOCK_MUTEX(buf->mutex); - if (buf->private) { - if (buf->createdByReference) - buf->pool->unreference(buf->pool, buf->private); - else - buf->pool->destroy(buf->pool, buf->private); - } - if (buf->userBuffer) - num_user_buffers--; - else - num_buffers--; - free(buf); - } else - _glthread_UNLOCK_MUTEX(buf->mutex); - -} - - -int -driBOData(struct _DriBufferObject *buf, - unsigned size, const void *data, - DriBufferPool *newPool, - uint64_t flags) -{ - void *virtual = NULL; - int newBuffer; - int retval = 0; - struct _DriBufferPool *pool; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - pool = buf->pool; - - if (pool == NULL && newPool != NULL) { - buf->pool = newPool; - pool = newPool; - } - if (newPool == NULL) - newPool = pool; - - if (!pool->create) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "driBOData called on invalid buffer\n"); - BM_CKFATAL(-EINVAL); - } - - newBuffer = (!buf->private || pool != newPool || - pool->size(pool, buf->private) < size); - - if (!flags) - flags = buf->flags; - - if (newBuffer) { - - if (buf->createdByReference) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "driBOData requiring resizing called on " - "shared buffer.\n"); - BM_CKFATAL(-EINVAL); - } - - if (buf->private) - buf->pool->destroy(buf->pool, buf->private); - - pool = newPool; - buf->pool = newPool; - buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, - buf->alignment); - if (!buf->private) - retval = -ENOMEM; - - if (retval == 0) - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); - } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { - /* - * Buffer is busy. need to create a new one. - */ - - void *newBuf; - - newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, - buf->alignment); - if (newBuf) { - buf->pool->destroy(buf->pool, buf->private); - buf->private = newBuf; - } - - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } else { - uint64_t flag_diff = flags ^ buf->flags; - - /* - * We might need to change buffer flags. - */ - - if (flag_diff){ - assert(pool->setStatus != NULL); - BM_CKFATAL(pool->unmap(pool, buf->private)); - BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, - buf->flags)); - if (!data) - goto out; - - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } - } - - if (retval == 0) { - if (data) - memcpy(virtual, data, size); - - BM_CKFATAL(pool->unmap(pool, buf->private)); - } - - out: - _glthread_UNLOCK_MUTEX(buf->mutex); - - return retval; -} - -void -driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, const void *data) -{ - void *virtual; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, - &virtual)); - memcpy((unsigned char *) virtual + offset, data, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, void *data) -{ - void *virtual; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); - memcpy(data, (unsigned char *) virtual + offset, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOSetReferenced(struct _DriBufferObject *buf, - unsigned long handle) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->private != NULL) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "Invalid buffer for setReferenced\n"); - BM_CKFATAL(-EINVAL); - - } - if (buf->pool->reference == NULL) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "Invalid buffer pool for setReferenced\n"); - BM_CKFATAL(-EINVAL); - } - buf->private = buf->pool->reference(buf->pool, handle); - if (!buf->private) { - _mesa_error(NULL, GL_OUT_OF_MEMORY, - "Invalid buffer pool for setStatic\n"); - BM_CKFATAL(-ENOMEM); - } - buf->createdByReference = GL_TRUE; - buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -int -driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, uint64_t flags, unsigned hint) -{ - struct _DriBufferObject *buf; - int i; - - flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - - ++num_buffers; - - assert(pool); - - for (i = 0; i < n; ++i) { - buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); - if (!buf) - return -ENOMEM; - - _glthread_INIT_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(buf->mutex); - buf->refCount = 1; - buf->flags = flags; - buf->hint = hint; - buf->name = name; - buf->alignment = alignment; - buf->pool = pool; - buf->createdByReference = 0; - _glthread_UNLOCK_MUTEX(buf->mutex); - buffers[i] = buf; - } - return 0; -} - -void -driGenUserBuffer(struct _DriBufferPool *pool, - const char *name, - struct _DriBufferObject **buffers, - void *ptr, unsigned bytes) -{ - const unsigned alignment = 1, flags = 0, hint = 0; - - --num_buffers; /* JB: is inced in GenBuffes */ - driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); - ++num_user_buffers; - - (*buffers)->userBuffer = 1; - (*buffers)->userData = ptr; - (*buffers)->userSize = bytes; -} - -void -driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) -{ - int i; - - for (i = 0; i < n; ++i) { - driBOUnReference(buffers[i]); - } -} - - -void -driInitBufMgr(int fd) -{ - ; -} - -/* - * Note that lists are per-context and don't need mutex protection. - */ - -struct _DriBufferList * -driBOCreateList(int target) -{ - struct _DriBufferList *list = calloc(sizeof(*list), 1); - - BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); - BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); - return list; -} - -int -driBOResetList(struct _DriBufferList * list) -{ - int ret; - ret = drmBOResetList(&list->drmBuffers); - if (ret) - return ret; - ret = drmBOResetList(&list->driBuffers); - return ret; -} - -void -driBOFreeList(struct _DriBufferList * list) -{ - drmBOFreeList(&list->drmBuffers); - drmBOFreeList(&list->driBuffers); - free(list); -} - - -/* - * Copied from libdrm, because it is needed by driAddValidateItem. - */ - -static drmBONode * -driAddListItem(drmBOList * list, drmBO * item, - uint64_t arg0, uint64_t arg1) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->free.next; - if (l == &list->free) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - return NULL; - } - list->numCurrent++; - } else { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - } - memset(&node->bo_arg, 0, sizeof(node->bo_arg)); - node->buf = item; - node->arg0 = arg0; - node->arg1 = arg1; - DRMLISTADDTAIL(&node->head, &list->list); - list->numOnList++; - return node; -} - -/* - * Slightly modified version compared to the libdrm version. - * This one returns the list index of the buffer put on the list. - */ - -static int -driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, - uint64_t mask, int *itemLoc, - struct _drmBONode **pnode) -{ - drmBONode *node, *cur; - drmMMListHead *l; - int count = 0; - - cur = NULL; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - if (node->buf == buf) { - cur = node; - break; - } - count++; - } - if (!cur) { - cur = driAddListItem(list, buf, flags, mask); - if (!cur) - return -ENOMEM; - - cur->arg0 = flags; - cur->arg1 = mask; - } else { - uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; - uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; - - if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { - return -EINVAL; - } - - cur->arg1 |= mask; - cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); - - if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && - (cur->arg0 & DRM_BO_MASK_MEM) == 0) { - return -EINVAL; - } - } - *itemLoc = count; - *pnode = cur; - return 0; -} - - -void -driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, - uint64_t flags, uint64_t mask, int *itemLoc, - struct _drmBONode **node) -{ - int newItem; - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(driAddValidateItem(&list->drmBuffers, - buf->pool->kernel(buf->pool, buf->private), - flags, mask, itemLoc, node)); - BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, - flags, mask, &newItem)); - if (newItem) - buf->refCount++; - - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -drmBOList *driGetdrmBOList(struct _DriBufferList *list) -{ - driWriteLockKernelBO(); - return &list->drmBuffers; -} - -void driPutdrmBOList(struct _DriBufferList *list) -{ - driWriteUnlockKernelBO(); -} - - -void -driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->pool->fence) - BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); - _glthread_UNLOCK_MUTEX(buf->mutex); - -} - -void -driBOUnrefUserList(struct _DriBufferList *list) -{ - struct _DriBufferObject *buf; - void *curBuf; - - curBuf = drmBOListIterator(&list->driBuffers); - while (curBuf) { - buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); - driBOUnReference(buf); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } -} - -struct _DriFenceObject * -driBOFenceUserList(struct _DriFenceMgr *mgr, - struct _DriBufferList *list, const char *name, - drmFence *kFence) -{ - struct _DriFenceObject *fence; - struct _DriBufferObject *buf; - void *curBuf; - - fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, - kFence, sizeof(*kFence)); - curBuf = drmBOListIterator(&list->driBuffers); - - /* - * User-space fencing callbacks. - */ - - while (curBuf) { - buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - driBOFence(buf, fence); - driBOUnReference(buf); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } - - driBOResetList(list); - return fence; -} - -void -driBOValidateUserList(struct _DriBufferList * list) -{ - void *curBuf; - struct _DriBufferObject *buf; - - curBuf = drmBOListIterator(&list->driBuffers); - - /* - * User-space validation callbacks. - */ - - while (curBuf) { - buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->pool->validate) - BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); - _glthread_UNLOCK_MUTEX(buf->mutex); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } -} - - -void -driPoolTakeDown(struct _DriBufferPool *pool) -{ - pool->takeDown(pool); - -} - -unsigned long -driBOSize(struct _DriBufferObject *buf) -{ - unsigned long size; - - _glthread_LOCK_MUTEX(buf->mutex); - size = buf->pool->size(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - - return size; - -} - -drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) -{ - return &list->drmBuffers; -} - -drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) -{ - return &list->driBuffers; -} - diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h deleted file mode 100644 index fdaf5ee93a..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - * Keith Whitwell - */ - -#ifndef _PSB_BUFMGR_H_ -#define _PSB_BUFMGR_H_ -#include -#include "i915_drm.h" -#include "ws_dri_fencemgr.h" - -typedef struct _drmBONode -{ - drmMMListHead head; - drmBO *buf; - struct drm_i915_op_arg bo_arg; - uint64_t arg0; - uint64_t arg1; -} drmBONode; - -typedef struct _drmBOList { - unsigned numTarget; - unsigned numCurrent; - unsigned numOnList; - drmMMListHead list; - drmMMListHead free; -} drmBOList; - - -struct _DriFenceObject; -struct _DriBufferObject; -struct _DriBufferPool; -struct _DriBufferList; - -/* - * Return a pointer to the libdrm buffer object this DriBufferObject - * uses. - */ - -extern drmBO *driBOKernel(struct _DriBufferObject *buf); -extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, - unsigned hint); -extern void driBOUnmap(struct _DriBufferObject *buf); -extern unsigned long driBOOffset(struct _DriBufferObject *buf); -extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); - -extern uint64_t driBOFlags(struct _DriBufferObject *buf); -extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); -extern void driBOUnReference(struct _DriBufferObject *buf); - -extern int driBOData(struct _DriBufferObject *r_buf, - unsigned size, const void *data, - struct _DriBufferPool *pool, uint64_t flags); - -extern void driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - const void *data); -extern void driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - void *data); -extern int driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, uint64_t flags, unsigned hint); -extern void driGenUserBuffer(struct _DriBufferPool *pool, - const char *name, - struct _DriBufferObject *buffers[], - void *ptr, unsigned bytes); -extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); -extern void driInitBufMgr(int fd); -extern struct _DriBufferList *driBOCreateList(int target); -extern int driBOResetList(struct _DriBufferList * list); -extern void driBOAddListItem(struct _DriBufferList * list, - struct _DriBufferObject *buf, - uint64_t flags, uint64_t mask, int *itemLoc, - struct _drmBONode **node); - -extern void driBOValidateList(int fd, struct _DriBufferList * list); -extern void driBOFreeList(struct _DriBufferList * list); -extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, - struct _DriBufferList *list, - const char *name, - drmFence *kFence); -extern void driBOUnrefUserList(struct _DriBufferList *list); -extern void driBOValidateUserList(struct _DriBufferList * list); -extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); -extern void driPutdrmBOList(struct _DriBufferList *list); - -extern void driBOFence(struct _DriBufferObject *buf, - struct _DriFenceObject *fence); - -extern void driPoolTakeDown(struct _DriBufferPool *pool); -extern void driBOSetReferenced(struct _DriBufferObject *buf, - unsigned long handle); -unsigned long driBOSize(struct _DriBufferObject *buf); -extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); -extern void driPoolTakeDown(struct _DriBufferPool *pool); - -extern void driReadLockKernelBO(void); -extern void driReadUnlockKernelBO(void); -extern void driWriteLockKernelBO(void); -extern void driWriteUnlockKernelBO(void); - -/* - * For debugging purposes. - */ - -extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); -extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); -#endif diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufpool.h b/src/gallium/winsys/dri/intel/ws_dri_bufpool.h deleted file mode 100644 index 3a302e13d3..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_bufpool.h +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - */ - -#ifndef _PSB_BUFPOOL_H_ -#define _PSB_BUFPOOL_H_ - -#include -#include -struct _DriFenceObject; - -typedef struct _DriBufferPool -{ - int fd; - int (*map) (struct _DriBufferPool * pool, void *private, - unsigned flags, int hint, _glthread_Mutex *mutex, - void **virtual); - int (*unmap) (struct _DriBufferPool * pool, void *private); - int (*destroy) (struct _DriBufferPool * pool, void *private); - unsigned long (*offset) (struct _DriBufferPool * pool, void *private); - unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); - uint64_t (*flags) (struct _DriBufferPool * pool, void *private); - unsigned long (*size) (struct _DriBufferPool * pool, void *private); - void *(*create) (struct _DriBufferPool * pool, unsigned long size, - uint64_t flags, unsigned hint, unsigned alignment); - void *(*reference) (struct _DriBufferPool * pool, unsigned handle); - int (*unreference) (struct _DriBufferPool * pool, void *private); - int (*fence) (struct _DriBufferPool * pool, void *private, - struct _DriFenceObject * fence); - drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); - int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); - int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, - int lazy); - int (*setStatus) (struct _DriBufferPool *pool, void *private, - uint64_t flag_diff, uint64_t old_flags); - void (*takeDown) (struct _DriBufferPool * pool); - void *data; -} DriBufferPool; - -extern void bmError(int val, const char *file, const char *function, - int line); -#define BM_CKFATAL(val) \ - do{ \ - int tstVal = (val); \ - if (tstVal) \ - bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ - } while(0); - - -/* - * Builtin pools. - */ - -/* - * Kernel buffer objects. Size in multiples of page size. Page size aligned. - */ - -extern struct _DriBufferPool *driDRMPoolInit(int fd); -extern struct _DriBufferPool *driMallocPoolInit(void); - -struct _DriFreeSlabManager; -extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, - uint64_t validMask, - uint32_t smallestSize, - uint32_t numSizes, - uint32_t desiredNumBuffers, - uint32_t maxSlabSize, - uint32_t pageAlignment, - struct _DriFreeSlabManager *fMan); -extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); -extern struct _DriFreeSlabManager * -driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); - - -#endif diff --git a/src/gallium/winsys/dri/intel/ws_dri_drmpool.c b/src/gallium/winsys/dri/intel/ws_dri_drmpool.c deleted file mode 100644 index 7c55dbc674..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_drmpool.c +++ /dev/null @@ -1,268 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - */ - -#include -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" -#include "assert.h" - -/* - * Buffer pool implementation using DRM buffer objects as DRI buffer objects. - */ - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, uint64_t flags, unsigned hint, - unsigned alignment) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - unsigned pageSize = getpagesize(); - - if (!buf) - return NULL; - - if ((alignment > pageSize) && (alignment % pageSize)) { - free(buf); - return NULL; - } - - ret = drmBOCreate(pool->fd, size, alignment / pageSize, - NULL, - flags, hint, buf); - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static void * -pool_reference(struct _DriBufferPool *pool, unsigned handle) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - - if (!buf) - return NULL; - - ret = drmBOReference(pool->fd, handle, buf); - - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); - ret = drmBOUnreference(pool->fd, buf); - free(buf); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_unreference(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); - ret = drmBOUnreference(pool->fd, buf); - free(buf); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOMap(pool->fd, buf, flags, hint, virtual); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOUnmap(pool->fd, buf); - driReadUnlockKernelBO(); - - return ret; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - unsigned long offset; - - driReadLockKernelBO(); - assert(buf->flags & DRM_BO_FLAG_NO_MOVE); - offset = buf->offset; - driReadUnlockKernelBO(); - - return buf->offset; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - return 0; -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - uint64_t flags; - - driReadLockKernelBO(); - flags = buf->flags; - driReadUnlockKernelBO(); - - return flags; -} - - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - unsigned long size; - - driReadLockKernelBO(); - size = buf->size; - driReadUnlockKernelBO(); - - return buf->size; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - /* - * Noop. The kernel handles all fencing. - */ - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - return (drmBO *) private; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, - int lazy) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); - driReadUnlockKernelBO(); - - return ret; -} - - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - -/*static int -pool_setStatus(struct _DriBufferPool *pool, void *private, - uint64_t flag_diff, uint64_t old_flags) -{ - drmBO *buf = (drmBO *) private; - uint64_t new_flags = old_flags ^ flag_diff; - int ret; - - driReadLockKernelBO(); - ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, - 0, 0, 0); - driReadUnlockKernelBO(); - return ret; -}*/ - -struct _DriBufferPool * -driDRMPoolInit(int fd) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - - if (!pool) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->poolOffset = &pool_poolOffset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - pool->reference = &pool_reference; - pool->unreference = &pool_unreference; - pool->data = NULL; - return pool; -} diff --git a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c deleted file mode 100644 index 1f893b47ce..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c +++ /dev/null @@ -1,377 +0,0 @@ -#include "ws_dri_fencemgr.h" -#include "glthread.h" -#include -#include -#include - -/* - * Note: Locking order is - * _DriFenceObject::mutex - * _DriFenceMgr::mutex - */ - -struct _DriFenceMgr { - /* - * Constant members. Need no mutex protection. - */ - struct _DriFenceMgrCreateInfo info; - void *private; - - /* - * These members are protected by this->mutex - */ - _glthread_Mutex mutex; - int refCount; - drmMMListHead *heads; - int num_fences; -}; - -struct _DriFenceObject { - - /* - * These members are constant and need no mutex protection. - */ - struct _DriFenceMgr *mgr; - uint32_t fence_class; - uint32_t fence_type; - - /* - * These members are protected by mgr->mutex. - */ - drmMMListHead head; - int refCount; - - /* - * These members are protected by this->mutex. - */ - _glthread_Mutex mutex; - uint32_t signaled_type; - void *private; -}; - -uint32_t -driFenceType(struct _DriFenceObject *fence) -{ - return fence->fence_type; -} - -struct _DriFenceMgr * -driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) -{ - struct _DriFenceMgr *tmp; - uint32_t i; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return NULL; - - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); - tmp->refCount = 1; - tmp->info = *info; - tmp->num_fences = 0; - tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); - if (!tmp->heads) - goto out_err; - - for (i=0; iinfo.num_classes; ++i) { - DRMINITLISTHEAD(&tmp->heads[i]); - } - _glthread_UNLOCK_MUTEX(tmp->mutex); - return tmp; - - out_err: - if (tmp) - free(tmp); - return NULL; -} - -static void -driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) -{ - struct _DriFenceMgr *mgr = *pMgr; - - *pMgr = NULL; - if (--mgr->refCount == 0) - free(mgr); - else - _glthread_UNLOCK_MUTEX(mgr->mutex); -} - -void -driFenceMgrUnReference(struct _DriFenceMgr **pMgr) -{ - _glthread_LOCK_MUTEX((*pMgr)->mutex); - driFenceMgrUnrefUnlock(pMgr); -} - -static void -driFenceUnReferenceLocked(struct _DriFenceObject **pFence) -{ - struct _DriFenceObject *fence = *pFence; - struct _DriFenceMgr *mgr = fence->mgr; - - *pFence = NULL; - if (--fence->refCount == 0) { - DRMLISTDELINIT(&fence->head); - if (fence->private) - mgr->info.unreference(mgr, &fence->private); - --mgr->num_fences; - fence->mgr = NULL; - --mgr->refCount; - free(fence); - - } -} - - -static void -driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, - drmMMListHead *list, - uint32_t fence_class, - uint32_t fence_type) -{ - struct _DriFenceObject *entry; - drmMMListHead *prev; - - while(list != &mgr->heads[fence_class]) { - entry = DRMLISTENTRY(struct _DriFenceObject, list, head); - - /* - * Up refcount so that entry doesn't disappear from under us - * when we unlock-relock mgr to get the correct locking order. - */ - - ++entry->refCount; - _glthread_UNLOCK_MUTEX(mgr->mutex); - _glthread_LOCK_MUTEX(entry->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); - - prev = list->prev; - - - - if (list->prev == list) { - - /* - * Somebody else removed the entry from the list. - */ - - _glthread_UNLOCK_MUTEX(entry->mutex); - driFenceUnReferenceLocked(&entry); - return; - } - - entry->signaled_type |= (fence_type & entry->fence_type); - if (entry->signaled_type == entry->fence_type) { - DRMLISTDELINIT(list); - mgr->info.unreference(mgr, &entry->private); - } - _glthread_UNLOCK_MUTEX(entry->mutex); - driFenceUnReferenceLocked(&entry); - list = prev; - } -} - - -int -driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, - int lazy_hint) -{ - struct _DriFenceMgr *mgr = fence->mgr; - int ret = 0; - - _glthread_LOCK_MUTEX(fence->mutex); - - if ((fence->signaled_type & fence_type) == fence_type) - goto out0; - - ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); - if (ret) - goto out0; - - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); - - driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, - fence_type); - _glthread_UNLOCK_MUTEX(mgr->mutex); - return 0; - - out0: - _glthread_UNLOCK_MUTEX(fence->mutex); - return ret; -} - -uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) -{ - uint32_t ret; - - _glthread_LOCK_MUTEX(fence->mutex); - ret = fence->signaled_type; - _glthread_UNLOCK_MUTEX(fence->mutex); - - return ret; -} - -int -driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, - uint32_t *signaled) -{ - int ret = 0; - struct _DriFenceMgr *mgr; - - _glthread_LOCK_MUTEX(fence->mutex); - mgr = fence->mgr; - *signaled = fence->signaled_type; - if ((fence->signaled_type & flush_type) == flush_type) - goto out0; - - ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); - if (ret) { - *signaled = fence->signaled_type; - goto out0; - } - - if ((fence->signaled_type | *signaled) == fence->signaled_type) - goto out0; - - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); - - driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, - *signaled); - - _glthread_UNLOCK_MUTEX(mgr->mutex); - return 0; - out0: - _glthread_UNLOCK_MUTEX(fence->mutex); - return ret; -} - -struct _DriFenceObject * -driFenceReference(struct _DriFenceObject *fence) -{ - _glthread_LOCK_MUTEX(fence->mgr->mutex); - ++fence->refCount; - _glthread_UNLOCK_MUTEX(fence->mgr->mutex); - return fence; -} - -void -driFenceUnReference(struct _DriFenceObject **pFence) -{ - struct _DriFenceMgr *mgr; - - if (*pFence == NULL) - return; - - mgr = (*pFence)->mgr; - _glthread_LOCK_MUTEX(mgr->mutex); - ++mgr->refCount; - driFenceUnReferenceLocked(pFence); - driFenceMgrUnrefUnlock(&mgr); -} - -struct _DriFenceObject -*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, - uint32_t fence_type, void *private, size_t private_size) -{ - struct _DriFenceObject *fence; - size_t fence_size = sizeof(*fence); - - if (private_size) - fence_size = ((fence_size + 15) & ~15); - - fence = calloc(1, fence_size + private_size); - - if (!fence) { - int ret = mgr->info.finish(mgr, private, fence_type, 0); - - if (ret) - usleep(10000000); - - return NULL; - } - - _glthread_INIT_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); - fence->refCount = 1; - DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); - fence->mgr = mgr; - ++mgr->refCount; - ++mgr->num_fences; - _glthread_UNLOCK_MUTEX(mgr->mutex); - fence->fence_class = fence_class; - fence->fence_type = fence_type; - fence->signaled_type = 0; - fence->private = private; - if (private_size) { - fence->private = (void *)(((uint8_t *) fence) + fence_size); - memcpy(fence->private, private, private_size); - } - - _glthread_UNLOCK_MUTEX(fence->mutex); - return fence; -} - - -static int -tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, - uint32_t *signaled_type) -{ - long fd = (long) mgr->private; - int dummy; - drmFence *fence = (drmFence *) private; - int ret; - - *signaled_type = 0; - ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); - if (ret) - return ret; - - *signaled_type = fence->signaled; - - return 0; -} - -static int -tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, - int lazy_hint) -{ - long fd = (long) mgr->private; - unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; - - return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); -} - -static int -tUnref(struct _DriFenceMgr *mgr, void **private) -{ - long fd = (long) mgr->private; - drmFence *fence = (drmFence *) *private; - *private = NULL; - - return drmFenceUnreference(fd, fence); -} - -struct _DriFenceMgr *driFenceMgrTTMInit(int fd) -{ - struct _DriFenceMgrCreateInfo info; - struct _DriFenceMgr *mgr; - - info.flags = DRI_FENCE_CLASS_ORDERED; - info.num_classes = 4; - info.signaled = tSignaled; - info.finish = tFinish; - info.unreference = tUnref; - - mgr = driFenceMgrCreate(&info); - if (mgr == NULL) - return NULL; - - mgr->private = (void *) (long) fd; - return mgr; -} - diff --git a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h deleted file mode 100644 index 4ea58dfe18..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef DRI_FENCEMGR_H -#define DRI_FENCEMGR_H - -#include -#include - -struct _DriFenceObject; -struct _DriFenceMgr; - -/* - * Do a quick check to see if the fence manager has registered the fence - * object as signaled. Note that this function may return a false negative - * answer. - */ -extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); - -/* - * Check if the fence object is signaled. This function can be substantially - * more expensive to call than the above function, but will not return a false - * negative answer. The argument "flush_type" sets the types that the - * underlying mechanism must make sure will eventually signal. - */ -extern int driFenceSignaledType(struct _DriFenceObject *fence, - uint32_t flush_type, uint32_t *signaled); - -/* - * Convenience functions. - */ - -static inline int driFenceSignaled(struct _DriFenceObject *fence, - uint32_t flush_type) -{ - uint32_t signaled_types; - int ret = driFenceSignaledType(fence, flush_type, &signaled_types); - if (ret) - return 0; - return ((signaled_types & flush_type) == flush_type); -} - -static inline int driFenceSignaledCached(struct _DriFenceObject *fence, - uint32_t flush_type) -{ - uint32_t signaled_types = - driFenceSignaledTypeCached(fence); - - return ((signaled_types & flush_type) == flush_type); -} - -/* - * Reference a fence object. - */ -extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); - -/* - * Unreference a fence object. The fence object pointer will be reset to NULL. - */ - -extern void driFenceUnReference(struct _DriFenceObject **pFence); - - -/* - * Wait for a fence to signal the indicated fence_type. - * If "lazy_hint" is true, it indicates that the wait may sleep to avoid - * busy-wait polling. - */ -extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, - int lazy_hint); - -/* - * Create a DriFenceObject for manager "mgr". - * - * "private" is a pointer that should be used for the callbacks in - * struct _DriFenceMgrCreateInfo. - * - * if private_size is nonzero, then the info stored at *private, with size - * private size will be copied and the fence manager will instead use a - * pointer to the copied data for the callbacks in - * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by - * "private" may be destroyed after the call to driFenceCreate. - */ -extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, - uint32_t fence_class, - uint32_t fence_type, - void *private, - size_t private_size); - -extern uint32_t driFenceType(struct _DriFenceObject *fence); - -/* - * Fence creations are ordered. If a fence signals a fence_type, - * it is safe to assume that all fences of the same class that was - * created before that fence has signaled the same type. - */ - -#define DRI_FENCE_CLASS_ORDERED (1 << 0) - -struct _DriFenceMgrCreateInfo { - uint32_t flags; - uint32_t num_classes; - int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, - uint32_t *signaled_type); - int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); - int (*unreference) (struct _DriFenceMgr *mgr, void **private); -}; - -extern struct _DriFenceMgr * -driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); - -void -driFenceMgrUnReference(struct _DriFenceMgr **pMgr); - -extern struct _DriFenceMgr * -driFenceMgrTTMInit(int fd); - -#endif diff --git a/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c b/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c deleted file mode 100644 index bf97d7e440..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c +++ /dev/null @@ -1,162 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - */ - -#include -#include -#include -#include "imports.h" -#include "glthread.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" -#include "intel_screen.h" - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, uint64_t flags, unsigned hint, - unsigned alignment) -{ - unsigned long *private = malloc(size + 2*sizeof(unsigned long)); - if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) - abort(); - - *private = size; - return (void *)private; -} - - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - free(private); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex, int lazy) -{ - return 0; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - *virtual = (void *)((unsigned long *)private + 2); - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - /* - * BUG - */ - abort(); - return 0UL; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - /* - * BUG - */ - abort(); -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - return *(unsigned long *) private; -} - - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - abort(); - return 0UL; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - abort(); - return NULL; -} - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - - -struct _DriBufferPool * -driMallocPoolInit(void) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - if (!pool) - return NULL; - - pool->data = NULL; - pool->fd = -1; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->poolOffset = &pool_poolOffset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - return pool; -} diff --git a/src/gallium/winsys/dri/intel/ws_dri_slabpool.c b/src/gallium/winsys/dri/intel/ws_dri_slabpool.c deleted file mode 100644 index 62d82bbd94..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_slabpool.c +++ /dev/null @@ -1,968 +0,0 @@ -/************************************************************************** - * - * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#include -#include -#include -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" -#include "ws_dri_bufmgr.h" -#include "glthread.h" - -#define DRI_SLABPOOL_ALLOC_RETRIES 100 - -struct _DriSlab; - -struct _DriSlabBuffer { - int isSlabBuffer; - drmBO *bo; - struct _DriFenceObject *fence; - struct _DriSlab *parent; - drmMMListHead head; - uint32_t mapCount; - uint32_t start; - uint32_t fenceType; - int unFenced; - _glthread_Cond event; -}; - -struct _DriKernelBO { - int fd; - drmBO bo; - drmMMListHead timeoutHead; - drmMMListHead head; - struct timeval timeFreed; - uint32_t pageAlignment; - void *virtual; -}; - -struct _DriSlab{ - drmMMListHead head; - drmMMListHead freeBuffers; - uint32_t numBuffers; - uint32_t numFree; - struct _DriSlabBuffer *buffers; - struct _DriSlabSizeHeader *header; - struct _DriKernelBO *kbo; -}; - - -struct _DriSlabSizeHeader { - drmMMListHead slabs; - drmMMListHead freeSlabs; - drmMMListHead delayedBuffers; - uint32_t numDelayed; - struct _DriSlabPool *slabPool; - uint32_t bufSize; - _glthread_Mutex mutex; -}; - -struct _DriFreeSlabManager { - struct timeval slabTimeout; - struct timeval checkInterval; - struct timeval nextCheck; - drmMMListHead timeoutList; - drmMMListHead unCached; - drmMMListHead cached; - _glthread_Mutex mutex; -}; - - -struct _DriSlabPool { - - /* - * The data of this structure remains constant after - * initialization and thus needs no mutex protection. - */ - - struct _DriFreeSlabManager *fMan; - uint64_t proposedFlags; - uint64_t validMask; - uint32_t *bucketSizes; - uint32_t numBuckets; - uint32_t pageSize; - int fd; - int pageAlignment; - int maxSlabSize; - int desiredNumBuffers; - struct _DriSlabSizeHeader *headers; -}; - -/* - * FIXME: Perhaps arrange timeout slabs in size buckets for fast - * retreival?? - */ - - -static inline int -driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) -{ - return ((arg1->tv_sec > arg2->tv_sec) || - ((arg1->tv_sec == arg2->tv_sec) && - (arg1->tv_usec > arg2->tv_usec))); -} - -static inline void -driTimeAdd(struct timeval *arg, struct timeval *add) -{ - unsigned int sec; - - arg->tv_sec += add->tv_sec; - arg->tv_usec += add->tv_usec; - sec = arg->tv_usec / 1000000; - arg->tv_sec += sec; - arg->tv_usec -= sec*1000000; -} - -static void -driFreeKernelBO(struct _DriKernelBO *kbo) -{ - if (!kbo) - return; - - (void) drmBOUnreference(kbo->fd, &kbo->bo); - free(kbo); -} - - -static void -driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, - struct timeval *time) -{ - drmMMListHead *list, *next; - struct _DriKernelBO *kbo; - - if (!driTimeAfterEq(time, &fMan->nextCheck)) - return; - - for (list = fMan->timeoutList.next, next = list->next; - list != &fMan->timeoutList; - list = next, next = list->next) { - - kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); - - if (!driTimeAfterEq(time, &kbo->timeFreed)) - break; - - DRMLISTDELINIT(&kbo->timeoutHead); - DRMLISTDELINIT(&kbo->head); - driFreeKernelBO(kbo); - } - - fMan->nextCheck = *time; - driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); -} - - -/* - * Add a _DriKernelBO to the free slab manager. - * This means that it is available for reuse, but if it's not - * reused in a while, it will be freed. - */ - -static void -driSetKernelBOFree(struct _DriFreeSlabManager *fMan, - struct _DriKernelBO *kbo) -{ - struct timeval time; - - _glthread_LOCK_MUTEX(fMan->mutex); - gettimeofday(&time, NULL); - driTimeAdd(&time, &fMan->slabTimeout); - - kbo->timeFreed = time; - - if (kbo->bo.flags & DRM_BO_FLAG_CACHED) - DRMLISTADD(&kbo->head, &fMan->cached); - else - DRMLISTADD(&kbo->head, &fMan->unCached); - - DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); - driFreeTimeoutKBOsLocked(fMan, &time); - - _glthread_UNLOCK_MUTEX(fMan->mutex); -} - -/* - * Get a _DriKernelBO for us to use as storage for a slab. - * - */ - -static struct _DriKernelBO * -driAllocKernelBO(struct _DriSlabSizeHeader *header) - -{ - struct _DriSlabPool *slabPool = header->slabPool; - struct _DriFreeSlabManager *fMan = slabPool->fMan; - drmMMListHead *list, *next, *head; - uint32_t size = header->bufSize * slabPool->desiredNumBuffers; - struct _DriKernelBO *kbo; - struct _DriKernelBO *kboTmp; - int ret; - - /* - * FIXME: We should perhaps allow some variation in slabsize in order - * to efficiently reuse slabs. - */ - - size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; - size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); - _glthread_LOCK_MUTEX(fMan->mutex); - - kbo = NULL; - - retry: - head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? - &fMan->cached : &fMan->unCached; - - for (list = head->next, next = list->next; - list != head; - list = next, next = list->next) { - - kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); - - if ((kboTmp->bo.size == size) && - (slabPool->pageAlignment == 0 || - (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { - - if (!kbo) - kbo = kboTmp; - - if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) - break; - - } - } - - if (kbo) { - DRMLISTDELINIT(&kbo->head); - DRMLISTDELINIT(&kbo->timeoutHead); - } - - _glthread_UNLOCK_MUTEX(fMan->mutex); - - if (kbo) { - uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; - - ret = 0; - if (new_mask) { - ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, - new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); - } - if (ret == 0) - return kbo; - - driFreeKernelBO(kbo); - kbo = NULL; - goto retry; - } - - kbo = calloc(1, sizeof(struct _DriKernelBO)); - if (!kbo) - return NULL; - - kbo->fd = slabPool->fd; - DRMINITLISTHEAD(&kbo->head); - DRMINITLISTHEAD(&kbo->timeoutHead); - ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, - slabPool->proposedFlags, - DRM_BO_HINT_DONT_FENCE, &kbo->bo); - if (ret) - goto out_err0; - - ret = drmBOMap(kbo->fd, &kbo->bo, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0, &kbo->virtual); - - if (ret) - goto out_err1; - - ret = drmBOUnmap(kbo->fd, &kbo->bo); - if (ret) - goto out_err1; - - return kbo; - - out_err1: - drmBOUnreference(kbo->fd, &kbo->bo); - out_err0: - free(kbo); - return NULL; -} - - -static int -driAllocSlab(struct _DriSlabSizeHeader *header) -{ - struct _DriSlab *slab; - struct _DriSlabBuffer *buf; - uint32_t numBuffers; - int ret; - int i; - - slab = calloc(1, sizeof(*slab)); - if (!slab) - return -ENOMEM; - - slab->kbo = driAllocKernelBO(header); - if (!slab->kbo) { - ret = -ENOMEM; - goto out_err0; - } - - numBuffers = slab->kbo->bo.size / header->bufSize; - - slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); - if (!slab->buffers) { - ret = -ENOMEM; - goto out_err1; - } - - DRMINITLISTHEAD(&slab->head); - DRMINITLISTHEAD(&slab->freeBuffers); - slab->numBuffers = numBuffers; - slab->numFree = 0; - slab->header = header; - - buf = slab->buffers; - for (i=0; i < numBuffers; ++i) { - buf->parent = slab; - buf->start = i* header->bufSize; - buf->mapCount = 0; - buf->isSlabBuffer = 1; - _glthread_INIT_COND(buf->event); - DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); - slab->numFree++; - buf++; - } - - DRMLISTADDTAIL(&slab->head, &header->slabs); - - return 0; - - out_err1: - driSetKernelBOFree(header->slabPool->fMan, slab->kbo); - free(slab->buffers); - out_err0: - free(slab); - return ret; -} - -/* - * Delete a buffer from the slab header delayed list and put - * it on the slab free list. - */ - -static void -driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) -{ - struct _DriSlab *slab = buf->parent; - struct _DriSlabSizeHeader *header = slab->header; - drmMMListHead *list = &buf->head; - - DRMLISTDEL(list); - DRMLISTADDTAIL(list, &slab->freeBuffers); - slab->numFree++; - - if (slab->head.next == &slab->head) - DRMLISTADDTAIL(&slab->head, &header->slabs); - - if (slab->numFree == slab->numBuffers) { - list = &slab->head; - DRMLISTDEL(list); - DRMLISTADDTAIL(list, &header->freeSlabs); - } - - if (header->slabs.next == &header->slabs || - slab->numFree != slab->numBuffers) { - - drmMMListHead *next; - struct _DriFreeSlabManager *fMan = header->slabPool->fMan; - - for (list = header->freeSlabs.next, next = list->next; - list != &header->freeSlabs; - list = next, next = list->next) { - - slab = DRMLISTENTRY(struct _DriSlab, list, head); - - DRMLISTDELINIT(list); - driSetKernelBOFree(fMan, slab->kbo); - free(slab->buffers); - free(slab); - } - } -} - -static void -driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) -{ - drmMMListHead *list, *prev, *first; - struct _DriSlabBuffer *buf; - struct _DriSlab *slab; - int firstWasSignaled = 1; - int signaled; - int i; - int ret; - - /* - * Rerun the freeing test if the youngest tested buffer - * was signaled, since there might be more idle buffers - * in the delay list. - */ - - while (firstWasSignaled) { - firstWasSignaled = 0; - signaled = 0; - first = header->delayedBuffers.next; - - /* Only examine the oldest 1/3 of delayed buffers: - */ - if (header->numDelayed > 3) { - for (i = 0; i < header->numDelayed; i += 3) { - first = first->next; - } - } - - for (list = first, prev = list->prev; - list != &header->delayedBuffers; - list = prev, prev = list->prev) { - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - slab = buf->parent; - - if (!signaled) { - if (wait) { - ret = driFenceFinish(buf->fence, buf->fenceType, 0); - if (ret) - break; - signaled = 1; - wait = 0; - } else { - signaled = driFenceSignaled(buf->fence, buf->fenceType); - } - if (signaled) { - if (list == first) - firstWasSignaled = 1; - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - } - } -} - - -static struct _DriSlabBuffer * -driSlabAllocBuffer(struct _DriSlabSizeHeader *header) -{ - static struct _DriSlabBuffer *buf; - struct _DriSlab *slab; - drmMMListHead *list; - int count = DRI_SLABPOOL_ALLOC_RETRIES; - - _glthread_LOCK_MUTEX(header->mutex); - while(header->slabs.next == &header->slabs && count > 0) { - driSlabCheckFreeLocked(header, 0); - if (header->slabs.next != &header->slabs) - break; - - _glthread_UNLOCK_MUTEX(header->mutex); - if (count != DRI_SLABPOOL_ALLOC_RETRIES) - usleep(1); - _glthread_LOCK_MUTEX(header->mutex); - (void) driAllocSlab(header); - count--; - } - - list = header->slabs.next; - if (list == &header->slabs) { - _glthread_UNLOCK_MUTEX(header->mutex); - return NULL; - } - slab = DRMLISTENTRY(struct _DriSlab, list, head); - if (--slab->numFree == 0) - DRMLISTDELINIT(list); - - list = slab->freeBuffers.next; - DRMLISTDELINIT(list); - - _glthread_UNLOCK_MUTEX(header->mutex); - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - return buf; -} - -static void * -pool_create(struct _DriBufferPool *driPool, unsigned long size, - uint64_t flags, unsigned hint, unsigned alignment) -{ - struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; - struct _DriSlabSizeHeader *header; - struct _DriSlabBuffer *buf; - void *dummy; - int i; - int ret; - - /* - * FIXME: Check for compatibility. - */ - - header = pool->headers; - for (i=0; inumBuckets; ++i) { - if (header->bufSize >= size) - break; - header++; - } - - if (i < pool->numBuckets) - return driSlabAllocBuffer(header); - - - /* - * Fall back to allocate a buffer object directly from DRM. - * and wrap it in a driBO structure. - */ - - - buf = calloc(1, sizeof(*buf)); - - if (!buf) - return NULL; - - buf->bo = calloc(1, sizeof(*buf->bo)); - if (!buf->bo) - goto out_err0; - - if (alignment) { - if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) - goto out_err1; - if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) - goto out_err1; - } - - ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, - flags, hint, buf->bo); - if (ret) - goto out_err1; - - ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0, &dummy); - if (ret) - goto out_err2; - - ret = drmBOUnmap(pool->fd, buf->bo); - if (ret) - goto out_err2; - - return buf; - out_err2: - drmBOUnreference(pool->fd, buf->bo); - out_err1: - free(buf->bo); - out_err0: - free(buf); - return NULL; -} - -static int -pool_destroy(struct _DriBufferPool *driPool, void *private) -{ - struct _DriSlabBuffer *buf = - (struct _DriSlabBuffer *) private; - struct _DriSlab *slab; - struct _DriSlabSizeHeader *header; - - if (!buf->isSlabBuffer) { - struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; - int ret; - - ret = drmBOUnreference(pool->fd, buf->bo); - free(buf->bo); - free(buf); - return ret; - } - - slab = buf->parent; - header = slab->header; - - _glthread_LOCK_MUTEX(header->mutex); - buf->unFenced = 0; - buf->mapCount = 0; - - if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { - DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); - header->numDelayed++; - } else { - if (buf->fence) - driFenceUnReference(&buf->fence); - driSlabFreeBufferLocked(buf); - } - - _glthread_UNLOCK_MUTEX(header->mutex); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *driPool, void *private, - _glthread_Mutex *mutex, int lazy) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - while(buf->unFenced) - _glthread_COND_WAIT(buf->event, *mutex); - - if (!buf->fence) - return 0; - - driFenceFinish(buf->fence, buf->fenceType, lazy); - driFenceUnReference(&buf->fence); - - return 0; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - int busy; - - if (buf->isSlabBuffer) - busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); - else - busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); - - - if (busy) { - if (hint & DRM_BO_HINT_DONT_BLOCK) - return -EBUSY; - else { - (void) pool_waitIdle(pool, private, mutex, 0); - } - } - - ++buf->mapCount; - *virtual = (buf->isSlabBuffer) ? - (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : - (void *) buf->bo->virtual; - - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - --buf->mapCount; - if (buf->mapCount == 0 && buf->isSlabBuffer) - _glthread_COND_BROADCAST(buf->event); - - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - struct _DriSlab *slab; - struct _DriSlabSizeHeader *header; - - if (!buf->isSlabBuffer) { - assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); - return buf->bo->offset; - } - - slab = buf->parent; - header = slab->header; - - (void) header; - assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); - return slab->kbo->bo.offset + buf->start; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - return buf->start; -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf->isSlabBuffer) - return buf->bo->flags; - - return buf->parent->kbo->bo.flags; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - if (!buf->isSlabBuffer) - return buf->bo->size; - - return buf->parent->header->bufSize; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - drmBO *bo; - - if (buf->fence) - driFenceUnReference(&buf->fence); - - buf->fence = driFenceReference(fence); - bo = (buf->isSlabBuffer) ? - &buf->parent->kbo->bo: - buf->bo; - buf->fenceType = bo->fenceFlags; - - buf->unFenced = 0; - _glthread_COND_BROADCAST(buf->event); - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; -} - -static int -pool_validate(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf->isSlabBuffer) - return 0; - - while(buf->mapCount != 0) - _glthread_COND_WAIT(buf->event, *mutex); - - buf->unFenced = 1; - return 0; -} - - -struct _DriFreeSlabManager * -driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) -{ - struct _DriFreeSlabManager *tmp; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return NULL; - - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); - tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; - tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; - tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; - - tmp->checkInterval.tv_usec = checkIntervalMsec*1000; - tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; - tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; - - gettimeofday(&tmp->nextCheck, NULL); - driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); - DRMINITLISTHEAD(&tmp->timeoutList); - DRMINITLISTHEAD(&tmp->unCached); - DRMINITLISTHEAD(&tmp->cached); - _glthread_UNLOCK_MUTEX(tmp->mutex); - - return tmp; -} - -void -driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) -{ - struct timeval time; - - time = fMan->nextCheck; - driTimeAdd(&time, &fMan->checkInterval); - - _glthread_LOCK_MUTEX(fMan->mutex); - driFreeTimeoutKBOsLocked(fMan, &time); - _glthread_UNLOCK_MUTEX(fMan->mutex); - - assert(fMan->timeoutList.next == &fMan->timeoutList); - assert(fMan->unCached.next == &fMan->unCached); - assert(fMan->cached.next == &fMan->cached); - - free(fMan); -} - -static void -driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, - struct _DriSlabSizeHeader *header) -{ - _glthread_INIT_MUTEX(header->mutex); - _glthread_LOCK_MUTEX(header->mutex); - - DRMINITLISTHEAD(&header->slabs); - DRMINITLISTHEAD(&header->freeSlabs); - DRMINITLISTHEAD(&header->delayedBuffers); - - header->numDelayed = 0; - header->slabPool = pool; - header->bufSize = size; - - _glthread_UNLOCK_MUTEX(header->mutex); -} - -static void -driFinishSizeHeader(struct _DriSlabSizeHeader *header) -{ - drmMMListHead *list, *next; - struct _DriSlabBuffer *buf; - - _glthread_LOCK_MUTEX(header->mutex); - for (list = header->delayedBuffers.next, next = list->next; - list != &header->delayedBuffers; - list = next, next = list->next) { - - buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); - if (buf->fence) { - (void) driFenceFinish(buf->fence, buf->fenceType, 0); - driFenceUnReference(&buf->fence); - } - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - _glthread_UNLOCK_MUTEX(header->mutex); -} - -static void -pool_takedown(struct _DriBufferPool *driPool) -{ - struct _DriSlabPool *pool = driPool->data; - int i; - - for (i=0; inumBuckets; ++i) { - driFinishSizeHeader(&pool->headers[i]); - } - - free(pool->headers); - free(pool->bucketSizes); - free(pool); - free(driPool); -} - -struct _DriBufferPool * -driSlabPoolInit(int fd, uint64_t flags, - uint64_t validMask, - uint32_t smallestSize, - uint32_t numSizes, - uint32_t desiredNumBuffers, - uint32_t maxSlabSize, - uint32_t pageAlignment, - struct _DriFreeSlabManager *fMan) -{ - struct _DriBufferPool *driPool; - struct _DriSlabPool *pool; - uint32_t i; - - driPool = calloc(1, sizeof(*driPool)); - if (!driPool) - return NULL; - - pool = calloc(1, sizeof(*pool)); - if (!pool) - goto out_err0; - - pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); - if (!pool->bucketSizes) - goto out_err1; - - pool->headers = calloc(numSizes, sizeof(*pool->headers)); - if (!pool->headers) - goto out_err2; - - pool->fMan = fMan; - pool->proposedFlags = flags; - pool->validMask = validMask; - pool->numBuckets = numSizes; - pool->pageSize = getpagesize(); - pool->fd = fd; - pool->pageAlignment = pageAlignment; - pool->maxSlabSize = maxSlabSize; - pool->desiredNumBuffers = desiredNumBuffers; - - for (i=0; inumBuckets; ++i) { - pool->bucketSizes[i] = (smallestSize << i); - driInitSizeHeader(pool, pool->bucketSizes[i], - &pool->headers[i]); - } - - driPool->data = (void *) pool; - driPool->map = &pool_map; - driPool->unmap = &pool_unmap; - driPool->destroy = &pool_destroy; - driPool->offset = &pool_offset; - driPool->poolOffset = &pool_poolOffset; - driPool->flags = &pool_flags; - driPool->size = &pool_size; - driPool->create = &pool_create; - driPool->fence = &pool_fence; - driPool->kernel = &pool_kernel; - driPool->validate = &pool_validate; - driPool->waitIdle = &pool_waitIdle; - driPool->takeDown = &pool_takedown; - - return driPool; - - out_err2: - free(pool->bucketSizes); - out_err1: - free(pool); - out_err0: - free(driPool); - - return NULL; -} -- cgit v1.2.3 From 1a2c445baf9f493b1590d715314a1c240e4c9ef7 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 6 Jun 2008 14:51:11 +0200 Subject: i915: Moved EGL_i915 to the common code --- src/gallium/winsys/egl_drm/Makefile.template | 1 + src/gallium/winsys/egl_drm/intel/Makefile | 15 +- .../winsys/egl_drm/intel/intel_batchbuffer.c | 465 ---------- .../winsys/egl_drm/intel/intel_batchbuffer.h | 133 +-- src/gallium/winsys/egl_drm/intel/intel_context.c | 343 +++----- src/gallium/winsys/egl_drm/intel/intel_context.h | 81 +- src/gallium/winsys/egl_drm/intel/intel_egl.c | 15 +- src/gallium/winsys/egl_drm/intel/intel_lock.c | 102 --- src/gallium/winsys/egl_drm/intel/intel_reg.h | 10 +- src/gallium/winsys/egl_drm/intel/intel_screen.c | 599 +------------ src/gallium/winsys/egl_drm/intel/intel_screen.h | 110 +-- .../winsys/egl_drm/intel/intel_swapbuffers.c | 243 +----- .../winsys/egl_drm/intel/intel_swapbuffers.h | 47 - src/gallium/winsys/egl_drm/intel/intel_winsys.h | 73 -- .../winsys/egl_drm/intel/intel_winsys_i915.c | 184 ---- .../winsys/egl_drm/intel/intel_winsys_pipe.c | 338 ------- .../winsys/egl_drm/intel/intel_winsys_softpipe.c | 82 -- src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c | 953 -------------------- src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h | 138 --- src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h | 102 --- src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c | 268 ------ src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c | 377 -------- src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h | 115 --- .../winsys/egl_drm/intel/ws_dri_mallocpool.c | 162 ---- src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c | 970 --------------------- 25 files changed, 185 insertions(+), 5741 deletions(-) delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_lock.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/Makefile.template b/src/gallium/winsys/egl_drm/Makefile.template index 3bc1fdd4d4..07abfa53f3 100644 --- a/src/gallium/winsys/egl_drm/Makefile.template +++ b/src/gallium/winsys/egl_drm/Makefile.template @@ -54,6 +54,7 @@ SHARED_INCLUDES = \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/winsys/common \ -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/main \ -I$(TOP)/src/mesa/glapi \ diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile index 5778ba77c3..9c7ff065ff 100644 --- a/src/gallium/winsys/egl_drm/intel/Makefile +++ b/src/gallium/winsys/egl_drm/intel/Makefile @@ -6,22 +6,13 @@ LIBNAME = EGL_i915.so PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ + $(TOP)/src/gallium/winsys/common/intel_drm/libinteldrm.a DRIVER_SOURCES = \ - intel_winsys_pipe.c \ - intel_winsys_softpipe.c \ - intel_winsys_i915.c \ - intel_batchbuffer.c \ intel_swapbuffers.c \ intel_context.c \ - intel_lock.c \ intel_screen.c \ - ws_dri_bufmgr.c \ - ws_dri_drmpool.c \ - ws_dri_fencemgr.c \ - ws_dri_mallocpool.c \ - ws_dri_slabpool.c \ intel_egl.c C_SOURCES = \ @@ -35,6 +26,4 @@ DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm - include ../Makefile.template -intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c - symlinks: diff --git a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c deleted file mode 100644 index 7ffa05a6e6..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c +++ /dev/null @@ -1,465 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 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 "intel_batchbuffer.h" -#include "intel_context.h" -#include "intel_egl.h" - -#include - -#if 0 -static void -intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) -{ - int i; - fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); - for (i = 0; i < count / 4; i += 4) - fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", - offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); - fprintf(stderr, "END BATCH\n\n\n"); -} -#endif - -static void -intel_realloc_relocs(struct intel_batchbuffer *batch, int num_relocs) -{ - unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; - - size *= sizeof(uint32_t); - batch->reloc = realloc(batch->reloc, size); - batch->reloc_size = num_relocs; -} - - -void -intel_batchbuffer_reset(struct intel_batchbuffer *batch) -{ - /* - * Get a new, free batchbuffer. - */ - drmBO *bo; - struct drm_bo_info_req *req; - int ret; - - driBOUnrefUserList(batch->list); - driBOResetList(batch->list); - - batch->size = 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize; - ret = driBOData(batch->buffer, batch->size, NULL, NULL, 0); - assert(!ret); - - /* - * Add the batchbuffer to the validate list. - */ - - driBOAddListItem(batch->list, batch->buffer, - DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, - &batch->dest_location, &batch->node); - - req = &batch->node->bo_arg.d.req.bo_req; - - /* - * Set up information needed for us to make relocations - * relative to the underlying drm buffer objects. - */ - - driReadLockKernelBO(); - bo = driBOKernel(batch->buffer); - req->presumed_offset = (uint64_t) bo->offset; - req->hint = DRM_BO_HINT_PRESUMED_OFFSET; - batch->drmBOVirtual = (uint8_t *) bo->virtual; - driReadUnlockKernelBO(); - - /* - * Adjust the relocation buffer size. - */ - - if (batch->reloc_size > INTEL_MAX_RELOCS || - batch->reloc == NULL) - intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); - - assert(batch->reloc != NULL); - batch->reloc[0] = 0; /* No relocs yet. */ - batch->reloc[1] = 1; /* Reloc type 1 */ - batch->reloc[2] = 0; /* Only a single relocation list. */ - batch->reloc[3] = 0; /* Only a single relocation list. */ - - batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); - batch->poolOffset = driBOPoolOffset(batch->buffer); - batch->ptr = batch->map; - batch->dirty_state = ~0; - batch->nr_relocs = 0; - batch->flags = 0; - batch->id = 0;//batch->intel->intelScreen->batch_id++; -} - -/*====================================================================== - * Public functions - */ -struct intel_batchbuffer * -intel_batchbuffer_alloc(struct intel_screen *intel_screen) -{ - struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); - - batch->intel_screen = intel_screen; - - driGenBuffers(intel_screen->batchPool, "batchbuffer", 1, - &batch->buffer, 4096, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); - batch->last_fence = NULL; - batch->list = driBOCreateList(20); - batch->reloc = NULL; - intel_batchbuffer_reset(batch); - return batch; -} - -void -intel_batchbuffer_free(struct intel_batchbuffer *batch) -{ - if (batch->last_fence) { - driFenceFinish(batch->last_fence, - DRM_FENCE_TYPE_EXE, GL_FALSE); - driFenceUnReference(&batch->last_fence); - } - if (batch->map) { - driBOUnmap(batch->buffer); - batch->map = NULL; - } - driBOUnReference(batch->buffer); - driBOFreeList(batch->list); - if (batch->reloc) - free(batch->reloc); - batch->buffer = NULL; - free(batch); -} - -void -intel_offset_relocation(struct intel_batchbuffer *batch, - unsigned pre_add, - struct _DriBufferObject *driBO, - uint64_t val_flags, - uint64_t val_mask) -{ - int itemLoc; - struct _drmBONode *node; - uint32_t *reloc; - struct drm_bo_info_req *req; - - driBOAddListItem(batch->list, driBO, val_flags, val_mask, - &itemLoc, &node); - req = &node->bo_arg.d.req.bo_req; - - if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { - - /* - * Stop other threads from tampering with the underlying - * drmBO while we're reading its offset. - */ - - driReadLockKernelBO(); - req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; - driReadUnlockKernelBO(); - req->hint = DRM_BO_HINT_PRESUMED_OFFSET; - } - - pre_add += driBOPoolOffset(driBO); - - if (batch->nr_relocs == batch->reloc_size) - intel_realloc_relocs(batch, batch->reloc_size * 2); - - reloc = batch->reloc + - (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); - - reloc[0] = ((uint8_t *)batch->ptr - batch->drmBOVirtual); - intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add); - reloc[1] = pre_add; - reloc[2] = itemLoc; - reloc[3] = batch->dest_location; - batch->nr_relocs++; -} - -static void -i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) -{ - buf->handle = rep->handle; - buf->flags = rep->flags; - buf->size = rep->size; - buf->offset = rep->offset; - buf->mapHandle = rep->arg_handle; - buf->proposedFlags = rep->proposed_flags; - buf->start = rep->buffer_start; - buf->fenceFlags = rep->fence_flags; - buf->replyFlags = rep->rep_flags; - buf->pageAlignment = rep->page_alignment; -} - -static int -i915_execbuf(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, - drmBOList *list, - struct drm_i915_execbuffer *ea) -{ - struct intel_screen *intel_screen = batch->intel_screen; - drmBONode *node; - drmMMListHead *l; - struct drm_i915_op_arg *arg, *first; - struct drm_bo_op_req *req; - struct drm_bo_info_rep *rep; - uint64_t *prevNext = NULL; - drmBO *buf; - int ret = 0; - uint32_t count = 0; - - first = NULL; - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - - arg = &node->bo_arg; - req = &arg->d.req; - - if (!first) - first = arg; - - if (prevNext) - *prevNext = (unsigned long)arg; - - prevNext = &arg->next; - req->bo_req.handle = node->buf->handle; - req->op = drm_bo_validate; - req->bo_req.flags = node->arg0; - req->bo_req.mask = node->arg1; - req->bo_req.hint |= 0; - count++; - } - - memset(ea, 0, sizeof(*ea)); - ea->num_buffers = count; - ea->batch.start = batch->poolOffset; - ea->batch.used = used; -#if 0 /* ZZZ JB: no cliprects used */ - ea->batch.cliprects = intel->pClipRects; - ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; - ea->batch.DR1 = 0; - ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | - (((GLuint) intel->drawY) << 16)); -#else - ea->batch.cliprects = NULL; - ea->batch.num_cliprects = 0; - ea->batch.DR1 = 0; - ea->batch.DR4 = 0; -#endif - ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; - ea->ops_list = (unsigned long) first; - first->reloc_ptr = (unsigned long) batch->reloc; - batch->reloc[0] = batch->nr_relocs; - - //return -EFAULT; - do { - ret = drmCommandWriteRead(intel_screen->device->drmFD, DRM_I915_EXECBUFFER, ea, - sizeof(*ea)); - } while (ret == -EAGAIN); - - if (ret != 0) { - printf("%s somebody set us up the bomb\n", __FUNCTION__); - return ret; - } - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - arg = &node->bo_arg; - rep = &arg->d.rep.bo_info; - - if (!arg->handled) { - return -EFAULT; - } - if (arg->d.rep.ret) - return arg->d.rep.ret; - - buf = node->buf; - i915_drm_copy_reply(rep, buf); - } - return 0; -} - -/* TODO: Push this whole function into bufmgr. - */ -static struct _DriFenceObject * -do_flush_locked(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock) -{ - struct intel_screen *intel_screen = batch->intel_screen; - struct _DriFenceObject *fo; - drmFence fence; - drmBOList *boList; - struct drm_i915_execbuffer ea; - int ret = 0; - - driBOValidateUserList(batch->list); - boList = driGetdrmBOList(batch->list); - -#if 0 /* ZZZ JB Allways run */ - if (!(intel->numClipRects == 0 && !ignore_cliprects)) { -#else - if (1) { -#endif - ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); - } else { - driPutdrmBOList(batch->list); - fo = NULL; - goto out; - } - driPutdrmBOList(batch->list); - if (ret) - abort(); - - if (ea.fence_arg.error != 0) { - - /* - * The hardware has been idled by the kernel. - * Don't fence the driBOs. - */ - - if (batch->last_fence) - driFenceUnReference(&batch->last_fence); -#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ - _mesa_printf("fence error\n"); -#endif - batch->last_fence = NULL; - fo = NULL; - goto out; - } - - fence.handle = ea.fence_arg.handle; - fence.fence_class = ea.fence_arg.fence_class; - fence.type = ea.fence_arg.type; - fence.flags = ea.fence_arg.flags; - fence.signaled = ea.fence_arg.signaled; - - fo = driBOFenceUserList(intel_screen->mgr, batch->list, - "SuperFence", &fence); - - if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { - if (batch->last_fence) - driFenceUnReference(&batch->last_fence); - /* - * FIXME: Context last fence?? - */ - batch->last_fence = fo; - driFenceReference(fo); - } - out: -#if 0 /* ZZZ JB: fix this */ - intel->vtbl.lost_hardware(intel); -#else -#endif - return fo; -} - - -struct _DriFenceObject * -intel_batchbuffer_flush(struct intel_batchbuffer *batch) -{ - //struct intel_context *intel = batch->intel; - GLuint used = batch->ptr - batch->map; - //GLboolean was_locked = 1; - struct _DriFenceObject *fence; - - if (used == 0) { - driFenceReference(batch->last_fence); - return batch->last_fence; - } - - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a - * performance drain that we would like to avoid. - */ -#if 0 /* ZZZ JB: what should we do here? */ - if (used & 4) { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; - used += 8; - } -#else - if (used & 4) { - ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; - used += 8; - } -#endif - driBOUnmap(batch->buffer); - batch->ptr = NULL; - batch->map = NULL; - - /* TODO: Just pass the relocation list and dma buffer up to the - * kernel. - */ -/* if (!was_locked) - LOCK_HARDWARE(intel);*/ - - fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), - GL_FALSE); - -/* if (!was_locked) - UNLOCK_HARDWARE(intel);*/ - - /* Reset the buffer: - */ - intel_batchbuffer_reset(batch); - return fence; -} - -void -intel_batchbuffer_finish(struct intel_batchbuffer *batch) -{ - struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); - driFenceFinish(fence, driFenceType(fence), GL_FALSE); - driFenceUnReference(&fence); -} - -void -intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags) -{ - assert((bytes & 3) == 0); - intel_batchbuffer_require_space(batch, bytes, flags); - memcpy(batch->ptr, data, bytes); - batch->ptr += bytes; -} diff --git a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h index 6d35cf8b96..1fa2719845 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h @@ -1,133 +1,24 @@ #ifndef INTEL_BATCHBUFFER_H #define INTEL_BATCHBUFFER_H -#include "mtypes.h" -#include "ws_dri_bufmgr.h" +#include "intel_drm/intel_be_batchbuffer.h" -struct intel_screen; - -#define BATCH_SZ 16384 -#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_batchbuffer -{ - struct bufmgr *bm; - struct intel_screen *intel_screen; - - struct _DriBufferObject *buffer; - struct _DriFenceObject *last_fence; - GLuint flags; - - struct _DriBufferList *list; - GLuint list_count; - GLubyte *map; - GLubyte *ptr; - - uint32_t *reloc; - GLuint reloc_size; - GLuint nr_relocs; - - GLuint size; - - GLuint dirty_state; - GLuint id; - - uint32_t poolOffset; - uint8_t *drmBOVirtual; - struct _drmBONode *node; /* Validation list node for this buffer */ - int dest_location; /* Validation list sequence for this buffer */ -}; - -struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_screen - *intel); - -void intel_batchbuffer_free(struct intel_batchbuffer *batch); - - -void intel_batchbuffer_finish(struct intel_batchbuffer *batch); - -struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer - *batch); - -void intel_batchbuffer_reset(struct intel_batchbuffer *batch); - - -/* Unlike bmBufferData, this currently requires the buffer be mapped. - * Consider it a convenience function wrapping multple - * intel_buffer_dword() calls. - */ -void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags); - -void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, - GLuint bytes); - -void -intel_offset_relocation(struct intel_batchbuffer *batch, - unsigned pre_add, - struct _DriBufferObject *driBO, - uint64_t val_flags, - uint64_t val_mask); - -/* Inline functions - might actually be better off with these - * non-inlined. Certainly better off switching all command packets to - * be passed as structs rather than dwords, but that's a little bit of - * work... +/* + * Need to redefine the BATCH defines */ -static INLINE GLuint -intel_batchbuffer_space(struct intel_batchbuffer *batch) -{ - return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); -} - - -static INLINE void -intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) -{ - assert(batch->map); - assert(intel_batchbuffer_space(batch) >= 4); - *(GLuint *) (batch->ptr) = dword; - batch->ptr += 4; -} -static INLINE void -intel_batchbuffer_require_space(struct intel_batchbuffer *batch, - GLuint sz, GLuint flags) -{ - struct _DriFenceObject *fence; +#undef BEGIN_BATCH +#define BEGIN_BATCH(dwords, relocs) \ + (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) - assert(sz < batch->size - 8); - if (intel_batchbuffer_space(batch) < sz || - (batch->flags != 0 && flags != 0 && batch->flags != flags)) { - fence = intel_batchbuffer_flush(batch); - driFenceUnReference(&fence); - } +#undef OUT_BATCH +#define OUT_BATCH(d) \ + i915_batchbuffer_dword(&intel->base.batch->base, d) - batch->flags |= flags; -} - -/* Here are the crusty old macros, to be removed: - */ -#define BATCH_LOCALS - -#define BEGIN_BATCH(n, flags) do { \ - assert(!intel->prim.flush); \ - intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ -} while (0) - -#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) - -#define OUT_RELOC(buf,flags,mask,delta) do { \ +#undef OUT_RELOC +#define OUT_RELOC(buf,flags,mask,delta) do { \ assert((delta) >= 0); \ - intel_offset_relocation(intel->batch, delta, buf, flags, mask); \ + intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ } while (0) -#define ADVANCE_BATCH() do { } while(0) - #endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c index 394a40d714..fdbaa230e5 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,14 +22,13 @@ * 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 "i915simple/i915_screen.h" #include "intel_screen.h" #include "intel_context.h" -#include "intel_swapbuffers.h" -#include "intel_winsys.h" #include "intel_batchbuffer.h" #include "state_tracker/st_public.h" @@ -70,74 +69,109 @@ int __intel_debug = 0; * old i830-specific driver. */ const struct dri_extension card_extensions[] = { - {"GL_ARB_multisample", GL_ARB_multisample_functions}, - {"GL_ARB_multitexture", NULL}, - {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, - {"GL_ARB_texture_border_clamp", NULL}, - {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, - {"GL_ARB_texture_cube_map", NULL}, - {"GL_ARB_texture_env_add", NULL}, - {"GL_ARB_texture_env_combine", NULL}, - {"GL_ARB_texture_env_dot3", NULL}, - {"GL_ARB_texture_mirrored_repeat", NULL}, - {"GL_ARB_texture_rectangle", NULL}, - {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, - {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, - {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, - {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, - {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, - {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, - {"GL_EXT_blend_subtract", NULL}, - {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, - {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, - {"GL_EXT_packed_depth_stencil", NULL}, - {"GL_EXT_pixel_buffer_object", NULL}, - {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, - {"GL_EXT_stencil_wrap", NULL}, - {"GL_EXT_texture_edge_clamp", NULL}, - {"GL_EXT_texture_env_combine", NULL}, - {"GL_EXT_texture_env_dot3", NULL}, - {"GL_EXT_texture_filter_anisotropic", NULL}, - {"GL_EXT_texture_lod_bias", NULL}, - {"GL_3DFX_texture_compression_FXT1", NULL}, - {"GL_APPLE_client_storage", NULL}, - {"GL_MESA_pack_invert", NULL}, - {"GL_MESA_ycbcr_texture", NULL}, - {"GL_NV_blend_square", NULL}, - {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, - {"GL_NV_vertex_program1_1", NULL}, - {"GL_SGIS_generate_mipmap", NULL }, - {NULL, NULL} + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, + {"GL_SGIS_generate_mipmap", NULL }, + {NULL, NULL} }; + +/* + * Hardware lock functions. + * Doesn't do anything in EGL + */ + +static void +intel_lock_hardware(struct intel_be_context *context) +{ + (void)context; +} + +static void +intel_unlock_hardware(struct intel_be_context *context) +{ + (void)context; +} + +static boolean +intel_locked_hardware(struct intel_be_context *context) +{ + (void)context; + return FALSE; +} + + +/* + * Misc functions. + */ + int -intel_create_context(struct egl_drm_context *eglCon, const __GLcontextModes *visual, void *sharedContextPrivate) +intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) { - struct intel_context *iCon = CALLOC_STRUCT(intel_context); - struct intel_screen *iScrn = (struct intel_screen *)eglCon->device->priv; + struct intel_context *intel = CALLOC_STRUCT(intel_context); + struct intel_screen *screen = (struct intel_screen *)egl_context->device->priv; struct pipe_context *pipe; struct st_context *st_share = NULL; - eglCon->priv = iCon; + egl_context->priv = intel; + + intel->intel_screen = screen; + intel->egl_context = egl_context; + intel->egl_device = egl_context->device; - iCon->intel_screen = iScrn; - iCon->egl_context = eglCon; - iCon->egl_device = eglCon->device; + intel->base.hardware_lock = intel_lock_hardware; + intel->base.hardware_unlock = intel_unlock_hardware; + intel->base.hardware_locked = intel_locked_hardware; - iCon->batch = intel_batchbuffer_alloc(iScrn); - iCon->last_swap_fence = NULL; - iCon->first_swap_fence = NULL; + intel_be_init_context(&intel->base, &screen->base); - pipe = intel_create_i915simple(iCon, iScrn->winsys); -// pipe = intel_create_softpipe(iCon, iScrn->winsys); +#if 0 + pipe = intel_create_softpipe(intel, screen->winsys); +#else + pipe = i915_create_context(screen->pipe, &screen->base.base, &intel->base.base); +#endif - pipe->priv = iCon; + pipe->priv = intel; - iCon->st = st_create_context(pipe, visual, st_share); + intel->st = st_create_context(pipe, visual, st_share); return TRUE; } @@ -161,7 +195,6 @@ intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *dra if (draw != read) st_resize_framebuffer(read_fb->stfb, read->w, read->h); - //intelUpdateWindowSize(driDrawPriv); } else { st_make_current(NULL, NULL, NULL); } @@ -173,7 +206,9 @@ intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer struct intel_screen *intelScreen = (struct intel_screen *)draw->device->priv; struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; - driBOUnReference(draw_fb->front_buffer); + if (draw_fb->front_buffer) + driBOUnReference(draw_fb->front_buffer); + draw_fb->front_buffer = NULL; draw_fb->front = NULL; @@ -183,184 +218,8 @@ intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer draw_fb->front = front; - driGenBuffers(intelScreen->staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); + driGenBuffers(intelScreen->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); driBOSetReferenced(draw_fb->front_buffer, front->handle); st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); } - -#if 0 -GLboolean -intelCreateContext(const __GLcontextModes * visual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate) -{ - struct intel_context *intel = CALLOC_STRUCT(intel_context); - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - struct intel_screen *intelScreen = intel_screen(sPriv); - drmI830Sarea *saPriv = intelScreen->sarea; - int fthrottle_mode; - GLboolean havePools; - struct pipe_context *pipe; - struct st_context *st_share = NULL; - - if (sharedContextPrivate) { - st_share = ((struct intel_context *) sharedContextPrivate)->st; - } - - driContextPriv->driverPrivate = intel; - intel->intelScreen = intelScreen; - intel->driScreen = sPriv; - intel->sarea = saPriv; - - driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, - intel->driScreen->myNum, "i915"); - - - /* - * memory pools - */ - DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); - // ZZZ JB should be per screen and not be done per context - havePools = intelCreatePools(sPriv); - DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); - if (!havePools) - return GL_FALSE; - - - /* Dri stuff */ - intel->hHWContext = driContextPriv->hHWContext; - intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; - - fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); - intel->iw.irq_seq = -1; - intel->irqsEmitted = 0; - - intel->batch = intel_batchbuffer_alloc(intel); - intel->last_swap_fence = NULL; - intel->first_swap_fence = NULL; - -#ifdef DEBUG - __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); -#endif - - /* - * Pipe-related setup - */ - if (getenv("INTEL_SP")) { - /* use softpipe driver instead of hw */ - pipe = intel_create_softpipe( intel, intelScreen->winsys ); - } - else { - switch (intel->intelScreen->deviceID) { - case PCI_CHIP_I945_G: - case PCI_CHIP_I945_GM: - case PCI_CHIP_I945_GME: - case PCI_CHIP_G33_G: - case PCI_CHIP_Q33_G: - case PCI_CHIP_Q35_G: - case PCI_CHIP_I915_G: - case PCI_CHIP_I915_GM: - pipe = intel_create_i915simple( intel, intelScreen->winsys ); - break; - default: - fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", - intel->intelScreen->deviceID, __FUNCTION__); - - pipe = intel_create_softpipe( intel, intelScreen->winsys ); - break; - } - } - - pipe->priv = intel; - - intel->st = st_create_context(pipe, visual, st_share); - - return GL_TRUE; -} - - -void -intelDestroyContext(__DRIcontextPrivate * driContextPriv) -{ - struct intel_context *intel = intel_context(driContextPriv); - - assert(intel); /* should never be null */ - if (intel) { - st_finish(intel->st); - - intel_batchbuffer_free(intel->batch); - - if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(&intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - if (intel->first_swap_fence) { - driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = NULL; - } - - if (intel->intelScreen->dummyContext == intel) - intel->intelScreen->dummyContext = NULL; - - st_destroy_context(intel->st); - free(intel); - } -} - - -GLboolean -intelUnbindContext(__DRIcontextPrivate * driContextPriv) -{ - struct intel_context *intel = intel_context(driContextPriv); - st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL); - /* XXX make_current(NULL)? */ - return GL_TRUE; -} - - -GLboolean -intelMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv) -{ - if (driContextPriv) { - struct intel_context *intel = intel_context(driContextPriv); - struct intel_framebuffer *draw_fb = intel_framebuffer(driDrawPriv); - struct intel_framebuffer *read_fb = intel_framebuffer(driReadPriv); - - assert(draw_fb->stfb); - assert(read_fb->stfb); - - /* This is for situations in which we need a rendering context but - * there may not be any currently bound. - */ - intel->intelScreen->dummyContext = intel; - - st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); - - if ((intel->driDrawable != driDrawPriv) || - (intel->lastStamp != driDrawPriv->lastStamp)) { - intel->driDrawable = driDrawPriv; - intelUpdateWindowSize(driDrawPriv); - intel->lastStamp = driDrawPriv->lastStamp; - } - - /* The size of the draw buffer will have been updated above. - * If the readbuffer is a different window, check/update its size now. - */ - if (driReadPriv != driDrawPriv) { - intelUpdateWindowSize(driReadPriv); - } - - } - else { - st_make_current(NULL, NULL, NULL); - } - - return GL_TRUE; -} -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h index aa9903f274..ccf8120761 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.h +++ b/src/gallium/winsys/egl_drm/intel/intel_context.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,61 +22,37 @@ * 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. - * + * **************************************************************************/ #ifndef INTEL_CONTEXT_H #define INTEL_CONTEXT_H -#include -#include "drm.h" - #include "pipe/p_debug.h" - -#include "intel_screen.h" -#include "i915_drm.h" +#include "intel_drm/intel_be_context.h" -struct pipe_context; -struct intel_context; -struct _DriBufferObject; struct st_context; struct egl_drm_device; struct egl_drm_context; struct egl_drm_frontbuffer; -#define INTEL_MAX_FIXUP 64 - /** * Intel rendering context, contains a state tracker and intel-specific info. */ struct intel_context { - struct st_context *st; - - struct _DriFenceObject *last_swap_fence; - struct _DriFenceObject *first_swap_fence; + struct intel_be_context base; - struct intel_batchbuffer *batch; + struct st_context *st; -#if 0 - boolean locked; - char *prevLockFile; - int prevLockLine; -#endif - - /* pick this up from the screen instead - int drmFd; - */ + struct intel_screen *intel_screen; - struct intel_screen *intel_screen; - - uint lastStamp; - /* new egl stuff */ - struct egl_drm_device *egl_device; - struct egl_drm_context *egl_context; - struct egl_drm_drawable *egl_drawable; + /* new egl stuff */ + struct egl_drm_device *egl_device; + struct egl_drm_context *egl_context; + struct egl_drm_drawable *egl_drawable; }; @@ -86,12 +62,12 @@ struct intel_context */ struct intel_framebuffer { - struct st_framebuffer *stfb; + struct st_framebuffer *stfb; - /* other fields TBD */ - int other; - struct _DriBufferObject *front_buffer; - struct egl_drm_frontbuffer *front; + /* other fields TBD */ + int other; + struct _DriBufferObject *front_buffer; + struct egl_drm_frontbuffer *front; }; @@ -123,11 +99,10 @@ extern int __intel_debug; } while(0) #else -#define DBG(flag, ...) +#define DBG(flag, ...) #endif - #define PCI_CHIP_845_G 0x2562 #define PCI_CHIP_I830_M 0x3577 #define PCI_CHIP_I855_GM 0x3582 @@ -141,22 +116,4 @@ extern int __intel_debug; #define PCI_CHIP_Q35_G 0x29B2 #define PCI_CHIP_Q33_G 0x29D2 - -#if 0 -/** Cast wrapper */ -static INLINE struct intel_context * -intel_context(__DRIcontextPrivate *driContextPriv) -{ - return (struct intel_context *) driContextPriv->driverPrivate; -} - - -/** Cast wrapper */ -static INLINE struct intel_framebuffer * -intel_framebuffer(__DRIdrawablePrivate * driDrawPriv) -{ - return (struct intel_framebuffer *) driDrawPriv->driverPrivate; -} -#endif - #endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 41b7eac4ed..3b4ab330f5 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -21,9 +21,6 @@ #include "intel_context.h" -#include "ws_dri_bufmgr.h" - -#include "intel_winsys.h" #include "state_tracker/st_public.h" struct egl_drm_device* egl_drm_create_device(int drmFD); @@ -434,10 +431,12 @@ prettyColors(int fd, unsigned int handle, size_t pitch) { drmBO bo; unsigned int *ptr; + void *p; int i; drmBOReference(fd, handle, &bo); - drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, (void**)&ptr); + drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &p); + ptr = (unsigned int*)p; for (i = 0; i < (bo.size / 4); i++) ptr[i] = 0xFFFFFFFF; @@ -460,8 +459,6 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, struct drm_driver *drm_drv = (struct drm_driver *)drv; struct drm_surface *surf = lookup_drm_surface(surface); struct drm_screen *scrn = lookup_drm_screen(dpy, screen); - //struct intel_framebuffer *intel_fb = NULL; - //struct pipe_surface *front_surf = NULL; _EGLMode *mode = _eglLookupMode(dpy, m); size_t pitch = 2048 * 4; size_t size = mode->Height * pitch; @@ -469,8 +466,6 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, /* TODO if allready shown take down */ - printf("setting mode to %i x %i\n", mode->Width, mode->Height); - ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | @@ -554,6 +549,7 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re struct drm_context *ctx = lookup_drm_context(context); EGLBoolean b; + printf("drm_make_current\n"); b = _eglMakeCurrent(drv, dpy, draw, read, context); if (!b) return EGL_FALSE; @@ -563,6 +559,7 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re (void) readSurf; (void) ctx; + printf("enter intel_make_current\n"); intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); return EGL_TRUE; } @@ -613,6 +610,8 @@ _eglMain(_EGLDisplay *dpy, const char *args) drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; drm->base.API.SwapBuffers = drm_swap_buffers; + drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; + /* enable supported extensions */ drm->base.Extensions.MESA_screen_surface = EGL_TRUE; drm->base.Extensions.MESA_copy_context = EGL_TRUE; diff --git a/src/gallium/winsys/egl_drm/intel/intel_lock.c b/src/gallium/winsys/egl_drm/intel/intel_lock.c deleted file mode 100644 index cec83c7585..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_lock.c +++ /dev/null @@ -1,102 +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 "main/glheader.h" -#include "glapi/glthread.h" -#include -#include "state_tracker/st_public.h" -#include "intel_context.h" - -#if 0 - -_glthread_DECLARE_STATIC_MUTEX( lockMutex ); - - -static void -intelContendedLock(struct intel_context *intel, uint flags) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - __DRIscreenPrivate *sPriv = intel->driScreen; - struct intel_screen *intelScreen = intel_screen(sPriv); - drmI830Sarea *sarea = intel->sarea; - - drmGetLock(intel->driFd, intel->hHWContext, flags); - - DBG(LOCK, "%s - got contended lock\n", __progname); - - /* 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); - - if (sarea->width != intelScreen->front.width || - sarea->height != intelScreen->front.height) { - - intelUpdateScreenRotation(sPriv, sarea); - } -} - - -/* Lock the hardware and validate our state. - */ -void LOCK_HARDWARE( struct intel_context *intel ) -{ - char __ret = 0; - - _glthread_LOCK_MUTEX(lockMutex); - assert(!intel->locked); - - DRM_CAS(intel->driHwLock, intel->hHWContext, - (DRM_LOCK_HELD|intel->hHWContext), __ret); - - if (__ret) - intelContendedLock( intel, 0 ); - - DBG(LOCK, "%s - locked\n", __progname); - - intel->locked = 1; -} - - -/* Unlock the hardware using the global current context - */ -void UNLOCK_HARDWARE( struct intel_context *intel ) -{ - assert(intel->locked); - intel->locked = 0; - - DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); - - _glthread_UNLOCK_MUTEX(lockMutex); - - DBG(LOCK, "%s - unlocked\n", __progname); -} -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_reg.h b/src/gallium/winsys/egl_drm/intel/intel_reg.h index f37c24fda9..4f33bee438 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_reg.h +++ b/src/gallium/winsys/egl_drm/intel/intel_reg.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,7 +22,7 @@ * 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. - * + * **************************************************************************/ diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c index 38c4098087..96b0bf1b85 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.c +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,62 +22,24 @@ * 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 "utils.h" -#include "vblank.h" -#include "xmlpool.h" + +#include "state_tracker/st_public.h" +#include "i915simple/i915_screen.h" #include "intel_context.h" #include "intel_screen.h" #include "intel_batchbuffer.h" -//#include "intel_batchpool.h" -#include "intel_swapbuffers.h" -#include "intel_winsys.h" - -#include "ws_dri_bufpool.h" - -#include "pipe/p_context.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_cb_fbo.h" #include "intel_egl.h" -static boolean -intel_create_pools(struct intel_screen *intel_screen) -{ - if (intel_screen->havePools) - return GL_TRUE; - - intel_screen->mgr = driFenceMgrTTMInit(intel_screen->device->drmFD); - if (!intel_screen->mgr) { - fprintf(stderr, "Failed to create fence manager.\n"); - return FALSE; - } - - intel_screen->fMan = driInitFreeSlabManager(10, 10); - if (!intel_screen->fMan) { - fprintf(stderr, "Failed to create free slab manager.\n"); - return FALSE; - } - - intel_screen->staticPool = driDRMPoolInit(intel_screen->device->drmFD); - intel_screen->batchPool = driSlabPoolInit(intel_screen->device->drmFD, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - 4096, //intelScreen->maxBatchSize, - 1, 40, 16*16384, 0, - intel_screen->fMan); - - intel_screen->havePools = GL_TRUE; - - return GL_TRUE; -} extern const struct dri_extension card_extensions[]; + int intel_init_driver(struct egl_drm_device *device) { @@ -85,18 +47,18 @@ intel_init_driver(struct egl_drm_device *device) /* Allocate the private area */ intel_screen = CALLOC_STRUCT(intel_screen); - if (!intel_screen) + if (!intel_screen) return FALSE; device->priv = (void *)intel_screen; intel_screen->device = device; - if (!intel_create_pools(intel_screen)) - return FALSE; + /** TODO JB: ugly hack */ + intel_screen->deviceID = PCI_CHIP_I945_GM; - intel_screen->batch = intel_batchbuffer_alloc(intel_screen); + intel_be_init_device(&intel_screen->base, device->drmFD); - intel_screen->winsys = intel_create_pipe_winsys(device->drmFD, intel_screen->fMan); + intel_screen->pipe = i915_create_screen(&intel_screen->base.base, intel_screen->deviceID); /* hack */ driInitExtensions(NULL, card_extensions, GL_FALSE); @@ -147,534 +109,3 @@ intel_create_drawable(struct egl_drm_drawable *drawable, drawable->priv = (void *) intelfb; return GL_TRUE; } - -#if 0 -PUBLIC const char __driConfigOptions[] = - DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE - DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) - DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) - DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY - DRI_CONF_FORCE_S3TC_ENABLE(false) - DRI_CONF_ALLOW_LARGE_TEXTURES(1) - DRI_CONF_SECTION_END DRI_CONF_END; - -const uint __driNConfigOptions = 4; - -#ifdef USE_NEW_INTERFACE -static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; -#endif /*USE_NEW_INTERFACE */ - -extern const struct dri_extension card_extensions[]; - - - - -static void -intelPrintDRIInfo(struct intel_screen * intelScreen, - __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) -{ - fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", - intelScreen->front.size, intelScreen->front.offset, - intelScreen->front.pitch); - fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); -} - -static void -intelPrintSAREA(const drmI830Sarea * sarea) -{ - fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, - sarea->height); - fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); - fprintf(stderr, - "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->front_offset, sarea->front_size, - (unsigned) sarea->front_handle); - fprintf(stderr, - "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->back_offset, sarea->back_size, - (unsigned) sarea->back_handle); - fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->depth_offset, sarea->depth_size, - (unsigned) sarea->depth_handle); - fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); - fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); - fprintf(stderr, - "SAREA: rotated offset: 0x%08x size: 0x%x\n", - sarea->rotated_offset, sarea->rotated_size); - fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); -} - -/** - * Use the information in the sarea to update the screen parameters - * related to screen rotation. Needs to be called locked. - */ -void -intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) -{ - struct intel_screen *intelScreen = intel_screen(sPriv); - - if (intelScreen->front.map) { - drmUnmap(intelScreen->front.map, intelScreen->front.size); - intelScreen->front.map = NULL; - } - - if (intelScreen->front.buffer) - driDeleteBuffers(1, &intelScreen->front.buffer); - - intelScreen->front.width = sarea->width; - intelScreen->front.height = sarea->height; - intelScreen->front.offset = sarea->front_offset; - intelScreen->front.pitch = sarea->pitch * intelScreen->front.cpp; - intelScreen->front.size = sarea->front_size; - intelScreen->front.handle = sarea->front_handle; - - assert( sarea->front_size >= - intelScreen->front.pitch * intelScreen->front.height ); - -#if 0 /* JB not important */ - if (!sarea->front_handle) - return; - - if (drmMap(sPriv->fd, - sarea->front_handle, - intelScreen->front.size, - (drmAddress *) & intelScreen->front.map) != 0) { - fprintf(stderr, "drmMap(frontbuffer) failed!\n"); - return; - } -#endif - -#if 0 /* JB */ - if (intelScreen->staticPool) { - driGenBuffers(intelScreen->staticPool, "static region", 1, - &intelScreen->front.buffer, 64, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - - driBOSetStatic(intelScreen->front.buffer, - intelScreen->front.offset, - intelScreen->front.pitch * intelScreen->front.height, - intelScreen->front.map, 0); - } -#else - if (intelScreen->staticPool) { - if (intelScreen->front.buffer) - driBOUnReference(intelScreen->front.buffer); - driGenBuffers(intelScreen->staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); - driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle); - } -#endif -} - - -boolean -intelCreatePools(__DRIscreenPrivate * sPriv) -{ - //unsigned batchPoolSize = 1024*1024; - struct intel_screen *intelScreen = intel_screen(sPriv); - - if (intelScreen->havePools) - return GL_TRUE; - -#if 0 /* ZZZ JB fix this */ - intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); - if (!intelScreen->staticPool) - return GL_FALSE; - - batchPoolSize /= BATCH_SZ; - intelScreen->batchPool = driBatchPoolInit(sPriv->fd, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_MEM_LOCAL, - BATCH_SZ, - batchPoolSize, 5); - if (!intelScreen->batchPool) { - fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); - return GL_FALSE; - } -#else - intelScreen->staticPool = driDRMPoolInit(sPriv->fd); - intelScreen->batchPool = driSlabPoolInit(sPriv->fd, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - 4096, //intelScreen->maxBatchSize, - 1, 40, 16*16384, 0, - intelScreen->fMan); -#endif - intelScreen->havePools = GL_TRUE; - - //intelUpdateScreenRotation(sPriv, intelScreen->sarea); - - return GL_TRUE; -} - - -static boolean -intelInitDriver(__DRIscreenPrivate * sPriv) -{ - struct intel_screen *intelScreen; - I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; - - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> - getProcAddress("glxEnableExtension")); - void *const psc = sPriv->psc->screenConfigs; - - if (sPriv->devPrivSize != sizeof(I830DRIRec)) { - fprintf(stderr, - "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); - return GL_FALSE; - } - - /* Allocate the private area */ - intelScreen = CALLOC_STRUCT(intel_screen); - if (!intelScreen) - return GL_FALSE; - - /* parse information in __driConfigOptions */ - driParseOptionInfo(&intelScreen->optionCache, - __driConfigOptions, __driNConfigOptions); - - sPriv->private = (void *) intelScreen; - - intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + - gDRIPriv->sarea_priv_offset); - intelScreen->deviceID = gDRIPriv->deviceID; - intelScreen->front.cpp = gDRIPriv->cpp; - intelScreen->drmMinor = sPriv->drmMinor; - - - assert(gDRIPriv->bitsPerPixel == 16 || - gDRIPriv->bitsPerPixel == 32); - - - intelUpdateScreenRotation(sPriv, intelScreen->sarea); - - if (0) - intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - - if (glx_enable_extension != NULL) { - (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); - (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); - (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); - } - - - -#if 1 // ZZZ JB - intelScreen->mgr = driFenceMgrTTMInit(sPriv->fd); - if (!intelScreen->mgr) { - fprintf(stderr, "Failed to create fence manager.\n"); - return GL_FALSE; - } - - intelScreen->fMan = driInitFreeSlabManager(10, 10); - if (!intelScreen->fMan) { - fprintf(stderr, "Failed to create free slab manager.\n"); - return GL_FALSE; - } - - if (!intelCreatePools(sPriv)) - return GL_FALSE; -#endif - - intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd, intelScreen->fMan); - - return GL_TRUE; -} - - -static void -intelDestroyScreen(__DRIscreenPrivate * sPriv) -{ - struct intel_screen *intelScreen = intel_screen(sPriv); - - /* intelUnmapScreenRegions(intelScreen); */ - - if (intelScreen->havePools) { - driPoolTakeDown(intelScreen->staticPool); - driPoolTakeDown(intelScreen->batchPool); - } - FREE(intelScreen); - sPriv->private = NULL; -} - - -/** - * This is called when we need to set up GL rendering to a new X window. - */ -static boolean -intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, - __DRIdrawablePrivate * driDrawPriv, - const __GLcontextModes * visual, boolean isPixmap) -{ - if (isPixmap) { - return GL_FALSE; /* not implemented */ - } - else { - enum pipe_format colorFormat, depthFormat, stencilFormat; - struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); - - if (!intelfb) - return GL_FALSE; - - if (visual->redBits == 5) - colorFormat = PIPE_FORMAT_R5G6B5_UNORM; - else - colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; - - if (visual->depthBits == 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (visual->depthBits == 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_NONE; - - if (visual->stencilBits == 8) - stencilFormat = PIPE_FORMAT_S8Z24_UNORM; - else - stencilFormat = PIPE_FORMAT_NONE; - - intelfb->stfb = st_create_framebuffer(visual, - colorFormat, - depthFormat, - stencilFormat, - driDrawPriv->w, - driDrawPriv->h, - (void*) intelfb); - if (!intelfb->stfb) { - free(intelfb); - return GL_FALSE; - } - - driDrawPriv->driverPrivate = (void *) intelfb; - return GL_TRUE; - } -} - -static void -intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) -{ - struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv); - assert(intelfb->stfb); - st_unreference_framebuffer(&intelfb->stfb); - free(intelfb); -} - - -/** - * Get information about previous buffer swaps. - */ -static int -intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) -{ - if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) - || (sInfo == NULL)) { - return -1; - } - - return 0; -} - - -static void -intelSetTexOffset(__DRIcontext *pDRICtx, int texname, - unsigned long long offset, int depth, uint pitch) -{ - abort(); -#if 0 - struct intel_context *intel = (struct intel_context*) - ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; - struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); - struct st_texture_object *stObj = st_texture_object(tObj); - - if (!stObj) - return; - - if (stObj->pt) - st->pipe->texture_release(intel->st->pipe, &stObj->pt); - - stObj->imageOverride = GL_TRUE; - stObj->depthOverride = depth; - stObj->pitchOverride = pitch; - - if (offset) - stObj->textureOffset = offset; -#endif -} - - -static const struct __DriverAPIRec intelAPI = { - .InitDriver = intelInitDriver, - .DestroyScreen = intelDestroyScreen, - .CreateContext = intelCreateContext, - .DestroyContext = intelDestroyContext, - .CreateBuffer = intelCreateBuffer, - .DestroyBuffer = intelDestroyBuffer, - .SwapBuffers = intelSwapBuffers, - .MakeCurrent = intelMakeCurrent, - .UnbindContext = intelUnbindContext, - .GetSwapInfo = intelGetSwapInfo, - .GetMSC = driGetMSC32, - .WaitForMSC = driWaitForMSC32, - .WaitForSBC = NULL, - .SwapBuffersMSC = NULL, - .CopySubBuffer = intelCopySubBuffer, - .setTexOffset = intelSetTexOffset, -}; - - -static __GLcontextModes * -intelFillInModes(unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, boolean have_back_buffer) -{ - __GLcontextModes *modes; - __GLcontextModes *m; - unsigned num_modes; - unsigned depth_buffer_factor; - unsigned back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't - * support pageflipping at all. - */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML - }; - - u_int8_t depth_bits_array[3]; - u_int8_t stencil_bits_array[3]; - - - 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; - - depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; - back_buffer_factor = (have_back_buffer) ? 3 : 1; - - num_modes = depth_buffer_factor * back_buffer_factor * 4; - - 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; - } - - modes = - (*dri_interface->createContextModes) (num_modes, - sizeof(__GLcontextModes)); - m = modes; - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_DIRECT_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - - /* Mark the visual as slow if there are "fake" stencil bits. - */ - for (m = modes; m != NULL; m = m->next) { - if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { - m->visualRating = GLX_SLOW_CONFIG; - } - } - - return modes; -} - - -/** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. - * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. - */ -PUBLIC void * -__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, - __DRIscreen * psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) -{ - __DRIscreenPrivate *psp; - static const __DRIversion ddx_expected = { 1, 7, 0 }; - static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 7, 0 }; - - dri_interface = interface; - - if (!driCheckDriDdxDrmVersions2("i915", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { - return NULL; - } - - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &intelAPI); - - if (psp != NULL) { - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - *driver_modes = intelFillInModes(dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, 1); - - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create - * is called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions(NULL, card_extensions, GL_FALSE); - } - - return (void *) psp; -} -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_screen.h index e8c1cdfca4..87c4406f54 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.h +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,112 +22,26 @@ * 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. - * + * **************************************************************************/ #ifndef _INTEL_SCREEN_H_ #define _INTEL_SCREEN_H_ -#include "ws_dri_bufpool.h" +#include "intel_drm/intel_be_device.h" #include "pipe/p_compiler.h" -struct egl_drm_device *device; +struct pipe_screen; +struct egl_drm_device; struct intel_screen { -#if 0 - struct { - drm_handle_t handle; + struct intel_be_device base; + struct pipe_screen *pipe; - /* We create a static dri buffer for the frontbuffer. - */ - struct _DriBufferObject *buffer; - - char *map; /* memory map */ - int offset; /* from start of video mem, in bytes */ - int pitch; /* row stride, in bytes */ - int width; - int height; - int size; - int cpp; /* for front and back buffers */ - } front; -#endif - - int drmFB; - -#if 0 - int deviceID; - int drmMinor; - - - drmI830Sarea *sarea;*/ - - - /** - * Configuration cache with default values for all contexts - */ - driOptionCache optionCache; -#endif - - struct _DriBufferPool *batchPool; - struct _DriBufferPool *staticPool; /** for the X screen/framebuffer */ - boolean havePools; - -#if 0 - /** - * Temporary(?) context to use for SwapBuffers or other situations in - * which we need a rendering context, but none is currently bound. - */ - struct intel_context *dummyContext; -#endif - - /* - * New stuff form the i915tex integration - */ - struct _DriFenceMgr *mgr; - struct _DriFreeSlabManager *fMan; - unsigned batch_id; - - struct pipe_winsys *winsys; - struct egl_drm_device *device; - - /* batch buffer used for swap buffers */ - struct intel_batchbuffer *batch; + int deviceID; + struct egl_drm_device *device; }; - - -/** cast wrapper */ -#if 0 -static INLINE struct intel_screen * -intel_screen(__DRIscreenPrivate *sPriv) -{ - return (struct intel_screen *) sPriv->private; -} - - -extern void -intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); - - -extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); - -extern boolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); - -extern boolean -intelMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv); - - -extern boolean -intelCreatePools(__DRIscreenPrivate *sPriv); - -extern boolean -intelCreateContext(const __GLcontextModes * visual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - -#endif #endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c index 1ce4b2754a..24e55f1568 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * 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 @@ -10,11 +10,11 @@ * 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. @@ -22,15 +22,13 @@ * 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 "intel_screen.h" #include "intel_context.h" -#include "intel_swapbuffers.h" #include "intel_batchbuffer.h" #include "intel_reg.h" -#include "intel_winsys.h" #include "pipe/p_context.h" #include "state_tracker/st_public.h" @@ -54,7 +52,8 @@ void intel_swap_buffers(struct egl_drm_drawable *draw) back_surf = st_get_framebuffer_surface(intel_fb->stfb, ST_SURFACE_BACK_LEFT); if (back_surf) { st_notify_swapbuffers(intel_fb->stfb); - intel_display_surface(draw, back_surf); + if (intel_fb->front) + intel_display_surface(draw, back_surf); st_notify_swapbuffers_complete(intel_fb->stfb); } } @@ -63,7 +62,7 @@ static void intel_display_surface(struct egl_drm_drawable *draw, struct pipe_surface *surf) { - struct intel_screen *intel = (struct intel_screen *)draw->device->priv; + struct intel_context *intel = NULL; struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; struct _DriFenceObject *fence; @@ -85,8 +84,7 @@ intel_display_surface(struct egl_drm_drawable *draw, CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); - printf("srcPitch: %u, dstWidth: %u, dstHeight: %u, dstPitch: %u, cpp: %u\n", srcPitch, dstWidth, dstHeight, dstPitch, cpp); - BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + BEGIN_BATCH(8, 2); OUT_BATCH(CMD); OUT_BATCH(BR13); OUT_BATCH((0 << 16) | 0); @@ -102,226 +100,7 @@ intel_display_surface(struct egl_drm_drawable *draw, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - ADVANCE_BATCH(); - - fence = intel_batchbuffer_flush(intel->batch); + fence = intel_be_batchbuffer_flush(intel->base.batch); driFenceUnReference(&fence); - intel_batchbuffer_finish(intel->batch); -} - -#if 0 -/** - * Display a colorbuffer surface in an X window. - * Used for SwapBuffers and flushing front buffer rendering. - * - * \param dPriv the window/drawable to display into - * \param surf the surface to display - * \param rect optional subrect of surface to display (may be NULL). - */ -void -intelDisplaySurface(__DRIdrawablePrivate *dPriv, - struct pipe_surface *surf, - const drm_clip_rect_t *rect) -{ - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - //struct intel_context *intel = intelScreen->dummyContext; - - DBG(SWAP, "%s\n", __FUNCTION__); - -#if 0 - if (!intel) { - /* XXX this is where some kind of extra/meta context could be useful */ - return; - } -#endif - - if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); - driFenceUnReference(&intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - intel->last_swap_fence = intel->first_swap_fence; - intel->first_swap_fence = NULL; - - /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets - * should work regardless. - */ - LOCK_HARDWARE(intel); - /* if this drawable isn't currently bound the LOCK_HARDWARE done on the - * current context (which is what intelScreenContext should return) might - * not get a contended lock and thus cliprects not updated (tests/manywin) - */ - if (intel_context(dPriv->driContextPriv) != intel) - DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); - - - if (dPriv && dPriv->numClipRects) { - const int srcWidth = surf->width; - const int srcHeight = surf->height; - const int nbox = dPriv->numClipRects; - const drm_clip_rect_t *pbox = dPriv->pClipRects; - const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; - const int cpp = intelScreen->front.cpp; - const int srcpitch = surf->pitch; - int BR13, CMD; - int i; - - ASSERT(surf->buffer); - ASSERT(surf->cpp == cpp); - - DBG(SWAP, "screen pitch %d src surface pitch %d\n", - pitch, surf->pitch); - - if (cpp == 2) { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); - CMD = XY_SRC_COPY_BLT_CMD; - } - else { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - } - - for (i = 0; i < nbox; i++, pbox++) { - drm_clip_rect_t box; - drm_clip_rect_t sbox; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > intelScreen->front.width || - pbox->y2 > intelScreen->front.height) { - /* invalid cliprect, skip it */ - continue; - } - - box = *pbox; - - if (rect) { - /* intersect cliprect with user-provided src rect */ - drm_clip_rect_t rrect; - - rrect.x1 = dPriv->x + rect->x1; - rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; - rrect.x2 = rect->x2 + rrect.x1; - rrect.y2 = rect->y2 + rrect.y1; - if (rrect.x1 > box.x1) - box.x1 = rrect.x1; - if (rrect.y1 > box.y1) - box.y1 = rrect.y1; - if (rrect.x2 < box.x2) - box.x2 = rrect.x2; - if (rrect.y2 < box.y2) - box.y2 = rrect.y2; - - if (box.x1 > box.x2 || box.y1 > box.y2) - continue; - } - - /* restrict blit to size of actually rendered area */ - if (box.x2 - box.x1 > srcWidth) - box.x2 = srcWidth + box.x1; - if (box.y2 - box.y1 > srcHeight) - box.y2 = srcHeight + box.y1; - - DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", - box.x1, box.x2, box.y1, box.y2); - - sbox.x1 = box.x1 - dPriv->x; - sbox.y1 = box.y1 - dPriv->y; - - assert(box.x1 < box.x2); - assert(box.y1 < box.y2); - - /* XXX this could be done with pipe->surface_copy() */ - BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((box.y1 << 16) | box.x1); - OUT_BATCH((box.y2 << 16) | box.x2); - - OUT_RELOC(intelScreen->front.buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); - OUT_BATCH((sbox.y1 << 16) | sbox.x1); - OUT_BATCH((srcpitch * cpp) & 0xffff); - OUT_RELOC(dri_bo(surf->buffer), - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - - ADVANCE_BATCH(); - } - - if (intel->first_swap_fence) - driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); - } - - UNLOCK_HARDWARE(intel); - - if (intel->lastStamp != dPriv->lastStamp) { - intelUpdateWindowSize(dPriv); - intel->lastStamp = dPriv->lastStamp; - } -} - - - -/** - * This will be called whenever the currently bound window is moved/resized. - */ -void -intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) -{ - struct intel_framebuffer *intelfb = intel_framebuffer(dPriv); - assert(intelfb->stfb); - st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); -} - - - -void -intelSwapBuffers(__DRIdrawablePrivate * dPriv) -{ - struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_surface *back_surf; - - assert(intel_fb); - assert(intel_fb->stfb); - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_surf) { - st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_surf, NULL); - st_notify_swapbuffers_complete(intel_fb->stfb); - } -} - - -/** - * Called via glXCopySubBufferMESA() to copy a subrect of the back - * buffer to the front buffer/screen. - */ -void -intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) -{ - struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_surface *back_surf; - - assert(intel_fb); - assert(intel_fb->stfb); - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_surf) { - drm_clip_rect_t rect; - rect.x1 = x; - rect.y1 = y; - rect.x2 = w; - rect.y2 = h; - - st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_surf, &rect); - } + intel_be_batchbuffer_finish(intel->base.batch); } -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h deleted file mode 100644 index 904f26732e..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 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. - * - **************************************************************************/ - -#ifndef INTEL_SWAPBUFFERS_H -#define INTEL_SWAPBUFFERS_H - - -struct pipe_surface; - -#if 0 -extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, - struct pipe_surface *surf, - const drm_clip_rect_t * rect); - -extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); - -extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, - int x, int y, int w, int h); - -extern void intelUpdateWindowSize(__DRIdrawablePrivate *dPriv); -#endif - -#endif /* INTEL_SWAPBUFFERS_H */ diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys.h b/src/gallium/winsys/egl_drm/intel/intel_winsys.h deleted file mode 100644 index d0a319f9a4..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_winsys.h +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 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. - * - **************************************************************************/ - -#ifndef INTEL_WINSYS_H -#define INTEL_WINSYS_H - -#include "pipe/p_state.h" - -struct intel_context; -struct pipe_context; -struct pipe_winsys; -struct pipe_buffer; -struct _DriBufferObject; - -struct pipe_winsys * -intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ); - -void -intel_destroy_pipe_winsys( struct pipe_winsys *winsys ); - -struct pipe_context * -intel_create_softpipe( struct intel_context *intel, - struct pipe_winsys *winsys ); - -struct pipe_context * -intel_create_i915simple( struct intel_context *intel, - struct pipe_winsys *winsys ); - - -struct intel_buffer { - struct pipe_buffer base; - struct _DriBufferObject *driBO; -}; - -static INLINE struct intel_buffer * -intel_buffer( struct pipe_buffer *buf ) -{ - return (struct intel_buffer *)buf; -} - -static INLINE struct _DriBufferObject * -dri_bo( struct pipe_buffer *buf ) -{ - return intel_buffer(buf)->driBO; -} - - - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c deleted file mode 100644 index 8ec5c7e82a..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c +++ /dev/null @@ -1,184 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" - -#include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_winsys.h" - -#include "pipe/p_util.h" -#include "pipe/p_winsys.h" -#include "i915simple/i915_winsys.h" -#include "i915simple/i915_screen.h" - - -struct intel_i915_winsys { - struct i915_winsys winsys; /**< batch buffer funcs */ - struct pipe_winsys *pws; - struct intel_context *intel; -}; - - -/* Turn a i915simple winsys into an intel/i915simple winsys: - */ -static inline struct intel_i915_winsys * -intel_i915_winsys( struct i915_winsys *sws ) -{ - return (struct intel_i915_winsys *)sws; -} - - -/* Simple batchbuffer interface: - */ - -static unsigned *intel_i915_batch_start( struct i915_winsys *sws, - unsigned dwords, - unsigned relocs ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - - /* XXX: check relocs. - */ - if (intel_batchbuffer_space( intel->batch ) >= dwords * 4) { - /* XXX: Hmm, the driver can't really do much with this pointer: - */ - return (unsigned *)intel->batch->ptr; - } - else - return NULL; -} - -static void intel_i915_batch_dword( struct i915_winsys *sws, - unsigned dword ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - intel_batchbuffer_emit_dword( intel->batch, dword ); -} - -static void intel_i915_batch_reloc( struct i915_winsys *sws, - struct pipe_buffer *buf, - unsigned access_flags, - unsigned delta ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - unsigned flags = DRM_BO_FLAG_MEM_TT; - unsigned mask = DRM_BO_MASK_MEM; - - if (access_flags & I915_BUFFER_ACCESS_WRITE) { - flags |= DRM_BO_FLAG_WRITE; - mask |= DRM_BO_FLAG_WRITE; - } - - if (access_flags & I915_BUFFER_ACCESS_READ) { - flags |= DRM_BO_FLAG_READ; - mask |= DRM_BO_FLAG_READ; - } - -#if 0 /* JB old */ - intel_batchbuffer_emit_reloc( intel->batch, - dri_bo( buf ), - flags, mask, - delta ); -#else /* new */ - intel_offset_relocation( intel->batch, - delta, - dri_bo( buf ), - flags, - mask ); -#endif -} - - - -static void intel_i915_batch_flush( struct i915_winsys *sws, - struct pipe_fence_handle **fence ) -{ - struct intel_i915_winsys *iws = intel_i915_winsys(sws); - struct intel_context *intel = iws->intel; - union { - struct _DriFenceObject *dri; - struct pipe_fence_handle *pipe; - } fu; - - if (fence) - assert(!*fence); - - fu.dri = intel_batchbuffer_flush( intel->batch ); - - if (!fu.dri) { - assert(0); - *fence = NULL; - return; - } - - if (fu.dri) { - if (fence) - *fence = fu.pipe; - else - driFenceUnReference(&fu.dri); - } - -} - - -/** - * Create i915 hardware rendering context. - */ -struct pipe_context * -intel_create_i915simple( struct intel_context *intel, - struct pipe_winsys *winsys ) -{ - struct intel_i915_winsys *iws = CALLOC_STRUCT( intel_i915_winsys ); - struct pipe_screen *screen; - - /* Fill in this struct with callbacks that i915simple will need to - * communicate with the window system, buffer manager, etc. - */ - iws->winsys.batch_start = intel_i915_batch_start; - iws->winsys.batch_dword = intel_i915_batch_dword; - iws->winsys.batch_reloc = intel_i915_batch_reloc; - iws->winsys.batch_flush = intel_i915_batch_flush; - iws->pws = winsys; - iws->intel = intel; - - screen = i915_create_screen(winsys, PCI_CHIP_I945_GM); - assert(screen); - - /* Create the i915simple context: - */ - return i915_create_context( screen, - winsys, - &iws->winsys ); -} diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c deleted file mode 100644 index 8bf8c21439..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c +++ /dev/null @@ -1,338 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include -#include -//#include "dri_bufpool.h" -//#include "dri_bufmgr.h" - -#include "intel_context.h" -#include "intel_winsys.h" -#include "intel_swapbuffers.h" -#include "intel_batchbuffer.h" - -#include "pipe/p_winsys.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" - - - -struct intel_pipe_winsys { - struct pipe_winsys winsys; - struct _DriBufferPool *regionPool; - struct _DriFreeSlabManager *fMan; -}; - - - -/* Turn a pipe winsys into an intel/pipe winsys: - */ -static inline struct intel_pipe_winsys * -intel_pipe_winsys( struct pipe_winsys *winsys ) -{ - return (struct intel_pipe_winsys *)winsys; -} - - -/* Most callbacks map direcly onto dri_bufmgr operations: - */ -static void *intel_buffer_map(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned flags ) -{ - unsigned drm_flags = 0; - - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) - drm_flags |= DRM_BO_FLAG_WRITE; - - if (flags & PIPE_BUFFER_USAGE_CPU_READ) - drm_flags |= DRM_BO_FLAG_READ; - - return driBOMap( dri_bo(buf), drm_flags, 0 ); -} - -static void intel_buffer_unmap(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - driBOUnmap( dri_bo(buf) ); -} - - -static void -intel_buffer_destroy(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - driBOUnReference( dri_bo(buf) ); - FREE(buf); -} - - -/* Pipe has no concept of pools. We choose the tex/region pool - * for all buffers. - * Grabs the hardware lock! - */ -static struct pipe_buffer * -intel_buffer_create(struct pipe_winsys *winsys, - unsigned alignment, - unsigned usage, - unsigned size ) -{ - struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); - struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); - unsigned flags = 0; - - buffer->base.refcount = 1; - buffer->base.alignment = alignment; - buffer->base.usage = usage; - buffer->base.size = size; - - if (usage & (PIPE_BUFFER_USAGE_VERTEX /*| IWS_BUFFER_USAGE_LOCAL*/)) { - flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; - } else { - flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; - } - - if (usage & PIPE_BUFFER_USAGE_GPU_READ) - flags |= DRM_BO_FLAG_READ; - - if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) - flags |= DRM_BO_FLAG_WRITE; - - /* drm complains if we don't set any read/write flags. - */ - if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) - flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - -#if 0 - if (flags & IWS_BUFFER_USAGE_EXE) - flags |= DRM_BO_FLAG_EXE; - - if (usage & IWS_BUFFER_USAGE_CACHED) - flags |= DRM_BO_FLAG_CACHED; -#endif - - driGenBuffers( iws->regionPool, - "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); - - driBOData( buffer->driBO, size, NULL, iws->regionPool, 0 ); - - return &buffer->base; -} - - -static struct pipe_buffer * -intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) -{ - struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); - struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); - - driGenUserBuffer( iws->regionPool, - "pipe user buffer", &buffer->driBO, ptr, bytes ); - - buffer->base.refcount = 1; - - return &buffer->base; -} - - -/* The state tracker (should!) keep track of whether the fake - * frontbuffer has been touched by any rendering since the last time - * we copied its contents to the real frontbuffer. Our task is easy: - */ -static void -intel_flush_frontbuffer( struct pipe_winsys *winsys, - struct pipe_surface *surf, - void *context_private) -{ -#if 0 - struct intel_context *intel = (struct intel_context *) context_private; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - intelDisplaySurface(dPriv, surf, NULL); -#endif -} - - -static struct pipe_surface * -intel_i915_surface_alloc(struct pipe_winsys *winsys) -{ - struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); - if (surf) { - surf->refcount = 1; - surf->winsys = winsys; - } - return surf; -} - - -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - -/** - * Copied from xm_winsys.c - */ -static int -intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, - unsigned width, unsigned height, - enum pipe_format format, - unsigned flags) -{ - const unsigned alignment = 64; - //int ret; - - surf->width = width; - surf->height = height; - surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); - if(!surf->buffer) - return -1; - - return 0; -} - - -static void -intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - pipe_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; -} - - - -static const char * -intel_get_name( struct pipe_winsys *winsys ) -{ - return "Intel/EGL/ttm"; -} - -static void -intel_fence_reference( struct pipe_winsys *sws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence ) -{ - if (*ptr) - driFenceUnReference((struct _DriFenceObject **)ptr); - - if (fence) - *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); -} - -static int -intel_fence_signalled( struct pipe_winsys *sws, - struct pipe_fence_handle *fence, - unsigned flag ) -{ - return driFenceSignaled((struct _DriFenceObject *)fence, flag); -} - -static int -intel_fence_finish( struct pipe_winsys *sws, - struct pipe_fence_handle *fence, - unsigned flag ) -{ - /* JB: Lets allways lazy wait */ - return driFenceFinish((struct _DriFenceObject *)fence, flag, 1); -} - -struct pipe_winsys * -intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) -{ - struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys ); - - /* Fill in this struct with callbacks that pipe will need to - * communicate with the window system, buffer manager, etc. - * - * Pipe would be happy with a malloc based memory manager, but - * the SwapBuffers implementation in this winsys driver requires - * that rendering be done to an appropriate _DriBufferObject. - */ - iws->winsys.buffer_create = intel_buffer_create; - iws->winsys.user_buffer_create = intel_user_buffer_create; - iws->winsys.buffer_map = intel_buffer_map; - iws->winsys.buffer_unmap = intel_buffer_unmap; - iws->winsys.buffer_destroy = intel_buffer_destroy; - iws->winsys.flush_frontbuffer = intel_flush_frontbuffer; - iws->winsys.get_name = intel_get_name; - iws->winsys.surface_alloc = intel_i915_surface_alloc; - iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; - iws->winsys.surface_release = intel_i915_surface_release; - - iws->winsys.fence_reference = intel_fence_reference; - iws->winsys.fence_signalled = intel_fence_signalled; - iws->winsys.fence_finish = intel_fence_finish; - - if (fd) - iws->regionPool = driSlabPoolInit(fd, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - 64, 6, 16, 4096, 0, - fMan); - - return &iws->winsys; -} - - -void -intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) -{ - struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); - if (iws->regionPool) { - driPoolTakeDown(iws->regionPool); - } - free(iws); -} - diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c deleted file mode 100644 index 0bc2dc4002..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include "intel_context.h" -#include "intel_winsys.h" -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "pipe/p_format.h" -#include "softpipe/sp_winsys.h" - - -struct intel_softpipe_winsys { - struct softpipe_winsys sws; - struct intel_context *intel; -}; - -/** - * Return list of surface formats supported by this driver. - */ -static boolean -intel_is_format_supported(struct softpipe_winsys *sws, - enum pipe_format format) -{ - switch(format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_S8Z24_UNORM: - return TRUE; - default: - return FALSE; - } -} - - -/** - * Create rendering context which uses software rendering. - */ -struct pipe_context * -intel_create_softpipe( struct intel_context *intel, - struct pipe_winsys *winsys ) -{ - struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); - struct pipe_screen *screen = softpipe_create_screen(winsys); - - /* Fill in this struct with callbacks that softpipe will need to - * communicate with the window system, buffer manager, etc. - */ - isws->sws.is_format_supported = intel_is_format_supported; - isws->intel = intel; - - /* Create the softpipe context: - */ - return softpipe_create( screen, winsys, &isws->sws ); -} diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c deleted file mode 100644 index 1bc1089352..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c +++ /dev/null @@ -1,953 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - * Keith Whitwell - */ - -#include -#include -#include "glthread.h" -#include "errno.h" -#include "ws_dri_bufmgr.h" -#include "string.h" -#include "imports.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" - -/* - * This lock is here to protect drmBO structs changing underneath us during a - * validate list call, since validatelist cannot take individiual locks for - * each drmBO. Validatelist takes this lock in write mode. Any access to an - * individual drmBO should take this lock in read mode, since in that case, the - * driBufferObject mutex will protect the access. Locking order is - * driBufferObject mutex - > this rw lock. - */ - -_glthread_DECLARE_STATIC_MUTEX(bmMutex); -_glthread_DECLARE_STATIC_COND(bmCond); - -static int kernelReaders = 0; -static int num_buffers = 0; -static int num_user_buffers = 0; - -static drmBO *drmBOListBuf(void *iterator) -{ - drmBONode *node; - drmMMListHead *l = (drmMMListHead *) iterator; - node = DRMLISTENTRY(drmBONode, l, head); - return node->buf; -} - -static void *drmBOListIterator(drmBOList *list) -{ - void *ret = list->list.next; - - if (ret == &list->list) - return NULL; - return ret; -} - -static void *drmBOListNext(drmBOList *list, void *iterator) -{ - void *ret; - - drmMMListHead *l = (drmMMListHead *) iterator; - ret = l->next; - if (ret == &list->list) - return NULL; - return ret; -} - -static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, - uint64_t arg0, - uint64_t arg1) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->free.next; - if (l == &list->free) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - return NULL; - } - list->numCurrent++; - } - else { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - } - node->buf = item; - node->arg0 = arg0; - node->arg1 = arg1; - DRMLISTADD(&node->head, &list->list); - list->numOnList++; - return node; -} - -static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, - uint64_t mask, int *newItem) -{ - drmBONode *node, *cur; - drmMMListHead *l; - - *newItem = 0; - cur = NULL; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - if (node->buf == buf) { - cur = node; - break; - } - } - if (!cur) { - cur = drmAddListItem(list, buf, flags, mask); - if (!cur) { - return -ENOMEM; - } - *newItem = 1; - cur->arg0 = flags; - cur->arg1 = mask; - } - else { - uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; - uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; - - if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { - return -EINVAL; - } - - cur->arg1 |= mask; - cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); - - if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && - (cur->arg0 & DRM_BO_MASK_MEM) == 0) { - return -EINVAL; - } - } - return 0; -} - -static void drmBOFreeList(drmBOList *list) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->list.next; - while(l != &list->list) { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - l = list->list.next; - list->numCurrent--; - list->numOnList--; - } - - l = list->free.next; - while(l != &list->free) { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - l = list->free.next; - list->numCurrent--; - } -} - -static int drmAdjustListNodes(drmBOList *list) -{ - drmBONode *node; - drmMMListHead *l; - int ret = 0; - - while(list->numCurrent < list->numTarget) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - ret = -ENOMEM; - break; - } - list->numCurrent++; - DRMLISTADD(&node->head, &list->free); - } - - while(list->numCurrent > list->numTarget) { - l = list->free.next; - if (l == &list->free) - break; - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - list->numCurrent--; - } - return ret; -} - -static int drmBOCreateList(int numTarget, drmBOList *list) -{ - DRMINITLISTHEAD(&list->list); - DRMINITLISTHEAD(&list->free); - list->numTarget = numTarget; - list->numCurrent = 0; - list->numOnList = 0; - return drmAdjustListNodes(list); -} - -static int drmBOResetList(drmBOList *list) -{ - drmMMListHead *l; - int ret; - - ret = drmAdjustListNodes(list); - if (ret) - return ret; - - l = list->list.next; - while (l != &list->list) { - DRMLISTDEL(l); - DRMLISTADD(l, &list->free); - list->numOnList--; - l = list->list.next; - } - return drmAdjustListNodes(list); -} - -void driWriteLockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - while(kernelReaders != 0) - _glthread_COND_WAIT(bmCond, bmMutex); -} - -void driWriteUnlockKernelBO(void) -{ - _glthread_UNLOCK_MUTEX(bmMutex); -} - -void driReadLockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - kernelReaders++; - _glthread_UNLOCK_MUTEX(bmMutex); -} - -void driReadUnlockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - if (--kernelReaders == 0) - _glthread_COND_BROADCAST(bmCond); - _glthread_UNLOCK_MUTEX(bmMutex); -} - - - - -/* - * TODO: Introduce fence pools in the same way as - * buffer object pools. - */ - -typedef struct _DriBufferObject -{ - DriBufferPool *pool; - _glthread_Mutex mutex; - int refCount; - const char *name; - uint64_t flags; - unsigned hint; - unsigned alignment; - unsigned createdByReference; - void *private; - /* user-space buffer: */ - unsigned userBuffer; - void *userData; - unsigned userSize; -} DriBufferObject; - -typedef struct _DriBufferList { - drmBOList drmBuffers; /* List of kernel buffers needing validation */ - drmBOList driBuffers; /* List of user-space buffers needing validation */ -} DriBufferList; - - -void -bmError(int val, const char *file, const char *function, int line) -{ - _mesa_printf("Fatal video memory manager error \"%s\".\n" - "Check kernel logs or set the LIBGL_DEBUG\n" - "environment variable to \"verbose\" for more info.\n" - "Detected in file %s, line %d, function %s.\n", - strerror(-val), file, line, function); -#ifndef NDEBUG - abort(); -#else - abort(); -#endif -} - -extern drmBO * -driBOKernel(struct _DriBufferObject *buf) -{ - drmBO *ret; - - driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); - assert(buf->private != NULL); - ret = buf->pool->kernel(buf->pool, buf->private); - if (!ret) - BM_CKFATAL(-EINVAL); - _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); - - return ret; -} - -void -driBOWaitIdle(struct _DriBufferObject *buf, int lazy) -{ - - /* - * This function may block. Is it sane to keep the mutex held during - * that time?? - */ - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void * -driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) -{ - void *virtual; - int retval; - - if (buf->userBuffer) { - return buf->userData; - } - - _glthread_LOCK_MUTEX(buf->mutex); - assert(buf->private != NULL); - retval = buf->pool->map(buf->pool, buf->private, flags, hint, - &buf->mutex, &virtual); - _glthread_UNLOCK_MUTEX(buf->mutex); - - return retval == 0 ? virtual : NULL; -} - -void -driBOUnmap(struct _DriBufferObject *buf) -{ - if (buf->userBuffer) - return; - - assert(buf->private != NULL); - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -unsigned long -driBOOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->offset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -unsigned long -driBOPoolOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->poolOffset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -uint64_t -driBOFlags(struct _DriBufferObject *buf) -{ - uint64_t ret; - - assert(buf->private != NULL); - - driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->flags(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); - return ret; -} - -struct _DriBufferObject * -driBOReference(struct _DriBufferObject *buf) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (++buf->refCount == 1) { - _glthread_UNLOCK_MUTEX(buf->mutex); - BM_CKFATAL(-EINVAL); - } - _glthread_UNLOCK_MUTEX(buf->mutex); - return buf; -} - -void -driBOUnReference(struct _DriBufferObject *buf) -{ - int tmp; - - if (!buf) - return; - - _glthread_LOCK_MUTEX(buf->mutex); - tmp = --buf->refCount; - if (!tmp) { - _glthread_UNLOCK_MUTEX(buf->mutex); - if (buf->private) { - if (buf->createdByReference) - buf->pool->unreference(buf->pool, buf->private); - else - buf->pool->destroy(buf->pool, buf->private); - } - if (buf->userBuffer) - num_user_buffers--; - else - num_buffers--; - free(buf); - } else - _glthread_UNLOCK_MUTEX(buf->mutex); - -} - - -int -driBOData(struct _DriBufferObject *buf, - unsigned size, const void *data, - DriBufferPool *newPool, - uint64_t flags) -{ - void *virtual = NULL; - int newBuffer; - int retval = 0; - struct _DriBufferPool *pool; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - pool = buf->pool; - - if (pool == NULL && newPool != NULL) { - buf->pool = newPool; - pool = newPool; - } - if (newPool == NULL) - newPool = pool; - - if (!pool->create) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "driBOData called on invalid buffer\n"); - BM_CKFATAL(-EINVAL); - } - - newBuffer = (!buf->private || pool != newPool || - pool->size(pool, buf->private) < size); - - if (!flags) - flags = buf->flags; - - if (newBuffer) { - - if (buf->createdByReference) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "driBOData requiring resizing called on " - "shared buffer.\n"); - BM_CKFATAL(-EINVAL); - } - - if (buf->private) - buf->pool->destroy(buf->pool, buf->private); - - pool = newPool; - buf->pool = newPool; - buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, - buf->alignment); - if (!buf->private) - retval = -ENOMEM; - - if (retval == 0) - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); - } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { - /* - * Buffer is busy. need to create a new one. - */ - - void *newBuf; - - newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, - buf->alignment); - if (newBuf) { - buf->pool->destroy(buf->pool, buf->private); - buf->private = newBuf; - } - - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } else { - uint64_t flag_diff = flags ^ buf->flags; - - /* - * We might need to change buffer flags. - */ - - if (flag_diff){ - assert(pool->setStatus != NULL); - BM_CKFATAL(pool->unmap(pool, buf->private)); - BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, - buf->flags)); - if (!data) - goto out; - - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } - } - - if (retval == 0) { - if (data) - memcpy(virtual, data, size); - - BM_CKFATAL(pool->unmap(pool, buf->private)); - } - - out: - _glthread_UNLOCK_MUTEX(buf->mutex); - - return retval; -} - -void -driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, const void *data) -{ - void *virtual; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, - &virtual)); - memcpy((unsigned char *) virtual + offset, data, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, void *data) -{ - void *virtual; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); - memcpy(data, (unsigned char *) virtual + offset, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOSetReferenced(struct _DriBufferObject *buf, - unsigned long handle) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->private != NULL) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "Invalid buffer for setReferenced\n"); - BM_CKFATAL(-EINVAL); - - } - if (buf->pool->reference == NULL) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "Invalid buffer pool for setReferenced\n"); - BM_CKFATAL(-EINVAL); - } - buf->private = buf->pool->reference(buf->pool, handle); - if (!buf->private) { - _mesa_error(NULL, GL_OUT_OF_MEMORY, - "Invalid buffer pool for setStatic\n"); - BM_CKFATAL(-ENOMEM); - } - buf->createdByReference = GL_TRUE; - buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -int -driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, uint64_t flags, unsigned hint) -{ - struct _DriBufferObject *buf; - int i; - - flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - - ++num_buffers; - - assert(pool); - - for (i = 0; i < n; ++i) { - buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); - if (!buf) - return -ENOMEM; - - _glthread_INIT_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(buf->mutex); - buf->refCount = 1; - buf->flags = flags; - buf->hint = hint; - buf->name = name; - buf->alignment = alignment; - buf->pool = pool; - buf->createdByReference = 0; - _glthread_UNLOCK_MUTEX(buf->mutex); - buffers[i] = buf; - } - return 0; -} - -void -driGenUserBuffer(struct _DriBufferPool *pool, - const char *name, - struct _DriBufferObject **buffers, - void *ptr, unsigned bytes) -{ - const unsigned alignment = 1, flags = 0, hint = 0; - - --num_buffers; /* JB: is inced in GenBuffes */ - driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); - ++num_user_buffers; - - (*buffers)->userBuffer = 1; - (*buffers)->userData = ptr; - (*buffers)->userSize = bytes; -} - -void -driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) -{ - int i; - - for (i = 0; i < n; ++i) { - driBOUnReference(buffers[i]); - } -} - - -void -driInitBufMgr(int fd) -{ - ; -} - -/* - * Note that lists are per-context and don't need mutex protection. - */ - -struct _DriBufferList * -driBOCreateList(int target) -{ - struct _DriBufferList *list = calloc(sizeof(*list), 1); - - BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); - BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); - return list; -} - -int -driBOResetList(struct _DriBufferList * list) -{ - int ret; - ret = drmBOResetList(&list->drmBuffers); - if (ret) - return ret; - ret = drmBOResetList(&list->driBuffers); - return ret; -} - -void -driBOFreeList(struct _DriBufferList * list) -{ - drmBOFreeList(&list->drmBuffers); - drmBOFreeList(&list->driBuffers); - free(list); -} - - -/* - * Copied from libdrm, because it is needed by driAddValidateItem. - */ - -static drmBONode * -driAddListItem(drmBOList * list, drmBO * item, - uint64_t arg0, uint64_t arg1) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->free.next; - if (l == &list->free) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - return NULL; - } - list->numCurrent++; - } else { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - } - memset(&node->bo_arg, 0, sizeof(node->bo_arg)); - node->buf = item; - node->arg0 = arg0; - node->arg1 = arg1; - DRMLISTADDTAIL(&node->head, &list->list); - list->numOnList++; - return node; -} - -/* - * Slightly modified version compared to the libdrm version. - * This one returns the list index of the buffer put on the list. - */ - -static int -driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, - uint64_t mask, int *itemLoc, - struct _drmBONode **pnode) -{ - drmBONode *node, *cur; - drmMMListHead *l; - int count = 0; - - cur = NULL; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - if (node->buf == buf) { - cur = node; - break; - } - count++; - } - if (!cur) { - cur = driAddListItem(list, buf, flags, mask); - if (!cur) - return -ENOMEM; - - cur->arg0 = flags; - cur->arg1 = mask; - } else { - uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; - uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; - - if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { - return -EINVAL; - } - - cur->arg1 |= mask; - cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); - - if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && - (cur->arg0 & DRM_BO_MASK_MEM) == 0) { - return -EINVAL; - } - } - *itemLoc = count; - *pnode = cur; - return 0; -} - - -void -driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, - uint64_t flags, uint64_t mask, int *itemLoc, - struct _drmBONode **node) -{ - int newItem; - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(driAddValidateItem(&list->drmBuffers, - buf->pool->kernel(buf->pool, buf->private), - flags, mask, itemLoc, node)); - BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, - flags, mask, &newItem)); - if (newItem) - buf->refCount++; - - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -drmBOList *driGetdrmBOList(struct _DriBufferList *list) -{ - driWriteLockKernelBO(); - return &list->drmBuffers; -} - -void driPutdrmBOList(struct _DriBufferList *list) -{ - driWriteUnlockKernelBO(); -} - - -void -driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->pool->fence) - BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); - _glthread_UNLOCK_MUTEX(buf->mutex); - -} - -void -driBOUnrefUserList(struct _DriBufferList *list) -{ - struct _DriBufferObject *buf; - void *curBuf; - - curBuf = drmBOListIterator(&list->driBuffers); - while (curBuf) { - buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); - driBOUnReference(buf); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } -} - -struct _DriFenceObject * -driBOFenceUserList(struct _DriFenceMgr *mgr, - struct _DriBufferList *list, const char *name, - drmFence *kFence) -{ - struct _DriFenceObject *fence; - struct _DriBufferObject *buf; - void *curBuf; - - fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, - kFence, sizeof(*kFence)); - curBuf = drmBOListIterator(&list->driBuffers); - - /* - * User-space fencing callbacks. - */ - - while (curBuf) { - buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - driBOFence(buf, fence); - driBOUnReference(buf); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } - - driBOResetList(list); - return fence; -} - -void -driBOValidateUserList(struct _DriBufferList * list) -{ - void *curBuf; - struct _DriBufferObject *buf; - - curBuf = drmBOListIterator(&list->driBuffers); - - /* - * User-space validation callbacks. - */ - - while (curBuf) { - buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->pool->validate) - BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); - _glthread_UNLOCK_MUTEX(buf->mutex); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } -} - - -void -driPoolTakeDown(struct _DriBufferPool *pool) -{ - pool->takeDown(pool); - -} - -unsigned long -driBOSize(struct _DriBufferObject *buf) -{ - unsigned long size; - - _glthread_LOCK_MUTEX(buf->mutex); - size = buf->pool->size(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - - return size; - -} - -drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) -{ - return &list->drmBuffers; -} - -drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) -{ - return &list->driBuffers; -} - diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h deleted file mode 100644 index fdaf5ee93a..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - * Keith Whitwell - */ - -#ifndef _PSB_BUFMGR_H_ -#define _PSB_BUFMGR_H_ -#include -#include "i915_drm.h" -#include "ws_dri_fencemgr.h" - -typedef struct _drmBONode -{ - drmMMListHead head; - drmBO *buf; - struct drm_i915_op_arg bo_arg; - uint64_t arg0; - uint64_t arg1; -} drmBONode; - -typedef struct _drmBOList { - unsigned numTarget; - unsigned numCurrent; - unsigned numOnList; - drmMMListHead list; - drmMMListHead free; -} drmBOList; - - -struct _DriFenceObject; -struct _DriBufferObject; -struct _DriBufferPool; -struct _DriBufferList; - -/* - * Return a pointer to the libdrm buffer object this DriBufferObject - * uses. - */ - -extern drmBO *driBOKernel(struct _DriBufferObject *buf); -extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, - unsigned hint); -extern void driBOUnmap(struct _DriBufferObject *buf); -extern unsigned long driBOOffset(struct _DriBufferObject *buf); -extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); - -extern uint64_t driBOFlags(struct _DriBufferObject *buf); -extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); -extern void driBOUnReference(struct _DriBufferObject *buf); - -extern int driBOData(struct _DriBufferObject *r_buf, - unsigned size, const void *data, - struct _DriBufferPool *pool, uint64_t flags); - -extern void driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - const void *data); -extern void driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - void *data); -extern int driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, uint64_t flags, unsigned hint); -extern void driGenUserBuffer(struct _DriBufferPool *pool, - const char *name, - struct _DriBufferObject *buffers[], - void *ptr, unsigned bytes); -extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); -extern void driInitBufMgr(int fd); -extern struct _DriBufferList *driBOCreateList(int target); -extern int driBOResetList(struct _DriBufferList * list); -extern void driBOAddListItem(struct _DriBufferList * list, - struct _DriBufferObject *buf, - uint64_t flags, uint64_t mask, int *itemLoc, - struct _drmBONode **node); - -extern void driBOValidateList(int fd, struct _DriBufferList * list); -extern void driBOFreeList(struct _DriBufferList * list); -extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, - struct _DriBufferList *list, - const char *name, - drmFence *kFence); -extern void driBOUnrefUserList(struct _DriBufferList *list); -extern void driBOValidateUserList(struct _DriBufferList * list); -extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); -extern void driPutdrmBOList(struct _DriBufferList *list); - -extern void driBOFence(struct _DriBufferObject *buf, - struct _DriFenceObject *fence); - -extern void driPoolTakeDown(struct _DriBufferPool *pool); -extern void driBOSetReferenced(struct _DriBufferObject *buf, - unsigned long handle); -unsigned long driBOSize(struct _DriBufferObject *buf); -extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); -extern void driPoolTakeDown(struct _DriBufferPool *pool); - -extern void driReadLockKernelBO(void); -extern void driReadUnlockKernelBO(void); -extern void driWriteLockKernelBO(void); -extern void driWriteUnlockKernelBO(void); - -/* - * For debugging purposes. - */ - -extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); -extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); -#endif diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h b/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h deleted file mode 100644 index 3a302e13d3..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - */ - -#ifndef _PSB_BUFPOOL_H_ -#define _PSB_BUFPOOL_H_ - -#include -#include -struct _DriFenceObject; - -typedef struct _DriBufferPool -{ - int fd; - int (*map) (struct _DriBufferPool * pool, void *private, - unsigned flags, int hint, _glthread_Mutex *mutex, - void **virtual); - int (*unmap) (struct _DriBufferPool * pool, void *private); - int (*destroy) (struct _DriBufferPool * pool, void *private); - unsigned long (*offset) (struct _DriBufferPool * pool, void *private); - unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); - uint64_t (*flags) (struct _DriBufferPool * pool, void *private); - unsigned long (*size) (struct _DriBufferPool * pool, void *private); - void *(*create) (struct _DriBufferPool * pool, unsigned long size, - uint64_t flags, unsigned hint, unsigned alignment); - void *(*reference) (struct _DriBufferPool * pool, unsigned handle); - int (*unreference) (struct _DriBufferPool * pool, void *private); - int (*fence) (struct _DriBufferPool * pool, void *private, - struct _DriFenceObject * fence); - drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); - int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); - int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, - int lazy); - int (*setStatus) (struct _DriBufferPool *pool, void *private, - uint64_t flag_diff, uint64_t old_flags); - void (*takeDown) (struct _DriBufferPool * pool); - void *data; -} DriBufferPool; - -extern void bmError(int val, const char *file, const char *function, - int line); -#define BM_CKFATAL(val) \ - do{ \ - int tstVal = (val); \ - if (tstVal) \ - bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ - } while(0); - - -/* - * Builtin pools. - */ - -/* - * Kernel buffer objects. Size in multiples of page size. Page size aligned. - */ - -extern struct _DriBufferPool *driDRMPoolInit(int fd); -extern struct _DriBufferPool *driMallocPoolInit(void); - -struct _DriFreeSlabManager; -extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, - uint64_t validMask, - uint32_t smallestSize, - uint32_t numSizes, - uint32_t desiredNumBuffers, - uint32_t maxSlabSize, - uint32_t pageAlignment, - struct _DriFreeSlabManager *fMan); -extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); -extern struct _DriFreeSlabManager * -driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); - - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c deleted file mode 100644 index 7c55dbc674..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c +++ /dev/null @@ -1,268 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - */ - -#include -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" -#include "assert.h" - -/* - * Buffer pool implementation using DRM buffer objects as DRI buffer objects. - */ - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, uint64_t flags, unsigned hint, - unsigned alignment) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - unsigned pageSize = getpagesize(); - - if (!buf) - return NULL; - - if ((alignment > pageSize) && (alignment % pageSize)) { - free(buf); - return NULL; - } - - ret = drmBOCreate(pool->fd, size, alignment / pageSize, - NULL, - flags, hint, buf); - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static void * -pool_reference(struct _DriBufferPool *pool, unsigned handle) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - - if (!buf) - return NULL; - - ret = drmBOReference(pool->fd, handle, buf); - - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); - ret = drmBOUnreference(pool->fd, buf); - free(buf); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_unreference(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); - ret = drmBOUnreference(pool->fd, buf); - free(buf); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOMap(pool->fd, buf, flags, hint, virtual); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOUnmap(pool->fd, buf); - driReadUnlockKernelBO(); - - return ret; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - unsigned long offset; - - driReadLockKernelBO(); - assert(buf->flags & DRM_BO_FLAG_NO_MOVE); - offset = buf->offset; - driReadUnlockKernelBO(); - - return buf->offset; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - return 0; -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - uint64_t flags; - - driReadLockKernelBO(); - flags = buf->flags; - driReadUnlockKernelBO(); - - return flags; -} - - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - unsigned long size; - - driReadLockKernelBO(); - size = buf->size; - driReadUnlockKernelBO(); - - return buf->size; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - /* - * Noop. The kernel handles all fencing. - */ - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - return (drmBO *) private; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, - int lazy) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); - driReadUnlockKernelBO(); - - return ret; -} - - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - -/*static int -pool_setStatus(struct _DriBufferPool *pool, void *private, - uint64_t flag_diff, uint64_t old_flags) -{ - drmBO *buf = (drmBO *) private; - uint64_t new_flags = old_flags ^ flag_diff; - int ret; - - driReadLockKernelBO(); - ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, - 0, 0, 0); - driReadUnlockKernelBO(); - return ret; -}*/ - -struct _DriBufferPool * -driDRMPoolInit(int fd) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - - if (!pool) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->poolOffset = &pool_poolOffset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - pool->reference = &pool_reference; - pool->unreference = &pool_unreference; - pool->data = NULL; - return pool; -} diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c deleted file mode 100644 index 1f893b47ce..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c +++ /dev/null @@ -1,377 +0,0 @@ -#include "ws_dri_fencemgr.h" -#include "glthread.h" -#include -#include -#include - -/* - * Note: Locking order is - * _DriFenceObject::mutex - * _DriFenceMgr::mutex - */ - -struct _DriFenceMgr { - /* - * Constant members. Need no mutex protection. - */ - struct _DriFenceMgrCreateInfo info; - void *private; - - /* - * These members are protected by this->mutex - */ - _glthread_Mutex mutex; - int refCount; - drmMMListHead *heads; - int num_fences; -}; - -struct _DriFenceObject { - - /* - * These members are constant and need no mutex protection. - */ - struct _DriFenceMgr *mgr; - uint32_t fence_class; - uint32_t fence_type; - - /* - * These members are protected by mgr->mutex. - */ - drmMMListHead head; - int refCount; - - /* - * These members are protected by this->mutex. - */ - _glthread_Mutex mutex; - uint32_t signaled_type; - void *private; -}; - -uint32_t -driFenceType(struct _DriFenceObject *fence) -{ - return fence->fence_type; -} - -struct _DriFenceMgr * -driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) -{ - struct _DriFenceMgr *tmp; - uint32_t i; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return NULL; - - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); - tmp->refCount = 1; - tmp->info = *info; - tmp->num_fences = 0; - tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); - if (!tmp->heads) - goto out_err; - - for (i=0; iinfo.num_classes; ++i) { - DRMINITLISTHEAD(&tmp->heads[i]); - } - _glthread_UNLOCK_MUTEX(tmp->mutex); - return tmp; - - out_err: - if (tmp) - free(tmp); - return NULL; -} - -static void -driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) -{ - struct _DriFenceMgr *mgr = *pMgr; - - *pMgr = NULL; - if (--mgr->refCount == 0) - free(mgr); - else - _glthread_UNLOCK_MUTEX(mgr->mutex); -} - -void -driFenceMgrUnReference(struct _DriFenceMgr **pMgr) -{ - _glthread_LOCK_MUTEX((*pMgr)->mutex); - driFenceMgrUnrefUnlock(pMgr); -} - -static void -driFenceUnReferenceLocked(struct _DriFenceObject **pFence) -{ - struct _DriFenceObject *fence = *pFence; - struct _DriFenceMgr *mgr = fence->mgr; - - *pFence = NULL; - if (--fence->refCount == 0) { - DRMLISTDELINIT(&fence->head); - if (fence->private) - mgr->info.unreference(mgr, &fence->private); - --mgr->num_fences; - fence->mgr = NULL; - --mgr->refCount; - free(fence); - - } -} - - -static void -driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, - drmMMListHead *list, - uint32_t fence_class, - uint32_t fence_type) -{ - struct _DriFenceObject *entry; - drmMMListHead *prev; - - while(list != &mgr->heads[fence_class]) { - entry = DRMLISTENTRY(struct _DriFenceObject, list, head); - - /* - * Up refcount so that entry doesn't disappear from under us - * when we unlock-relock mgr to get the correct locking order. - */ - - ++entry->refCount; - _glthread_UNLOCK_MUTEX(mgr->mutex); - _glthread_LOCK_MUTEX(entry->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); - - prev = list->prev; - - - - if (list->prev == list) { - - /* - * Somebody else removed the entry from the list. - */ - - _glthread_UNLOCK_MUTEX(entry->mutex); - driFenceUnReferenceLocked(&entry); - return; - } - - entry->signaled_type |= (fence_type & entry->fence_type); - if (entry->signaled_type == entry->fence_type) { - DRMLISTDELINIT(list); - mgr->info.unreference(mgr, &entry->private); - } - _glthread_UNLOCK_MUTEX(entry->mutex); - driFenceUnReferenceLocked(&entry); - list = prev; - } -} - - -int -driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, - int lazy_hint) -{ - struct _DriFenceMgr *mgr = fence->mgr; - int ret = 0; - - _glthread_LOCK_MUTEX(fence->mutex); - - if ((fence->signaled_type & fence_type) == fence_type) - goto out0; - - ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); - if (ret) - goto out0; - - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); - - driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, - fence_type); - _glthread_UNLOCK_MUTEX(mgr->mutex); - return 0; - - out0: - _glthread_UNLOCK_MUTEX(fence->mutex); - return ret; -} - -uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) -{ - uint32_t ret; - - _glthread_LOCK_MUTEX(fence->mutex); - ret = fence->signaled_type; - _glthread_UNLOCK_MUTEX(fence->mutex); - - return ret; -} - -int -driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, - uint32_t *signaled) -{ - int ret = 0; - struct _DriFenceMgr *mgr; - - _glthread_LOCK_MUTEX(fence->mutex); - mgr = fence->mgr; - *signaled = fence->signaled_type; - if ((fence->signaled_type & flush_type) == flush_type) - goto out0; - - ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); - if (ret) { - *signaled = fence->signaled_type; - goto out0; - } - - if ((fence->signaled_type | *signaled) == fence->signaled_type) - goto out0; - - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); - - driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, - *signaled); - - _glthread_UNLOCK_MUTEX(mgr->mutex); - return 0; - out0: - _glthread_UNLOCK_MUTEX(fence->mutex); - return ret; -} - -struct _DriFenceObject * -driFenceReference(struct _DriFenceObject *fence) -{ - _glthread_LOCK_MUTEX(fence->mgr->mutex); - ++fence->refCount; - _glthread_UNLOCK_MUTEX(fence->mgr->mutex); - return fence; -} - -void -driFenceUnReference(struct _DriFenceObject **pFence) -{ - struct _DriFenceMgr *mgr; - - if (*pFence == NULL) - return; - - mgr = (*pFence)->mgr; - _glthread_LOCK_MUTEX(mgr->mutex); - ++mgr->refCount; - driFenceUnReferenceLocked(pFence); - driFenceMgrUnrefUnlock(&mgr); -} - -struct _DriFenceObject -*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, - uint32_t fence_type, void *private, size_t private_size) -{ - struct _DriFenceObject *fence; - size_t fence_size = sizeof(*fence); - - if (private_size) - fence_size = ((fence_size + 15) & ~15); - - fence = calloc(1, fence_size + private_size); - - if (!fence) { - int ret = mgr->info.finish(mgr, private, fence_type, 0); - - if (ret) - usleep(10000000); - - return NULL; - } - - _glthread_INIT_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); - fence->refCount = 1; - DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); - fence->mgr = mgr; - ++mgr->refCount; - ++mgr->num_fences; - _glthread_UNLOCK_MUTEX(mgr->mutex); - fence->fence_class = fence_class; - fence->fence_type = fence_type; - fence->signaled_type = 0; - fence->private = private; - if (private_size) { - fence->private = (void *)(((uint8_t *) fence) + fence_size); - memcpy(fence->private, private, private_size); - } - - _glthread_UNLOCK_MUTEX(fence->mutex); - return fence; -} - - -static int -tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, - uint32_t *signaled_type) -{ - long fd = (long) mgr->private; - int dummy; - drmFence *fence = (drmFence *) private; - int ret; - - *signaled_type = 0; - ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); - if (ret) - return ret; - - *signaled_type = fence->signaled; - - return 0; -} - -static int -tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, - int lazy_hint) -{ - long fd = (long) mgr->private; - unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; - - return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); -} - -static int -tUnref(struct _DriFenceMgr *mgr, void **private) -{ - long fd = (long) mgr->private; - drmFence *fence = (drmFence *) *private; - *private = NULL; - - return drmFenceUnreference(fd, fence); -} - -struct _DriFenceMgr *driFenceMgrTTMInit(int fd) -{ - struct _DriFenceMgrCreateInfo info; - struct _DriFenceMgr *mgr; - - info.flags = DRI_FENCE_CLASS_ORDERED; - info.num_classes = 4; - info.signaled = tSignaled; - info.finish = tFinish; - info.unreference = tUnref; - - mgr = driFenceMgrCreate(&info); - if (mgr == NULL) - return NULL; - - mgr->private = (void *) (long) fd; - return mgr; -} - diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h deleted file mode 100644 index 4ea58dfe18..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef DRI_FENCEMGR_H -#define DRI_FENCEMGR_H - -#include -#include - -struct _DriFenceObject; -struct _DriFenceMgr; - -/* - * Do a quick check to see if the fence manager has registered the fence - * object as signaled. Note that this function may return a false negative - * answer. - */ -extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); - -/* - * Check if the fence object is signaled. This function can be substantially - * more expensive to call than the above function, but will not return a false - * negative answer. The argument "flush_type" sets the types that the - * underlying mechanism must make sure will eventually signal. - */ -extern int driFenceSignaledType(struct _DriFenceObject *fence, - uint32_t flush_type, uint32_t *signaled); - -/* - * Convenience functions. - */ - -static inline int driFenceSignaled(struct _DriFenceObject *fence, - uint32_t flush_type) -{ - uint32_t signaled_types; - int ret = driFenceSignaledType(fence, flush_type, &signaled_types); - if (ret) - return 0; - return ((signaled_types & flush_type) == flush_type); -} - -static inline int driFenceSignaledCached(struct _DriFenceObject *fence, - uint32_t flush_type) -{ - uint32_t signaled_types = - driFenceSignaledTypeCached(fence); - - return ((signaled_types & flush_type) == flush_type); -} - -/* - * Reference a fence object. - */ -extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); - -/* - * Unreference a fence object. The fence object pointer will be reset to NULL. - */ - -extern void driFenceUnReference(struct _DriFenceObject **pFence); - - -/* - * Wait for a fence to signal the indicated fence_type. - * If "lazy_hint" is true, it indicates that the wait may sleep to avoid - * busy-wait polling. - */ -extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, - int lazy_hint); - -/* - * Create a DriFenceObject for manager "mgr". - * - * "private" is a pointer that should be used for the callbacks in - * struct _DriFenceMgrCreateInfo. - * - * if private_size is nonzero, then the info stored at *private, with size - * private size will be copied and the fence manager will instead use a - * pointer to the copied data for the callbacks in - * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by - * "private" may be destroyed after the call to driFenceCreate. - */ -extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, - uint32_t fence_class, - uint32_t fence_type, - void *private, - size_t private_size); - -extern uint32_t driFenceType(struct _DriFenceObject *fence); - -/* - * Fence creations are ordered. If a fence signals a fence_type, - * it is safe to assume that all fences of the same class that was - * created before that fence has signaled the same type. - */ - -#define DRI_FENCE_CLASS_ORDERED (1 << 0) - -struct _DriFenceMgrCreateInfo { - uint32_t flags; - uint32_t num_classes; - int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, - uint32_t *signaled_type); - int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); - int (*unreference) (struct _DriFenceMgr *mgr, void **private); -}; - -extern struct _DriFenceMgr * -driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); - -void -driFenceMgrUnReference(struct _DriFenceMgr **pMgr); - -extern struct _DriFenceMgr * -driFenceMgrTTMInit(int fd); - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c deleted file mode 100644 index bf97d7e440..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c +++ /dev/null @@ -1,162 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - */ - -#include -#include -#include -#include "imports.h" -#include "glthread.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" -#include "intel_screen.h" - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, uint64_t flags, unsigned hint, - unsigned alignment) -{ - unsigned long *private = malloc(size + 2*sizeof(unsigned long)); - if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) - abort(); - - *private = size; - return (void *)private; -} - - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - free(private); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex, int lazy) -{ - return 0; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - *virtual = (void *)((unsigned long *)private + 2); - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - /* - * BUG - */ - abort(); - return 0UL; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - /* - * BUG - */ - abort(); -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - return *(unsigned long *) private; -} - - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - abort(); - return 0UL; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - abort(); - return NULL; -} - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - - -struct _DriBufferPool * -driMallocPoolInit(void) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - if (!pool) - return NULL; - - pool->data = NULL; - pool->fd = -1; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->poolOffset = &pool_poolOffset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - return pool; -} diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c deleted file mode 100644 index e69519a01f..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c +++ /dev/null @@ -1,970 +0,0 @@ -/************************************************************************** - * - * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#include -#include -#include -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" -#include "ws_dri_bufmgr.h" -#include "glthread.h" - -#define DRI_SLABPOOL_ALLOC_RETRIES 100 - -struct _DriSlab; - -struct _DriSlabBuffer { - int isSlabBuffer; - drmBO *bo; - struct _DriFenceObject *fence; - struct _DriSlab *parent; - drmMMListHead head; - uint32_t mapCount; - uint32_t start; - uint32_t fenceType; - int unFenced; - _glthread_Cond event; -}; - -struct _DriKernelBO { - int fd; - drmBO bo; - drmMMListHead timeoutHead; - drmMMListHead head; - struct timeval timeFreed; - uint32_t pageAlignment; - void *virtual; -}; - -struct _DriSlab{ - drmMMListHead head; - drmMMListHead freeBuffers; - uint32_t numBuffers; - uint32_t numFree; - struct _DriSlabBuffer *buffers; - struct _DriSlabSizeHeader *header; - struct _DriKernelBO *kbo; -}; - - -struct _DriSlabSizeHeader { - drmMMListHead slabs; - drmMMListHead freeSlabs; - drmMMListHead delayedBuffers; - uint32_t numDelayed; - struct _DriSlabPool *slabPool; - uint32_t bufSize; - _glthread_Mutex mutex; -}; - -struct _DriFreeSlabManager { - struct timeval slabTimeout; - struct timeval checkInterval; - struct timeval nextCheck; - drmMMListHead timeoutList; - drmMMListHead unCached; - drmMMListHead cached; - _glthread_Mutex mutex; -}; - - -struct _DriSlabPool { - - /* - * The data of this structure remains constant after - * initialization and thus needs no mutex protection. - */ - - struct _DriFreeSlabManager *fMan; - uint64_t proposedFlags; - uint64_t validMask; - uint32_t *bucketSizes; - uint32_t numBuckets; - uint32_t pageSize; - int fd; - int pageAlignment; - int maxSlabSize; - int desiredNumBuffers; - struct _DriSlabSizeHeader *headers; -}; - -/* - * FIXME: Perhaps arrange timeout slabs in size buckets for fast - * retreival?? - */ - - -static inline int -driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) -{ - return ((arg1->tv_sec > arg2->tv_sec) || - ((arg1->tv_sec == arg2->tv_sec) && - (arg1->tv_usec > arg2->tv_usec))); -} - -static inline void -driTimeAdd(struct timeval *arg, struct timeval *add) -{ - unsigned int sec; - - arg->tv_sec += add->tv_sec; - arg->tv_usec += add->tv_usec; - sec = arg->tv_usec / 1000000; - arg->tv_sec += sec; - arg->tv_usec -= sec*1000000; -} - -static void -driFreeKernelBO(struct _DriKernelBO *kbo) -{ - if (!kbo) - return; - - (void) drmBOUnreference(kbo->fd, &kbo->bo); - free(kbo); -} - - -static void -driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, - struct timeval *time) -{ - drmMMListHead *list, *next; - struct _DriKernelBO *kbo; - - if (!driTimeAfterEq(time, &fMan->nextCheck)) - return; - - for (list = fMan->timeoutList.next, next = list->next; - list != &fMan->timeoutList; - list = next, next = list->next) { - - kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); - - if (!driTimeAfterEq(time, &kbo->timeFreed)) - break; - - DRMLISTDELINIT(&kbo->timeoutHead); - DRMLISTDELINIT(&kbo->head); - driFreeKernelBO(kbo); - } - - fMan->nextCheck = *time; - driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); -} - - -/* - * Add a _DriKernelBO to the free slab manager. - * This means that it is available for reuse, but if it's not - * reused in a while, it will be freed. - */ - -static void -driSetKernelBOFree(struct _DriFreeSlabManager *fMan, - struct _DriKernelBO *kbo) -{ - struct timeval time; - - _glthread_LOCK_MUTEX(fMan->mutex); - gettimeofday(&time, NULL); - driTimeAdd(&time, &fMan->slabTimeout); - - kbo->timeFreed = time; - - if (kbo->bo.flags & DRM_BO_FLAG_CACHED) - DRMLISTADD(&kbo->head, &fMan->cached); - else - DRMLISTADD(&kbo->head, &fMan->unCached); - - DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); - driFreeTimeoutKBOsLocked(fMan, &time); - - _glthread_UNLOCK_MUTEX(fMan->mutex); -} - -/* - * Get a _DriKernelBO for us to use as storage for a slab. - * - */ - -static struct _DriKernelBO * -driAllocKernelBO(struct _DriSlabSizeHeader *header) - -{ - struct _DriSlabPool *slabPool = header->slabPool; - struct _DriFreeSlabManager *fMan = slabPool->fMan; - drmMMListHead *list, *next, *head; - uint32_t size = header->bufSize * slabPool->desiredNumBuffers; - struct _DriKernelBO *kbo; - struct _DriKernelBO *kboTmp; - int ret; - - /* - * FIXME: We should perhaps allow some variation in slabsize in order - * to efficiently reuse slabs. - */ - - size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; - size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); - _glthread_LOCK_MUTEX(fMan->mutex); - - kbo = NULL; - - retry: - head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? - &fMan->cached : &fMan->unCached; - - for (list = head->next, next = list->next; - list != head; - list = next, next = list->next) { - - kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); - - if ((kboTmp->bo.size == size) && - (slabPool->pageAlignment == 0 || - (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { - - if (!kbo) - kbo = kboTmp; - - if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) - break; - - } - } - - if (kbo) { - DRMLISTDELINIT(&kbo->head); - DRMLISTDELINIT(&kbo->timeoutHead); - } - - _glthread_UNLOCK_MUTEX(fMan->mutex); - - if (kbo) { - uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; - - ret = 0; - if (new_mask) { - ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, - new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); - } - if (ret == 0) - return kbo; - - driFreeKernelBO(kbo); - kbo = NULL; - goto retry; - } - - kbo = calloc(1, sizeof(struct _DriKernelBO)); - if (!kbo) - return NULL; - - kbo->fd = slabPool->fd; - DRMINITLISTHEAD(&kbo->head); - DRMINITLISTHEAD(&kbo->timeoutHead); - ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, - slabPool->proposedFlags, - DRM_BO_HINT_DONT_FENCE, &kbo->bo); - if (ret) - goto out_err0; - - ret = drmBOMap(kbo->fd, &kbo->bo, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0, &kbo->virtual); - - if (ret) - goto out_err1; - - ret = drmBOUnmap(kbo->fd, &kbo->bo); - if (ret) - goto out_err1; - - return kbo; - - out_err1: - drmBOUnreference(kbo->fd, &kbo->bo); - out_err0: - free(kbo); - return NULL; -} - - -static int -driAllocSlab(struct _DriSlabSizeHeader *header) -{ - struct _DriSlab *slab; - struct _DriSlabBuffer *buf; - uint32_t numBuffers; - int ret; - int i; - - slab = calloc(1, sizeof(*slab)); - if (!slab) - return -ENOMEM; - - slab->kbo = driAllocKernelBO(header); - if (!slab->kbo) { - ret = -ENOMEM; - goto out_err0; - } - - numBuffers = slab->kbo->bo.size / header->bufSize; - - slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); - if (!slab->buffers) { - ret = -ENOMEM; - goto out_err1; - } - - DRMINITLISTHEAD(&slab->head); - DRMINITLISTHEAD(&slab->freeBuffers); - slab->numBuffers = numBuffers; - slab->numFree = 0; - slab->header = header; - - buf = slab->buffers; - for (i=0; i < numBuffers; ++i) { - buf->parent = slab; - buf->start = i* header->bufSize; - buf->mapCount = 0; - buf->isSlabBuffer = 1; - _glthread_INIT_COND(buf->event); - DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); - slab->numFree++; - buf++; - } - - DRMLISTADDTAIL(&slab->head, &header->slabs); - - return 0; - - out_err1: - driSetKernelBOFree(header->slabPool->fMan, slab->kbo); - free(slab->buffers); - out_err0: - free(slab); - return ret; -} - -/* - * Delete a buffer from the slab header delayed list and put - * it on the slab free list. - */ - -static void -driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) -{ - struct _DriSlab *slab = buf->parent; - struct _DriSlabSizeHeader *header = slab->header; - drmMMListHead *list = &buf->head; - - DRMLISTDEL(list); - DRMLISTADDTAIL(list, &slab->freeBuffers); - slab->numFree++; - - if (slab->head.next == &slab->head) - DRMLISTADDTAIL(&slab->head, &header->slabs); - - if (slab->numFree == slab->numBuffers) { - list = &slab->head; - DRMLISTDEL(list); - DRMLISTADDTAIL(list, &header->freeSlabs); - } - - if (header->slabs.next == &header->slabs || - slab->numFree != slab->numBuffers) { - - drmMMListHead *next; - struct _DriFreeSlabManager *fMan = header->slabPool->fMan; - - for (list = header->freeSlabs.next, next = list->next; - list != &header->freeSlabs; - list = next, next = list->next) { - - slab = DRMLISTENTRY(struct _DriSlab, list, head); - - DRMLISTDELINIT(list); - driSetKernelBOFree(fMan, slab->kbo); - free(slab->buffers); - free(slab); - } - } -} - -static void -driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) -{ - drmMMListHead *list, *prev, *first; - struct _DriSlabBuffer *buf; - struct _DriSlab *slab; - int firstWasSignaled = 1; - int signaled; - int i; - int ret; - - /* - * Rerun the freeing test if the youngest tested buffer - * was signaled, since there might be more idle buffers - * in the delay list. - */ - - while (firstWasSignaled) { - firstWasSignaled = 0; - signaled = 0; - first = header->delayedBuffers.next; - - /* Only examine the oldest 1/3 of delayed buffers: - */ - if (header->numDelayed > 3) { - for (i = 0; i < header->numDelayed; i += 3) { - first = first->next; - } - } - - for (list = first, prev = list->prev; - list != &header->delayedBuffers; - list = prev, prev = list->prev) { - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - slab = buf->parent; - - if (!signaled) { - if (wait) { - ret = driFenceFinish(buf->fence, buf->fenceType, 0); - if (ret) - break; - signaled = 1; - wait = 0; - } else { - signaled = driFenceSignaled(buf->fence, buf->fenceType); - } - if (signaled) { - if (list == first) - firstWasSignaled = 1; - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - } - } -} - - -static struct _DriSlabBuffer * -driSlabAllocBuffer(struct _DriSlabSizeHeader *header) -{ - static struct _DriSlabBuffer *buf; - struct _DriSlab *slab; - drmMMListHead *list; - int count = DRI_SLABPOOL_ALLOC_RETRIES; - - _glthread_LOCK_MUTEX(header->mutex); - while(header->slabs.next == &header->slabs && count > 0) { - driSlabCheckFreeLocked(header, 0); - if (header->slabs.next != &header->slabs) - break; - - _glthread_UNLOCK_MUTEX(header->mutex); - if (count != DRI_SLABPOOL_ALLOC_RETRIES) - usleep(1); - _glthread_LOCK_MUTEX(header->mutex); - (void) driAllocSlab(header); - count--; - } - - list = header->slabs.next; - if (list == &header->slabs) { - _glthread_UNLOCK_MUTEX(header->mutex); - return NULL; - } - slab = DRMLISTENTRY(struct _DriSlab, list, head); - if (--slab->numFree == 0) - DRMLISTDELINIT(list); - - list = slab->freeBuffers.next; - DRMLISTDELINIT(list); - - _glthread_UNLOCK_MUTEX(header->mutex); - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - return buf; -} - -static void * -pool_create(struct _DriBufferPool *driPool, unsigned long size, - uint64_t flags, unsigned hint, unsigned alignment) -{ - struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; - struct _DriSlabSizeHeader *header; - struct _DriSlabBuffer *buf; - void *dummy; - int i; - int ret; - - /* - * FIXME: Check for compatibility. - */ - header = pool->headers; - for (i=0; inumBuckets; ++i) { - if (header->bufSize >= size) - break; - header++; - } - - if (i < pool->numBuckets) - return driSlabAllocBuffer(header); - - - /* - * Fall back to allocate a buffer object directly from DRM. - * and wrap it in a driBO structure. - */ - - - buf = calloc(1, sizeof(*buf)); - - if (!buf) - return NULL; - - buf->bo = calloc(1, sizeof(*buf->bo)); - if (!buf->bo) - goto out_err0; - - if (alignment) { - if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) - goto out_err1; - if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) - goto out_err1; - } - - ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, - flags, hint, buf->bo); - if (ret) - goto out_err1; - - ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0, &dummy); - if (ret) - goto out_err2; - - ret = drmBOUnmap(pool->fd, buf->bo); - if (ret) - goto out_err2; - - return buf; - out_err2: - drmBOUnreference(pool->fd, buf->bo); - out_err1: - free(buf->bo); - out_err0: - free(buf); - return NULL; -} - -static int -pool_destroy(struct _DriBufferPool *driPool, void *private) -{ - struct _DriSlabBuffer *buf = - (struct _DriSlabBuffer *) private; - struct _DriSlab *slab; - struct _DriSlabSizeHeader *header; - - if (!buf->isSlabBuffer) { - struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; - int ret; - - ret = drmBOUnreference(pool->fd, buf->bo); - free(buf->bo); - free(buf); - return ret; - } - - slab = buf->parent; - header = slab->header; - - _glthread_LOCK_MUTEX(header->mutex); - buf->unFenced = 0; - buf->mapCount = 0; - - if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { - DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); - header->numDelayed++; - } else { - if (buf->fence) - driFenceUnReference(&buf->fence); - driSlabFreeBufferLocked(buf); - } - - _glthread_UNLOCK_MUTEX(header->mutex); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *driPool, void *private, - _glthread_Mutex *mutex, int lazy) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - while(buf->unFenced) - _glthread_COND_WAIT(buf->event, *mutex); - - if (!buf->fence) - return 0; - - driFenceFinish(buf->fence, buf->fenceType, lazy); - driFenceUnReference(&buf->fence); - - return 0; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - int busy; - - if (buf->isSlabBuffer) - busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); - else - busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); - - - if (busy) { - if (hint & DRM_BO_HINT_DONT_BLOCK) - return -EBUSY; - else { - (void) pool_waitIdle(pool, private, mutex, 0); - } - } - - ++buf->mapCount; - *virtual = (buf->isSlabBuffer) ? - (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : - (void *) buf->bo->virtual; - - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - --buf->mapCount; - if (buf->mapCount == 0 && buf->isSlabBuffer) - _glthread_COND_BROADCAST(buf->event); - - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - struct _DriSlab *slab; - struct _DriSlabSizeHeader *header; - - if (!buf->isSlabBuffer) { - assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); - return buf->bo->offset; - } - - slab = buf->parent; - header = slab->header; - - (void) header; - assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); - return slab->kbo->bo.offset + buf->start; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - return buf->start; -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf->isSlabBuffer) - return buf->bo->flags; - - return buf->parent->kbo->bo.flags; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - if (!buf->isSlabBuffer) - return buf->bo->size; - - return buf->parent->header->bufSize; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - drmBO *bo; - - if (buf->fence) - driFenceUnReference(&buf->fence); - - buf->fence = driFenceReference(fence); - bo = (buf->isSlabBuffer) ? - &buf->parent->kbo->bo: - buf->bo; - buf->fenceType = bo->fenceFlags; - - buf->unFenced = 0; - _glthread_COND_BROADCAST(buf->event); - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf) - return NULL; - - return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; -} - -static int -pool_validate(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf->isSlabBuffer) - return 0; - - while(buf->mapCount != 0) - _glthread_COND_WAIT(buf->event, *mutex); - - buf->unFenced = 1; - return 0; -} - - -struct _DriFreeSlabManager * -driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) -{ - struct _DriFreeSlabManager *tmp; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return NULL; - - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); - tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; - tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; - tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; - - tmp->checkInterval.tv_usec = checkIntervalMsec*1000; - tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; - tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; - - gettimeofday(&tmp->nextCheck, NULL); - driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); - DRMINITLISTHEAD(&tmp->timeoutList); - DRMINITLISTHEAD(&tmp->unCached); - DRMINITLISTHEAD(&tmp->cached); - _glthread_UNLOCK_MUTEX(tmp->mutex); - - return tmp; -} - -void -driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) -{ - struct timeval time; - - time = fMan->nextCheck; - driTimeAdd(&time, &fMan->checkInterval); - - _glthread_LOCK_MUTEX(fMan->mutex); - driFreeTimeoutKBOsLocked(fMan, &time); - _glthread_UNLOCK_MUTEX(fMan->mutex); - - assert(fMan->timeoutList.next == &fMan->timeoutList); - assert(fMan->unCached.next == &fMan->unCached); - assert(fMan->cached.next == &fMan->cached); - - free(fMan); -} - -static void -driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, - struct _DriSlabSizeHeader *header) -{ - _glthread_INIT_MUTEX(header->mutex); - _glthread_LOCK_MUTEX(header->mutex); - - DRMINITLISTHEAD(&header->slabs); - DRMINITLISTHEAD(&header->freeSlabs); - DRMINITLISTHEAD(&header->delayedBuffers); - - header->numDelayed = 0; - header->slabPool = pool; - header->bufSize = size; - - _glthread_UNLOCK_MUTEX(header->mutex); -} - -static void -driFinishSizeHeader(struct _DriSlabSizeHeader *header) -{ - drmMMListHead *list, *next; - struct _DriSlabBuffer *buf; - - _glthread_LOCK_MUTEX(header->mutex); - for (list = header->delayedBuffers.next, next = list->next; - list != &header->delayedBuffers; - list = next, next = list->next) { - - buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); - if (buf->fence) { - (void) driFenceFinish(buf->fence, buf->fenceType, 0); - driFenceUnReference(&buf->fence); - } - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - _glthread_UNLOCK_MUTEX(header->mutex); -} - -static void -pool_takedown(struct _DriBufferPool *driPool) -{ - struct _DriSlabPool *pool = driPool->data; - int i; - - for (i=0; inumBuckets; ++i) { - driFinishSizeHeader(&pool->headers[i]); - } - - free(pool->headers); - free(pool->bucketSizes); - free(pool); - free(driPool); -} - -struct _DriBufferPool * -driSlabPoolInit(int fd, uint64_t flags, - uint64_t validMask, - uint32_t smallestSize, - uint32_t numSizes, - uint32_t desiredNumBuffers, - uint32_t maxSlabSize, - uint32_t pageAlignment, - struct _DriFreeSlabManager *fMan) -{ - struct _DriBufferPool *driPool; - struct _DriSlabPool *pool; - uint32_t i; - - driPool = calloc(1, sizeof(*driPool)); - if (!driPool) - return NULL; - - pool = calloc(1, sizeof(*pool)); - if (!pool) - goto out_err0; - - pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); - if (!pool->bucketSizes) - goto out_err1; - - pool->headers = calloc(numSizes, sizeof(*pool->headers)); - if (!pool->headers) - goto out_err2; - - pool->fMan = fMan; - pool->proposedFlags = flags; - pool->validMask = validMask; - pool->numBuckets = numSizes; - pool->pageSize = getpagesize(); - pool->fd = fd; - pool->pageAlignment = pageAlignment; - pool->maxSlabSize = maxSlabSize; - pool->desiredNumBuffers = desiredNumBuffers; - - for (i=0; inumBuckets; ++i) { - pool->bucketSizes[i] = (smallestSize << i); - driInitSizeHeader(pool, pool->bucketSizes[i], - &pool->headers[i]); - } - - driPool->data = (void *) pool; - driPool->map = &pool_map; - driPool->unmap = &pool_unmap; - driPool->destroy = &pool_destroy; - driPool->offset = &pool_offset; - driPool->poolOffset = &pool_poolOffset; - driPool->flags = &pool_flags; - driPool->size = &pool_size; - driPool->create = &pool_create; - driPool->fence = &pool_fence; - driPool->kernel = &pool_kernel; - driPool->validate = &pool_validate; - driPool->waitIdle = &pool_waitIdle; - driPool->takeDown = &pool_takedown; - - return driPool; - - out_err2: - free(pool->bucketSizes); - out_err1: - free(pool); - out_err0: - free(driPool); - - return NULL; -} -- cgit v1.2.3 From 0a84d327de8258104b98b176c0eaf0fb6712a982 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 6 Jun 2008 10:42:13 -0600 Subject: egl: open X display if needed --- src/gallium/winsys/egl_xlib/egl_xlib.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 07b3c0eb00..7bef46d560 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -573,6 +573,10 @@ _eglMain(_EGLDisplay *dpy, const char *args) if (!xdrv) return NULL; + if (!dpy->Xdpy) { + dpy->Xdpy = XOpenDisplay(NULL); + } + _eglInitDriverFallbacks(&xdrv->Base); xdrv->Base.API.Initialize = xlib_eglInitialize; xdrv->Base.API.Terminate = xlib_eglTerminate; -- cgit v1.2.3 From f0fdf0c23a16b9e0338eb945c6f88c7a57a9fbd0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 6 Jun 2008 12:33:53 -0600 Subject: gallium: additional comment --- src/gallium/winsys/xlib/Makefile | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index c443330942..ec92c79068 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -1,5 +1,9 @@ # src/gallium/winsys/xlib/Makefile +# This makefile produces a "stand-alone" libGL.so which is based on +# Xlib (no DRI HW acceleration) + + TOP = ../../../.. include $(TOP)/configs/current -- cgit v1.2.3 From ab102d5a9f1db0f76eabbf22cd05b08ff7bb8448 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 6 Jun 2008 15:42:08 -0600 Subject: egl: clean-ups --- src/gallium/winsys/egl_xlib/Makefile | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile index fe4b931e30..46666650b0 100644 --- a/src/gallium/winsys/egl_xlib/Makefile +++ b/src/gallium/winsys/egl_xlib/Makefile @@ -7,7 +7,7 @@ TOP = ../../../.. include $(TOP)/configs/current -LIBNAME = softpipe_egl.so +DRIVER_NAME = softpipe_egl.so INCLUDE_DIRS = \ @@ -36,30 +36,28 @@ LIBS = \ LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1 -.SUFFIXES : .cpp - .c.o: $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@ -.cpp.o: - $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $(LOCAL_CFLAGS) $< -o $@ + +.PHONY: library +default: depend library Makefile -default: $(TOP)/$(LIB_DIR)/$(LIBNAME) + +library: $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) # Make the softpipe_egl.so library -$(TOP)/$(LIB_DIR)/$(LIBNAME): $(WINSYS_OBJECTS) $(LIBS) - $(TOP)/bin/mklib -o $(LIBNAME) \ +$(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(WINSYS_OBJECTS) $(LIBS) + $(TOP)/bin/mklib -o $(DRIVER_NAME) \ -linker "$(CC)" \ -noprefix \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) \ --start-group $(LIBS) --end-group -# $(GL_LIB_DEPS) - depend: $(ALL_SOURCES) @ echo "running $(MKDEP)" @@ -72,7 +70,7 @@ depend: $(ALL_SOURCES) install: default $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) @if [ -e $(TOP)/$(LIB_DIR) ]; then \ - $(INSTALL) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(INSTALL_DIR)/$(LIB_DIR); \ + $(INSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(INSTALL_DIR)/$(LIB_DIR); \ fi -- cgit v1.2.3 From edea59e8e5a3ef4c6afdcb4f1d32961466be508b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 8 Jun 2008 12:50:47 +1000 Subject: nouveau: kill off surface_alloc_storage() --- .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 23 ---------------------- 1 file changed, 23 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index 2fab1eab65..ba5dd2eea4 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -39,28 +39,6 @@ nouveau_surface_alloc(struct pipe_winsys *ws) return surf; } -static int -nouveau_surface_alloc_storage(struct pipe_winsys *ws, struct pipe_surface *surf, - unsigned width, unsigned height, - enum pipe_format format, unsigned flags, - unsigned tex_usage) -{ - unsigned pitch = ((width * pf_get_size(format)) + 63) & ~63; - - surf->format = format; - surf->width = width; - surf->height = height; - surf->cpp = pf_get_size(format); - surf->pitch = pitch / surf->cpp; - - surf->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, - pitch * height); - if (!surf->buffer) - return 1; - - return 0; -} - static void nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s) { @@ -226,7 +204,6 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv) pws->flush_frontbuffer = nouveau_flush_frontbuffer; pws->surface_alloc = nouveau_surface_alloc; - pws->surface_alloc_storage = nouveau_surface_alloc_storage; pws->surface_release = nouveau_surface_release; pws->buffer_create = nouveau_pipe_bo_create; -- cgit v1.2.3 From c11a7ec821d41b91a3825c5abfb4687c98b5bf98 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 8 Jun 2008 03:04:14 -0400 Subject: Initial commit for g3dvl. Initial commit for g3dvl, contains support for basic XvMC features. - Context, surface, block, macroblock creation and deletion - Surface rendering - Frame pictures - Frame based motion compensation - Intra-coded macroblocks - Predicted macroblocks - Bi-directionally predicted macroblocks - Surface display - Color conversion - Scaling --- src/gallium/winsys/g3dvl/xsp_winsys.c | 256 ++++++++++++++++++++++++++++++++++ src/gallium/winsys/g3dvl/xsp_winsys.h | 11 ++ 2 files changed, 267 insertions(+) create mode 100644 src/gallium/winsys/g3dvl/xsp_winsys.c create mode 100644 src/gallium/winsys/g3dvl/xsp_winsys.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c new file mode 100644 index 0000000000..eb4c9085d6 --- /dev/null +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -0,0 +1,256 @@ +#include "xsp_winsys.h" +#include +#include +#include +#include +#include +#include + +/* pipe_winsys implementation */ + +struct xsp_pipe_winsys +{ + struct pipe_winsys base; + Display *display; + XImage fbimage; +}; + +struct xsp_buffer +{ + struct pipe_buffer base; + boolean is_user_buffer; + void *data; + void *mapped_data; +}; + +static struct pipe_buffer* xsp_buffer_create(struct pipe_winsys *pws, unsigned alignment, unsigned usage, unsigned size) +{ + struct xsp_buffer *buffer; + + assert(pws); + + buffer = calloc(1, sizeof(struct xsp_buffer)); + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + buffer->data = align_malloc(size, alignment); + + return (struct pipe_buffer*)buffer; +} + +static struct pipe_buffer* xsp_user_buffer_create(struct pipe_winsys *pws, void *data, unsigned size) +{ + struct xsp_buffer *buffer; + + assert(pws); + + buffer = calloc(1, sizeof(struct xsp_buffer)); + buffer->base.refcount = 1; + buffer->base.size = size; + buffer->is_user_buffer = TRUE; + buffer->data = data; + + return (struct pipe_buffer*)buffer; +} + +static void* xsp_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buffer, unsigned flags) +{ + struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; + + assert(pws); + assert(buffer); + + xsp_buf->mapped_data = xsp_buf->data; + return xsp_buf->mapped_data; +} + +static void xsp_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buffer) +{ + struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; + + assert(pws); + assert(buffer); + + xsp_buf->mapped_data = NULL; +} + +static void xsp_buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buffer) +{ + struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; + + assert(pws); + assert(buffer); + + if (!xsp_buf->is_user_buffer) + align_free(xsp_buf->data); + + free(xsp_buf); +} + +static struct pipe_surface* xsp_surface_alloc(struct pipe_winsys *pws) +{ + struct pipe_surface *surface; + + assert(pws); + + surface = calloc(1, sizeof(struct pipe_surface)); + surface->refcount = 1; + surface->winsys = pws; + + return surface; +} + +static int xsp_surface_alloc_storage +( + struct pipe_winsys *pws, + struct pipe_surface *surface, + unsigned width, + unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage +) +{ + const unsigned int ALIGNMENT = 1; + + assert(pws); + assert(surface); + + surface->width = width; + surface->height = height; + surface->format = format; + surface->cpp = pf_get_size(format); + surface->pitch = width; + surface->usage = flags; + surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->pitch * surface->cpp * height); + + return 0; +} + +static void xsp_surface_release(struct pipe_winsys *pws, struct pipe_surface **surface) +{ + struct pipe_surface *s; + + assert(pws); + assert(surface); + assert(*surface); + + s = *surface; + + s->refcount--; + + if (s->refcount == 0) + { + pipe_buffer_reference(pws, &s->buffer, NULL); + free(s); + } + + *surface = NULL; +} + +static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private) +{ + struct xsp_pipe_winsys *xsp_winsys; + + assert(pws); + assert(surface); + assert(context_private); + + xsp_winsys = (struct xsp_pipe_winsys*)pws; + + xsp_winsys->fbimage.width = surface->width; + xsp_winsys->fbimage.height = surface->height; + xsp_winsys->fbimage.bytes_per_line = surface->width * (xsp_winsys->fbimage.bits_per_pixel >> 3); + xsp_winsys->fbimage.data = pipe_surface_map(surface, 0); + + XPutImage + ( + xsp_winsys->display, + *(Drawable*)context_private, + XDefaultGC(xsp_winsys->display, XDefaultScreen(xsp_winsys->display)), + &xsp_winsys->fbimage, + 0, + 0, + 0, + 0, + surface->width, + surface->height + ); + XFlush(xsp_winsys->display); + pipe_surface_unmap(surface); +} + +static const char* xsp_get_name(struct pipe_winsys *pws) +{ + assert(pws); + return "X11 SoftPipe"; +} + +/* softpipe_winsys implementation */ + +static boolean xsp_is_format_supported(struct softpipe_winsys *spws, enum pipe_format format) +{ + assert(spws); + + /* TODO: Test that 'format' is equal to our output window's format */ + return TRUE; +} + +/* Show starts here */ + +struct pipe_context* create_pipe_context(Display *display) +{ + struct xsp_pipe_winsys *xsp_winsys; + struct softpipe_winsys *sp_winsys; + struct pipe_screen *p_screen; + struct pipe_context *p_context; + + assert(display); + + xsp_winsys = calloc(1, sizeof(struct xsp_pipe_winsys)); + xsp_winsys->base.buffer_create = xsp_buffer_create; + xsp_winsys->base.user_buffer_create = xsp_user_buffer_create; + xsp_winsys->base.buffer_map = xsp_buffer_map; + xsp_winsys->base.buffer_unmap = xsp_buffer_unmap; + xsp_winsys->base.buffer_destroy = xsp_buffer_destroy; + xsp_winsys->base.surface_alloc = xsp_surface_alloc; + xsp_winsys->base.surface_alloc_storage = xsp_surface_alloc_storage; + xsp_winsys->base.surface_release = xsp_surface_release; + xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer; + xsp_winsys->base.get_name = xsp_get_name; + xsp_winsys->display = display; + + { + /* XXX: Can't use the returned XImage* directly, + since we don't have control over winsys destruction + and we wouldn't be able to free it */ + XImage *template = XCreateImage + ( + display, + XDefaultVisual(display, XDefaultScreen(display)), + XDefaultDepth(display, XDefaultScreen(display)), + ZPixmap, + 0, + NULL, + 0, /* Don't know the width and height until flush_frontbuffer */ + 0, + 32, + 0 + ); + + memcpy(&xsp_winsys->fbimage, template, sizeof(XImage)); + XInitImage(&xsp_winsys->fbimage); + + XDestroyImage(template); + } + + sp_winsys = calloc(1, sizeof(struct softpipe_winsys)); + sp_winsys->is_format_supported = xsp_is_format_supported; + + p_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); + p_context = softpipe_create(p_screen, (struct pipe_winsys*)xsp_winsys, sp_winsys); + + return p_context; +} + diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.h b/src/gallium/winsys/g3dvl/xsp_winsys.h new file mode 100644 index 0000000000..47a6ac6e25 --- /dev/null +++ b/src/gallium/winsys/g3dvl/xsp_winsys.h @@ -0,0 +1,11 @@ +#ifndef xsp_winsys_h +#define xsp_winsys_h + +#include + +struct pipe_context; + +struct pipe_context* create_pipe_context(Display *display); + +#endif + -- cgit v1.2.3 From 6420a62cf0f5812708a4c649691ba62c573eaced Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 9 Jun 2008 12:26:20 -0600 Subject: egl: s/softpipe_egl.so/egl_softpipe.so/ --- src/gallium/winsys/egl_xlib/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile index 46666650b0..d5595b819a 100644 --- a/src/gallium/winsys/egl_xlib/Makefile +++ b/src/gallium/winsys/egl_xlib/Makefile @@ -1,13 +1,13 @@ # src/gallium/winsys/egl_xlib/Makefile -# Build softpipe/xlib/EGL driver library/object: "softpipe_egl.so" +# Build softpipe/xlib/EGL driver library/object: "egl_softpipe.so" TOP = ../../../.. include $(TOP)/configs/current -DRIVER_NAME = softpipe_egl.so +DRIVER_NAME = egl_softpipe.so INCLUDE_DIRS = \ @@ -49,7 +49,7 @@ default: depend library Makefile library: $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) -# Make the softpipe_egl.so library +# Make the egl_softpipe.so library $(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(WINSYS_OBJECTS) $(LIBS) $(TOP)/bin/mklib -o $(DRIVER_NAME) \ -linker "$(CC)" \ -- cgit v1.2.3 From 4566b006f1a6bbdb96871e511e10e16f18bad23e Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 10 Jun 2008 20:17:16 +0100 Subject: Bring in DRI2 changes --- src/gallium/winsys/dri/intel/intel_context.c | 83 ++++- src/gallium/winsys/dri/intel/intel_screen.c | 449 ++++++++++++++++++--------- 2 files changed, 379 insertions(+), 153 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 8284e0edbb..ecc4b0aa53 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -67,7 +67,6 @@ int __intel_debug = 0; #define need_GL_NV_vertex_program #include "extension_helper.h" - /** * Extension strings exported by the intel driver. * @@ -75,7 +74,7 @@ int __intel_debug = 0; * It appears that ARB_texture_env_crossbar has "disappeared" compared to the * old i830-specific driver. */ -const struct dri_extension card_extensions[] = { +static const struct dri_extension card_extensions[] = { {"GL_ARB_multisample", GL_ARB_multisample_functions}, {"GL_ARB_multitexture", NULL}, {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, @@ -86,22 +85,27 @@ const struct dri_extension card_extensions[] = { {"GL_ARB_texture_env_combine", NULL}, {"GL_ARB_texture_env_dot3", NULL}, {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_non_power_of_two", NULL }, {"GL_ARB_texture_rectangle", NULL}, + {"GL_NV_texture_rectangle", NULL}, + {"GL_EXT_texture_rectangle", NULL}, + {"GL_ARB_point_parameters", NULL}, {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_equation_separate", + GL_EXT_blend_equation_separate_functions}, {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_logic_op", NULL}, {"GL_EXT_blend_subtract", NULL}, {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, +#if 1 /* XXX FBO temporary? */ {"GL_EXT_packed_depth_stencil", NULL}, - {"GL_EXT_pixel_buffer_object", NULL}, +#endif {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, {"GL_EXT_stencil_wrap", NULL}, {"GL_EXT_texture_edge_clamp", NULL}, @@ -116,10 +120,67 @@ const struct dri_extension card_extensions[] = { {"GL_NV_blend_square", NULL}, {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, {"GL_NV_vertex_program1_1", NULL}, - {"GL_SGIS_generate_mipmap", NULL }, + { "GL_SGIS_generate_mipmap", NULL }, {NULL, NULL} }; +#if 0 +static const struct dri_extension brw_extensions[] = { + { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions}, + { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions}, + { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions}, + { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions}, + { "GL_ARB_point_sprite", NULL}, + { "GL_ARB_fragment_shader", NULL }, + { "GL_ARB_draw_buffers", NULL }, + { "GL_ARB_depth_texture", NULL }, + { "GL_ARB_fragment_program", NULL }, + { "GL_ARB_shadow", NULL }, + { "GL_EXT_shadow_funcs", NULL }, + /* ARB extn won't work if not enabled */ + { "GL_SGIX_depth_texture", NULL }, + { "GL_ARB_texture_env_crossbar", NULL }, + { "GL_EXT_texture_sRGB", NULL}, + { NULL, NULL } +}; + +static const struct dri_extension arb_oc_extensions[] = { + {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, + {NULL, NULL} +}; + +static const struct dri_extension ttm_extensions[] = { + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {NULL, NULL} +}; +#endif + +/** + * Initializes potential list of extensions if ctx == NULL, or actually enables + * extensions for a context. + */ +void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging) +{ + /* Disable imaging extension until convolution is working in teximage paths. + */ + enable_imaging = GL_FALSE; + + driInitExtensions(ctx, card_extensions, enable_imaging); + +#if 0 + if (intel == NULL || intel->ttm) + driInitExtensions(ctx, ttm_extensions, GL_FALSE); + + if (intel == NULL || + (IS_965(intel->intelScreen->deviceID) && + intel->intelScreen->drmMinor >= 8)) + driInitExtensions(ctx, arb_oc_extensions, GL_FALSE); + + if (intel == NULL || IS_965(intel->intelScreen->deviceID)) + driInitExtensions(ctx, brw_extensions, GL_FALSE); +#endif +} #ifdef DEBUG @@ -204,10 +265,10 @@ intelCreateContext(const __GLcontextModes * visual, /* * memory pools */ - DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + DRM_LIGHT_LOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext); // ZZZ JB should be per screen and not be done per context havePools = intelCreatePools(sPriv); - DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + DRM_UNLOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext); if (!havePools) return GL_FALSE; @@ -215,7 +276,7 @@ intelCreateContext(const __GLcontextModes * visual, /* Dri stuff */ intel->hHWContext = driContextPriv->hHWContext; intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + intel->driHwLock = (drmLock *) & sPriv->lock; fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); intel->iw.irq_seq = -1; @@ -265,7 +326,7 @@ intelCreateContext(const __GLcontextModes * visual, intel->st = st_create_context(pipe, visual, st_share); - driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE ); + intelInitExtensions( intel->st->ctx, GL_TRUE ); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 8817a80a5a..23889c80b8 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -60,7 +60,190 @@ static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; extern const struct dri_extension card_extensions[]; +static GLboolean +intel_get_param(__DRIscreenPrivate *psp, int param, int *value) +{ + int ret; + struct drm_i915_getparam gp; + + gp.param = param; + gp.value = value; + + ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drm_i915_getparam: %d\n", ret); + return GL_FALSE; + } + + return GL_TRUE; +} + +static void +intelSetTexOffset(__DRIcontext *pDRICtx, int texname, + unsigned long long offset, int depth, uint pitch) +{ + abort(); +#if 0 + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct st_texture_object *stObj = st_texture_object(tObj); + + if (!stObj) + return; + + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); + + stObj->imageOverride = GL_TRUE; + stObj->depthOverride = depth; + stObj->pitchOverride = pitch; + + if (offset) + stObj->textureOffset = offset; +#endif +} + + +static void +intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv, + __DRIcontextPrivate *pcp, + __DRIDrawableConfigEvent *event) +{ + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + struct intel_region *region = NULL; + struct intel_renderbuffer *rb, *depth_rb, *stencil_rb; + struct intel_context *intel = pcp->driverPrivate; + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + int cpp, pitch; + +#if 0 + cpp = intelScreen->front.cpp; + pitch = ((cpp * dPriv->w + 63) & ~63) / cpp; + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + rb = intel_fb->color_rb[1]; + if (rb) { + region = intel_region_alloc(intel, cpp, pitch, dPriv->h); + intel_renderbuffer_set_region(rb, region); + } + + rb = intel_fb->color_rb[2]; + if (rb) { + region = intel_region_alloc(intel, cpp, pitch, dPriv->h); + intel_renderbuffer_set_region(rb, region); + } + + depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + if (depth_rb || stencil_rb) + region = intel_region_alloc(intel, cpp, pitch, dPriv->h); + if (depth_rb) + intel_renderbuffer_set_region(depth_rb, region); + if (stencil_rb) + intel_renderbuffer_set_region(stencil_rb, region); + + /* FIXME: Tell the X server about the regions we just allocated and + * attached. */ +#endif + +} + +#define BUFFER_FLAG_TILED 0x0100 + +static void +intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, + __DRIcontextPrivate *pcp, + __DRIBufferAttachEvent *ba) +{ + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + struct intel_renderbuffer *rb; + struct intel_region *region; + struct intel_context *intel = pcp->driverPrivate; + struct pipe_surface *surf; + GLuint tiled; + + switch (ba->buffer.attachment) { + case DRI_DRAWABLE_BUFFER_FRONT_LEFT: + #if 0 + intelScreen->front.width = ba->width; + intelScreen->front.height = ba->height; + intelScreen->front.offset = sarea->front_offset; + #endif + intelScreen->front.pitch = ba->buffer.pitch * ba->buffer.cpp; + #if 0 + intelScreen->front.size = sarea->front_size; + #endif + driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); + driBOSetReferenced(intelScreen->front.buffer, ba->buffer.handle); + + break; + +#if 0 + case DRI_DRAWABLE_BUFFER_BACK_LEFT: + rb = intel_fb->color_rb[0]; + break; + + case DRI_DRAWABLE_BUFFER_DEPTH: + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + break; + + case DRI_DRAWABLE_BUFFER_STENCIL: + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + break; +#endif + + case DRI_DRAWABLE_BUFFER_ACCUM: + default: + fprintf(stderr, "unhandled buffer attach event, attacment type %d\n", + ba->buffer.attachment); + return; + } + +#if 0 + /* FIXME: Add this so we can filter out when the X server sends us + * attachment events for the buffers we just allocated. Need to + * get the BO handle for a render buffer. */ + if (intel_renderbuffer_get_region_handle(rb) == ba->buffer.handle) + return; +#endif + +#if 0 + tiled = (ba->buffer.flags & BUFFER_FLAG_TILED) > 0; + + region = intel_region_alloc_for_handle(intel, ba->buffer.cpp, + ba->buffer.pitch / ba->buffer.cpp, + dPriv->h, tiled, + ba->buffer.handle); + + intel_renderbuffer_set_region(rb, region); +#endif +} + +static const __DRItexOffsetExtension intelTexOffsetExtension = { + { __DRI_TEX_OFFSET }, + intelSetTexOffset, +}; + +#if 0 +static const __DRItexBufferExtension intelTexBufferExtension = { + { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, + intelSetTexBuffer, +}; +#endif +static const __DRIextension *intelScreenExtensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + &intelTexOffsetExtension.base, +// &intelTexBufferExtension.base, + NULL +}; static void @@ -177,7 +360,8 @@ intelCreatePools(__DRIscreenPrivate * sPriv) intelScreen->havePools = GL_TRUE; - intelUpdateScreenRotation(sPriv, intelScreen->sarea); + if (intelScreen->sarea) + intelUpdateScreenRotation(sPriv, intelScreen->sarea); return GL_TRUE; } @@ -210,11 +394,6 @@ intelInitDriver(__DRIscreenPrivate * sPriv) struct intel_screen *intelScreen; I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> - getProcAddress("glxEnableExtension")); - void *const psc = sPriv->psc->screenConfigs; - if (sPriv->devPrivSize != sizeof(I830DRIRec)) { fprintf(stderr, "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); @@ -231,28 +410,17 @@ intelInitDriver(__DRIscreenPrivate * sPriv) __driConfigOptions, __driNConfigOptions); sPriv->private = (void *) intelScreen; - intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + - gDRIPriv->sarea_priv_offset); - intelScreen->deviceID = gDRIPriv->deviceID; - intelScreen->front.cpp = gDRIPriv->cpp; - intelScreen->drmMinor = sPriv->drmMinor; + gDRIPriv->sarea_priv_offset); - assert(gDRIPriv->bitsPerPixel == 16 || - gDRIPriv->bitsPerPixel == 32); + intelScreen->deviceID = gDRIPriv->deviceID; intelUpdateScreenRotation(sPriv, intelScreen->sarea); if (0) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - if (glx_enable_extension != NULL) { - (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); - (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); - (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); - } + sPriv->extensions = intelScreenExtensions; intel_be_init_device(&intelScreen->base, sPriv->fd); intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; @@ -351,65 +519,19 @@ intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) return 0; } - -static void -intelSetTexOffset(__DRIcontext *pDRICtx, int texname, - unsigned long long offset, int depth, uint pitch) +static __DRIconfig ** +intelFillInModes(__DRIscreenPrivate *psp, + unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) { - abort(); -#if 0 - struct intel_context *intel = (struct intel_context*) - ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; - struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); - struct st_texture_object *stObj = st_texture_object(tObj); - - if (!stObj) - return; - - if (stObj->pt) - st->pipe->texture_release(intel->st->pipe, &stObj->pt); - - stObj->imageOverride = GL_TRUE; - stObj->depthOverride = depth; - stObj->pitchOverride = pitch; - - if (offset) - stObj->textureOffset = offset; -#endif -} - - -static const struct __DriverAPIRec intelAPI = { - .InitDriver = intelInitDriver, - .DestroyScreen = intelDestroyScreen, - .CreateContext = intelCreateContext, - .DestroyContext = intelDestroyContext, - .CreateBuffer = intelCreateBuffer, - .DestroyBuffer = intelDestroyBuffer, - .SwapBuffers = intelSwapBuffers, - .MakeCurrent = intelMakeCurrent, - .UnbindContext = intelUnbindContext, - .GetSwapInfo = intelGetSwapInfo, - .GetMSC = driGetMSC32, - .WaitForMSC = driWaitForMSC32, - .WaitForSBC = NULL, - .SwapBuffersMSC = NULL, - .CopySubBuffer = intelCopySubBuffer, - .setTexOffset = intelSetTexOffset, -}; - - -static __GLcontextModes * -intelFillInModes(unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, boolean have_back_buffer) -{ - __GLcontextModes *modes; + __DRIconfig **configs; __GLcontextModes *m; unsigned num_modes; unsigned depth_buffer_factor; unsigned back_buffer_factor; GLenum fb_format; GLenum fb_type; + int i; /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't * support pageflipping at all. @@ -451,100 +573,143 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; } - modes = - (*dri_interface->createContextModes) (num_modes, - sizeof(__GLcontextModes)); - m = modes; - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_DIRECT_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + configs = driCreateConfigs(fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor); + if (configs == NULL) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; } /* Mark the visual as slow if there are "fake" stencil bits. */ - for (m = modes; m != NULL; m = m->next) { + for (i = 0; configs[i]; i++) { + m = &configs[i]->modes; if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { m->visualRating = GLX_SLOW_CONFIG; } } - return modes; + return configs; } - /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. + * + * \todo maybe fold this into intelInitDriver * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \return the __GLcontextModes supported by this driver */ -PUBLIC void * -__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, - __DRIscreen * psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) +static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; - static const __DRIversion ddx_expected = { 1, 7, 0 }; +#ifdef I915 + static const __DRIversion ddx_expected = { 1, 5, 0 }; +#else + static const __DRIversion ddx_expected = { 1, 6, 0 }; +#endif static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 7, 0 }; - - dri_interface = interface; + static const __DRIversion drm_expected = { 1, 5, 0 }; + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; if (!driCheckDriDdxDrmVersions2("i915", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { + &psp->dri_version, &dri_expected, + &psp->ddx_version, &ddx_expected, + &psp->drm_version, &drm_expected)) { return NULL; } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &intelAPI); - - if (psp != NULL) { - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - *driver_modes = intelFillInModes(dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, 1); - - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create - * is called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions(NULL, card_extensions, GL_FALSE); + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + intelInitExtensions(NULL, GL_TRUE); + + if (!intelInitDriver(psp)) + return NULL; + + psp->extensions = intelScreenExtensions; + + return (const __DRIconfig **) + intelFillInModes(psp, dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); +} + +/** + * This is the driver specific part of the createNewScreen entry point. + * + * \return the __GLcontextModes supported by this driver + */ +static const +__DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp) +{ + struct intel_screen *intelScreen; + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + intelInitExtensions(NULL, GL_TRUE); + + /* Allocate the private area */ + intelScreen = CALLOC_STRUCT(intel_screen); + if (!intelScreen) { + fprintf(stderr, "\nERROR! Allocating private area failed\n"); + return GL_FALSE; } + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); - return (void *) psp; + psp->private = (void *) intelScreen; + + intelScreen->drmMinor = psp->drm_version.minor; + + /* Determine chipset ID? */ + if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID, + &intelScreen->deviceID)) + return GL_FALSE; + + psp->extensions = intelScreenExtensions; + + intel_be_init_device(&intelScreen->base, psp->fd); + intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; + intelScreen->base.base.get_name = intel_get_name; + + return driConcatConfigs(intelFillInModes(psp, 16, 16, 0, 1), + intelFillInModes(psp, 32, 24, 8, 1)); } +const struct __DriverAPIRec driDriverAPI = { + .InitScreen = intelInitScreen, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetDrawableMSC = driDrawableGetMSC32, + .WaitForMSC = driWaitForMSC32, + .CopySubBuffer = intelCopySubBuffer, + + .InitScreen2 = intelInitScreen2, + .HandleDrawableConfig = intelHandleDrawableConfig, + .HandleBufferAttach = intelHandleBufferAttach, +}; -- cgit v1.2.3 From 1bcb817167773d6a148dd4b2cd63777d0f072c08 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 11 Jun 2008 14:52:55 +0100 Subject: Hook gallium i915 up to DRI2 --- src/gallium/winsys/dri/intel/intel_context.c | 9 ++- src/gallium/winsys/dri/intel/intel_lock.c | 7 +- src/gallium/winsys/dri/intel/intel_screen.c | 98 +++--------------------- src/gallium/winsys/dri/intel/intel_screen.h | 4 +- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 3 +- 5 files changed, 26 insertions(+), 95 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index ecc4b0aa53..af44018053 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -28,6 +28,8 @@ #include "i830_dri.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" #include "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" @@ -36,8 +38,6 @@ #include "i915simple/i915_screen.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" #include "pipe/p_defines.h" #include "pipe/p_context.h" @@ -160,8 +160,9 @@ static const struct dri_extension ttm_extensions[] = { * Initializes potential list of extensions if ctx == NULL, or actually enables * extensions for a context. */ -void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging) +void intelInitExtensions(struct st_context *st, GLboolean enable_imaging) { + GLcontext *ctx = st ? st->ctx : NULL; /* Disable imaging extension until convolution is working in teximage paths. */ enable_imaging = GL_FALSE; @@ -326,7 +327,7 @@ intelCreateContext(const __GLcontextModes * visual, intel->st = st_create_context(pipe, visual, st_share); - intelInitExtensions( intel->st->ctx, GL_TRUE ); + intelInitExtensions( intel->st, GL_TRUE ); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_lock.c b/src/gallium/winsys/dri/intel/intel_lock.c index 406284c98f..469090c0e1 100644 --- a/src/gallium/winsys/dri/intel/intel_lock.c +++ b/src/gallium/winsys/dri/intel/intel_lock.c @@ -50,6 +50,9 @@ intelContendedLock(struct intel_context *intel, uint flags) DBG(LOCK, "%s - got contended lock\n", __progname); + if (sPriv->dri2.enabled) + return; + /* If the window moved, may need to set a new cliprect now. * * NOTE: This releases and regains the hw lock, so all state @@ -58,8 +61,8 @@ intelContendedLock(struct intel_context *intel, uint flags) if (dPriv) DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); - if (sarea->width != intelScreen->front.width || - sarea->height != intelScreen->front.height) { + if (sarea && (sarea->width != intelScreen->front.width || + sarea->height != intelScreen->front.height)) { intelUpdateScreenRotation(sPriv, sarea); } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 23889c80b8..a36c9407d4 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -110,116 +110,40 @@ intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv, __DRIcontextPrivate *pcp, __DRIDrawableConfigEvent *event) { - struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - struct intel_region *region = NULL; - struct intel_renderbuffer *rb, *depth_rb, *stencil_rb; - struct intel_context *intel = pcp->driverPrivate; - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - int cpp, pitch; - -#if 0 - cpp = intelScreen->front.cpp; - pitch = ((cpp * dPriv->w + 63) & ~63) / cpp; - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - rb = intel_fb->color_rb[1]; - if (rb) { - region = intel_region_alloc(intel, cpp, pitch, dPriv->h); - intel_renderbuffer_set_region(rb, region); - } - - rb = intel_fb->color_rb[2]; - if (rb) { - region = intel_region_alloc(intel, cpp, pitch, dPriv->h); - intel_renderbuffer_set_region(rb, region); - } - - depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); - stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); - if (depth_rb || stencil_rb) - region = intel_region_alloc(intel, cpp, pitch, dPriv->h); - if (depth_rb) - intel_renderbuffer_set_region(depth_rb, region); - if (stencil_rb) - intel_renderbuffer_set_region(stencil_rb, region); - - /* FIXME: Tell the X server about the regions we just allocated and - * attached. */ -#endif - + (void) dPriv; + (void) pcp; + (void) event; } -#define BUFFER_FLAG_TILED 0x0100 - static void intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, __DRIcontextPrivate *pcp, __DRIBufferAttachEvent *ba) { struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - struct intel_renderbuffer *rb; - struct intel_region *region; - struct intel_context *intel = pcp->driverPrivate; - struct pipe_surface *surf; - GLuint tiled; switch (ba->buffer.attachment) { case DRI_DRAWABLE_BUFFER_FRONT_LEFT: - #if 0 - intelScreen->front.width = ba->width; - intelScreen->front.height = ba->height; - intelScreen->front.offset = sarea->front_offset; - #endif - intelScreen->front.pitch = ba->buffer.pitch * ba->buffer.cpp; - #if 0 - intelScreen->front.size = sarea->front_size; - #endif + intelScreen->front.width = dPriv->w; + intelScreen->front.height = dPriv->h; + intelScreen->front.cpp = ba->buffer.cpp; + intelScreen->front.pitch = ba->buffer.pitch; driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); driBOSetReferenced(intelScreen->front.buffer, ba->buffer.handle); - break; -#if 0 case DRI_DRAWABLE_BUFFER_BACK_LEFT: - rb = intel_fb->color_rb[0]; - break; - case DRI_DRAWABLE_BUFFER_DEPTH: - rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); - break; - case DRI_DRAWABLE_BUFFER_STENCIL: - rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); - break; -#endif - case DRI_DRAWABLE_BUFFER_ACCUM: + /* anything ?? */ + break; + default: - fprintf(stderr, "unhandled buffer attach event, attacment type %d\n", + fprintf(stderr, "unhandled buffer attach event, attachment type %d\n", ba->buffer.attachment); return; } - -#if 0 - /* FIXME: Add this so we can filter out when the X server sends us - * attachment events for the buffers we just allocated. Need to - * get the BO handle for a render buffer. */ - if (intel_renderbuffer_get_region_handle(rb) == ba->buffer.handle) - return; -#endif - -#if 0 - tiled = (ba->buffer.flags & BUFFER_FLAG_TILED) > 0; - - region = intel_region_alloc_for_handle(intel, ba->buffer.cpp, - ba->buffer.pitch / ba->buffer.cpp, - dPriv->h, tiled, - ba->buffer.handle); - - intel_renderbuffer_set_region(rb, region); -#endif } static const __DRItexOffsetExtension intelTexOffsetExtension = { diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index 8036917903..d1389a31fb 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -32,7 +32,7 @@ #include "i830_common.h" #include "xmlconfig.h" #include "intel_drm/ws_dri_bufpool.h" - +#include "state_tracker/st_context.h" #include "pipe/p_compiler.h" #include "intel_drm/intel_be_device.h" @@ -116,5 +116,7 @@ intelCreateContext(const __GLcontextModes * visual, __DRIcontextPrivate * driContextPriv, void *sharedContextPrivate); +extern void +intelInitExtensions(struct st_context *st, GLboolean enable_imaging); #endif diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 7f3babd98e..8b17154cf9 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -78,7 +78,8 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, * current context (which is what intelScreenContext should return) might * not get a contended lock and thus cliprects not updated (tests/manywin) */ - if (intel_context(dPriv->driContextPriv) != intel) + if (!intel->driScreen->dri2.enabled && + intel_context(dPriv->driContextPriv) != intel) DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); -- cgit v1.2.3 From f851ba705ae878f62149afa377c755286cf53c85 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 11 Jun 2008 15:35:12 +0100 Subject: fix legacy DRI --- src/gallium/winsys/dri/intel/intel_screen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index a36c9407d4..e456c28d0d 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -339,6 +339,8 @@ intelInitDriver(__DRIscreenPrivate * sPriv) intelScreen->deviceID = gDRIPriv->deviceID; + intelScreen->front.cpp = gDRIPriv->cpp; + intelScreen->drmMinor = sPriv->drm_version.minor; intelUpdateScreenRotation(sPriv, intelScreen->sarea); if (0) -- cgit v1.2.3 From d45e99060d531d3a3889bb59fb55875bde05811f Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 11 Jun 2008 15:50:07 +0100 Subject: fix card_extensions --- src/gallium/winsys/dri/intel/intel_context.c | 17 +++++------------ src/gallium/winsys/dri/intel/intel_screen.h | 2 +- 2 files changed, 6 insertions(+), 13 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index af44018053..9d78e9ebf8 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -141,6 +141,8 @@ static const struct dri_extension brw_extensions[] = { { "GL_SGIX_depth_texture", NULL }, { "GL_ARB_texture_env_crossbar", NULL }, { "GL_EXT_texture_sRGB", NULL}, + { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + { "GL_ARB_pixel_buffer_object", NULL}, { NULL, NULL } }; @@ -148,21 +150,15 @@ static const struct dri_extension arb_oc_extensions[] = { {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, {NULL, NULL} }; - -static const struct dri_extension ttm_extensions[] = { - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, - {NULL, NULL} -}; #endif /** * Initializes potential list of extensions if ctx == NULL, or actually enables * extensions for a context. */ -void intelInitExtensions(struct st_context *st, GLboolean enable_imaging) +void intelInitExtensions(struct intel_context *intel, GLboolean enable_imaging) { - GLcontext *ctx = st ? st->ctx : NULL; + GLcontext *ctx = intel ? intel->st->ctx : NULL; /* Disable imaging extension until convolution is working in teximage paths. */ enable_imaging = GL_FALSE; @@ -170,9 +166,6 @@ void intelInitExtensions(struct st_context *st, GLboolean enable_imaging) driInitExtensions(ctx, card_extensions, enable_imaging); #if 0 - if (intel == NULL || intel->ttm) - driInitExtensions(ctx, ttm_extensions, GL_FALSE); - if (intel == NULL || (IS_965(intel->intelScreen->deviceID) && intel->intelScreen->drmMinor >= 8)) @@ -327,7 +320,7 @@ intelCreateContext(const __GLcontextModes * visual, intel->st = st_create_context(pipe, visual, st_share); - intelInitExtensions( intel->st, GL_TRUE ); + intelInitExtensions( intel, GL_TRUE ); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index d1389a31fb..5a3ae1dc0f 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -117,6 +117,6 @@ intelCreateContext(const __GLcontextModes * visual, void *sharedContextPrivate); extern void -intelInitExtensions(struct st_context *st, GLboolean enable_imaging); +intelInitExtensions(struct intel_context *intel, GLboolean enable_imaging); #endif -- cgit v1.2.3 From 6f7ed99b306990f284f9d57c0b66efaa7f2277e1 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Thu, 12 Jun 2008 00:11:54 +0100 Subject: revert the DRI2 commits --- src/gallium/winsys/dri/intel/intel_context.c | 81 +---- src/gallium/winsys/dri/intel/intel_lock.c | 7 +- src/gallium/winsys/dri/intel/intel_screen.c | 375 +++++++++-------------- src/gallium/winsys/dri/intel/intel_screen.h | 4 +- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 3 +- 5 files changed, 159 insertions(+), 311 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 9d78e9ebf8..8284e0edbb 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -28,8 +28,6 @@ #include "i830_dri.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" #include "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" @@ -38,6 +36,8 @@ #include "i915simple/i915_screen.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" #include "pipe/p_defines.h" #include "pipe/p_context.h" @@ -67,6 +67,7 @@ int __intel_debug = 0; #define need_GL_NV_vertex_program #include "extension_helper.h" + /** * Extension strings exported by the intel driver. * @@ -74,7 +75,7 @@ int __intel_debug = 0; * It appears that ARB_texture_env_crossbar has "disappeared" compared to the * old i830-specific driver. */ -static const struct dri_extension card_extensions[] = { +const struct dri_extension card_extensions[] = { {"GL_ARB_multisample", GL_ARB_multisample_functions}, {"GL_ARB_multitexture", NULL}, {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, @@ -85,27 +86,22 @@ static const struct dri_extension card_extensions[] = { {"GL_ARB_texture_env_combine", NULL}, {"GL_ARB_texture_env_dot3", NULL}, {"GL_ARB_texture_mirrored_repeat", NULL}, - {"GL_ARB_texture_non_power_of_two", NULL }, {"GL_ARB_texture_rectangle", NULL}, - {"GL_NV_texture_rectangle", NULL}, - {"GL_EXT_texture_rectangle", NULL}, - {"GL_ARB_point_parameters", NULL}, {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", - GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, - {"GL_EXT_blend_logic_op", NULL}, {"GL_EXT_blend_subtract", NULL}, {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, -#if 1 /* XXX FBO temporary? */ {"GL_EXT_packed_depth_stencil", NULL}, -#endif + {"GL_EXT_pixel_buffer_object", NULL}, {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, {"GL_EXT_stencil_wrap", NULL}, {"GL_EXT_texture_edge_clamp", NULL}, @@ -120,61 +116,10 @@ static const struct dri_extension card_extensions[] = { {"GL_NV_blend_square", NULL}, {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, {"GL_NV_vertex_program1_1", NULL}, - { "GL_SGIS_generate_mipmap", NULL }, + {"GL_SGIS_generate_mipmap", NULL }, {NULL, NULL} }; -#if 0 -static const struct dri_extension brw_extensions[] = { - { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions}, - { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions}, - { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions}, - { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions}, - { "GL_ARB_point_sprite", NULL}, - { "GL_ARB_fragment_shader", NULL }, - { "GL_ARB_draw_buffers", NULL }, - { "GL_ARB_depth_texture", NULL }, - { "GL_ARB_fragment_program", NULL }, - { "GL_ARB_shadow", NULL }, - { "GL_EXT_shadow_funcs", NULL }, - /* ARB extn won't work if not enabled */ - { "GL_SGIX_depth_texture", NULL }, - { "GL_ARB_texture_env_crossbar", NULL }, - { "GL_EXT_texture_sRGB", NULL}, - { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - { "GL_ARB_pixel_buffer_object", NULL}, - { NULL, NULL } -}; - -static const struct dri_extension arb_oc_extensions[] = { - {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, - {NULL, NULL} -}; -#endif - -/** - * Initializes potential list of extensions if ctx == NULL, or actually enables - * extensions for a context. - */ -void intelInitExtensions(struct intel_context *intel, GLboolean enable_imaging) -{ - GLcontext *ctx = intel ? intel->st->ctx : NULL; - /* Disable imaging extension until convolution is working in teximage paths. - */ - enable_imaging = GL_FALSE; - - driInitExtensions(ctx, card_extensions, enable_imaging); - -#if 0 - if (intel == NULL || - (IS_965(intel->intelScreen->deviceID) && - intel->intelScreen->drmMinor >= 8)) - driInitExtensions(ctx, arb_oc_extensions, GL_FALSE); - - if (intel == NULL || IS_965(intel->intelScreen->deviceID)) - driInitExtensions(ctx, brw_extensions, GL_FALSE); -#endif -} #ifdef DEBUG @@ -259,10 +204,10 @@ intelCreateContext(const __GLcontextModes * visual, /* * memory pools */ - DRM_LIGHT_LOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext); + DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); // ZZZ JB should be per screen and not be done per context havePools = intelCreatePools(sPriv); - DRM_UNLOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext); + DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); if (!havePools) return GL_FALSE; @@ -270,7 +215,7 @@ intelCreateContext(const __GLcontextModes * visual, /* Dri stuff */ intel->hHWContext = driContextPriv->hHWContext; intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->lock; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); intel->iw.irq_seq = -1; @@ -320,7 +265,7 @@ intelCreateContext(const __GLcontextModes * visual, intel->st = st_create_context(pipe, visual, st_share); - intelInitExtensions( intel, GL_TRUE ); + driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE ); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_lock.c b/src/gallium/winsys/dri/intel/intel_lock.c index 469090c0e1..406284c98f 100644 --- a/src/gallium/winsys/dri/intel/intel_lock.c +++ b/src/gallium/winsys/dri/intel/intel_lock.c @@ -50,9 +50,6 @@ intelContendedLock(struct intel_context *intel, uint flags) DBG(LOCK, "%s - got contended lock\n", __progname); - if (sPriv->dri2.enabled) - return; - /* If the window moved, may need to set a new cliprect now. * * NOTE: This releases and regains the hw lock, so all state @@ -61,8 +58,8 @@ intelContendedLock(struct intel_context *intel, uint flags) if (dPriv) DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); - if (sarea && (sarea->width != intelScreen->front.width || - sarea->height != intelScreen->front.height)) { + if (sarea->width != intelScreen->front.width || + sarea->height != intelScreen->front.height) { intelUpdateScreenRotation(sPriv, sarea); } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index e456c28d0d..8817a80a5a 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -60,114 +60,7 @@ static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; extern const struct dri_extension card_extensions[]; -static GLboolean -intel_get_param(__DRIscreenPrivate *psp, int param, int *value) -{ - int ret; - struct drm_i915_getparam gp; - - gp.param = param; - gp.value = value; - ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "drm_i915_getparam: %d\n", ret); - return GL_FALSE; - } - - return GL_TRUE; -} - -static void -intelSetTexOffset(__DRIcontext *pDRICtx, int texname, - unsigned long long offset, int depth, uint pitch) -{ - abort(); -#if 0 - struct intel_context *intel = (struct intel_context*) - ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; - struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); - struct st_texture_object *stObj = st_texture_object(tObj); - - if (!stObj) - return; - - if (stObj->pt) - st->pipe->texture_release(intel->st->pipe, &stObj->pt); - - stObj->imageOverride = GL_TRUE; - stObj->depthOverride = depth; - stObj->pitchOverride = pitch; - - if (offset) - stObj->textureOffset = offset; -#endif -} - - -static void -intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv, - __DRIcontextPrivate *pcp, - __DRIDrawableConfigEvent *event) -{ - (void) dPriv; - (void) pcp; - (void) event; -} - -static void -intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, - __DRIcontextPrivate *pcp, - __DRIBufferAttachEvent *ba) -{ - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - - switch (ba->buffer.attachment) { - case DRI_DRAWABLE_BUFFER_FRONT_LEFT: - intelScreen->front.width = dPriv->w; - intelScreen->front.height = dPriv->h; - intelScreen->front.cpp = ba->buffer.cpp; - intelScreen->front.pitch = ba->buffer.pitch; - driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); - driBOSetReferenced(intelScreen->front.buffer, ba->buffer.handle); - break; - - case DRI_DRAWABLE_BUFFER_BACK_LEFT: - case DRI_DRAWABLE_BUFFER_DEPTH: - case DRI_DRAWABLE_BUFFER_STENCIL: - case DRI_DRAWABLE_BUFFER_ACCUM: - /* anything ?? */ - break; - - default: - fprintf(stderr, "unhandled buffer attach event, attachment type %d\n", - ba->buffer.attachment); - return; - } -} - -static const __DRItexOffsetExtension intelTexOffsetExtension = { - { __DRI_TEX_OFFSET }, - intelSetTexOffset, -}; - -#if 0 -static const __DRItexBufferExtension intelTexBufferExtension = { - { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, - intelSetTexBuffer, -}; -#endif - -static const __DRIextension *intelScreenExtensions[] = { - &driReadDrawableExtension, - &driCopySubBufferExtension.base, - &driSwapControlExtension.base, - &driFrameTrackingExtension.base, - &driMediaStreamCounterExtension.base, - &intelTexOffsetExtension.base, -// &intelTexBufferExtension.base, - NULL -}; static void @@ -284,8 +177,7 @@ intelCreatePools(__DRIscreenPrivate * sPriv) intelScreen->havePools = GL_TRUE; - if (intelScreen->sarea) - intelUpdateScreenRotation(sPriv, intelScreen->sarea); + intelUpdateScreenRotation(sPriv, intelScreen->sarea); return GL_TRUE; } @@ -318,6 +210,11 @@ intelInitDriver(__DRIscreenPrivate * sPriv) struct intel_screen *intelScreen; I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> + getProcAddress("glxEnableExtension")); + void *const psc = sPriv->psc->screenConfigs; + if (sPriv->devPrivSize != sizeof(I830DRIRec)) { fprintf(stderr, "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); @@ -334,19 +231,28 @@ intelInitDriver(__DRIscreenPrivate * sPriv) __driConfigOptions, __driNConfigOptions); sPriv->private = (void *) intelScreen; - intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + - gDRIPriv->sarea_priv_offset); + intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + + gDRIPriv->sarea_priv_offset); intelScreen->deviceID = gDRIPriv->deviceID; - intelScreen->front.cpp = gDRIPriv->cpp; - intelScreen->drmMinor = sPriv->drm_version.minor; + intelScreen->drmMinor = sPriv->drmMinor; + + assert(gDRIPriv->bitsPerPixel == 16 || + gDRIPriv->bitsPerPixel == 32); + intelUpdateScreenRotation(sPriv, intelScreen->sarea); if (0) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - sPriv->extensions = intelScreenExtensions; + if (glx_enable_extension != NULL) { + (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); + (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); + (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); + } intel_be_init_device(&intelScreen->base, sPriv->fd); intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; @@ -445,19 +351,65 @@ intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) return 0; } -static __DRIconfig ** -intelFillInModes(__DRIscreenPrivate *psp, - unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) + +static void +intelSetTexOffset(__DRIcontext *pDRICtx, int texname, + unsigned long long offset, int depth, uint pitch) +{ + abort(); +#if 0 + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct st_texture_object *stObj = st_texture_object(tObj); + + if (!stObj) + return; + + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); + + stObj->imageOverride = GL_TRUE; + stObj->depthOverride = depth; + stObj->pitchOverride = pitch; + + if (offset) + stObj->textureOffset = offset; +#endif +} + + +static const struct __DriverAPIRec intelAPI = { + .InitDriver = intelInitDriver, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = intelCopySubBuffer, + .setTexOffset = intelSetTexOffset, +}; + + +static __GLcontextModes * +intelFillInModes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, boolean have_back_buffer) { - __DRIconfig **configs; + __GLcontextModes *modes; __GLcontextModes *m; unsigned num_modes; unsigned depth_buffer_factor; unsigned back_buffer_factor; GLenum fb_format; GLenum fb_type; - int i; /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't * support pageflipping at all. @@ -499,143 +451,100 @@ intelFillInModes(__DRIscreenPrivate *psp, 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); - if (configs == NULL) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + modes = + (*dri_interface->createContextModes) (num_modes, + sizeof(__GLcontextModes)); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_DIRECT_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; } /* Mark the visual as slow if there are "fake" stencil bits. */ - for (i = 0; configs[i]; i++) { - m = &configs[i]->modes; + for (m = modes; m != NULL; m = m->next) { if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { m->visualRating = GLX_SLOW_CONFIG; } } - return configs; + return modes; } + /** - * This is the driver specific part of the createNewScreen entry point. - * - * \todo maybe fold this into intelInitDriver + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. * - * \return the __GLcontextModes supported by this driver + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. */ -static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp) +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, + __DRIscreen * psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) { -#ifdef I915 - static const __DRIversion ddx_expected = { 1, 5, 0 }; -#else - static const __DRIversion ddx_expected = { 1, 6, 0 }; -#endif + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 7, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 5, 0 }; - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + static const __DRIversion drm_expected = { 1, 7, 0 }; + + dri_interface = interface; if (!driCheckDriDdxDrmVersions2("i915", - &psp->dri_version, &dri_expected, - &psp->ddx_version, &ddx_expected, - &psp->drm_version, &drm_expected)) { + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { return NULL; } - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is - * called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - intelInitExtensions(NULL, GL_TRUE); - - if (!intelInitDriver(psp)) - return NULL; - - psp->extensions = intelScreenExtensions; - - return (const __DRIconfig **) - intelFillInModes(psp, dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, 1); -} - -/** - * This is the driver specific part of the createNewScreen entry point. - * - * \return the __GLcontextModes supported by this driver - */ -static const -__DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp) -{ - struct intel_screen *intelScreen; - - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is - * called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - intelInitExtensions(NULL, GL_TRUE); - - /* Allocate the private area */ - intelScreen = CALLOC_STRUCT(intel_screen); - if (!intelScreen) { - fprintf(stderr, "\nERROR! Allocating private area failed\n"); - return GL_FALSE; + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &intelAPI); + + if (psp != NULL) { + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + *driver_modes = intelFillInModes(dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create + * is called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); } - /* parse information in __driConfigOptions */ - driParseOptionInfo(&intelScreen->optionCache, - __driConfigOptions, __driNConfigOptions); - - psp->private = (void *) intelScreen; - - intelScreen->drmMinor = psp->drm_version.minor; - /* Determine chipset ID? */ - if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID, - &intelScreen->deviceID)) - return GL_FALSE; - - psp->extensions = intelScreenExtensions; - - intel_be_init_device(&intelScreen->base, psp->fd); - intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; - intelScreen->base.base.get_name = intel_get_name; - - return driConcatConfigs(intelFillInModes(psp, 16, 16, 0, 1), - intelFillInModes(psp, 32, 24, 8, 1)); + return (void *) psp; } -const struct __DriverAPIRec driDriverAPI = { - .InitScreen = intelInitScreen, - .DestroyScreen = intelDestroyScreen, - .CreateContext = intelCreateContext, - .DestroyContext = intelDestroyContext, - .CreateBuffer = intelCreateBuffer, - .DestroyBuffer = intelDestroyBuffer, - .SwapBuffers = intelSwapBuffers, - .MakeCurrent = intelMakeCurrent, - .UnbindContext = intelUnbindContext, - .GetSwapInfo = intelGetSwapInfo, - .GetDrawableMSC = driDrawableGetMSC32, - .WaitForMSC = driWaitForMSC32, - .CopySubBuffer = intelCopySubBuffer, - - .InitScreen2 = intelInitScreen2, - .HandleDrawableConfig = intelHandleDrawableConfig, - .HandleBufferAttach = intelHandleBufferAttach, -}; diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index 5a3ae1dc0f..8036917903 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -32,7 +32,7 @@ #include "i830_common.h" #include "xmlconfig.h" #include "intel_drm/ws_dri_bufpool.h" -#include "state_tracker/st_context.h" + #include "pipe/p_compiler.h" #include "intel_drm/intel_be_device.h" @@ -116,7 +116,5 @@ intelCreateContext(const __GLcontextModes * visual, __DRIcontextPrivate * driContextPriv, void *sharedContextPrivate); -extern void -intelInitExtensions(struct intel_context *intel, GLboolean enable_imaging); #endif diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 8b17154cf9..7f3babd98e 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -78,8 +78,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, * current context (which is what intelScreenContext should return) might * not get a contended lock and thus cliprects not updated (tests/manywin) */ - if (!intel->driScreen->dri2.enabled && - intel_context(dPriv->driContextPriv) != intel) + if (intel_context(dPriv->driContextPriv) != intel) DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); -- cgit v1.2.3 From 5805a9e32881831f320bcd1a95fbfacf17aef5d5 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 17 Jun 2008 17:46:45 +0200 Subject: i915: Made region pool a slabpool --- src/gallium/winsys/common/intel_drm/intel_be_device.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c index 0fc1894eaa..3eed0fe410 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.c +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.c @@ -220,7 +220,18 @@ intel_be_init_device(struct intel_be_device *dev, int fd) dev->mallocPool = driMallocPoolInit(); dev->staticPool = driDRMPoolInit(dev->fd); - dev->regionPool = driDRMPoolInit(dev->fd); + /* Sizes: 64 128 256 512 1024 2048 4096 8192 16384 32768 */ + dev->regionPool = driSlabPoolInit(dev->fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + 64, + 10, 120, 4096 * 64, 0, + dev->fMan); + dev->vertexPool = driSlabPoolInit(dev->fd, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | -- cgit v1.2.3 From 1496bba42904cbc9b827816b7924fa930661c22a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 17 Jun 2008 14:28:07 -0600 Subject: egl: call st_get_proc_address() --- src/gallium/winsys/egl_xlib/egl_xlib.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 7bef46d560..194bf2842a 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -210,11 +210,7 @@ xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) static _EGLProc xlib_eglGetProcAddress(const char *procname) { - /* XXX for each supported API, evaluate GetProcAddress(name) */ - /* - return _glapi_get_proc_address(procname); - */ - return NULL; + return (_EGLProc) st_get_proc_address(procname); } -- cgit v1.2.3 From 0cf79316d076d598f143b68f61308df9ddaf5e9a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 18 Jun 2008 09:21:09 -0600 Subject: egl: omit libmesa.a glapi.c from library --- src/gallium/winsys/egl_xlib/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile index d5595b819a..76f1b56da4 100644 --- a/src/gallium/winsys/egl_xlib/Makefile +++ b/src/gallium/winsys/egl_xlib/Makefile @@ -28,9 +28,13 @@ WINSYS_OBJECTS = $(WINSYS_SOURCES:.c=.o) LIBS = \ $(GALLIUM_DRIVERS) \ + $(GALLIUM_AUXILIARIES) + +# XXX temporary (should create a separate lib with the GL API funcs and +# mesa code, as done for ES 1.x, 2.x, OpenVG, etc) +UNUSED_LIBS = \ $(TOP)/src/mesa/libglapi.a \ $(TOP)/src/mesa/libmesa.a \ - $(GALLIUM_AUXILIARIES) LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1 @@ -56,7 +60,7 @@ $(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(WINSYS_OBJECTS) $(LIBS) -noprefix \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) \ - --start-group $(LIBS) --end-group + --whole-archive $(LIBS) --no-whole-archive depend: $(ALL_SOURCES) -- cgit v1.2.3 From 064001dbe7fd6cbb6bd5c91bdf7f0831b9c351a9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 19 Jun 2008 16:12:17 -0600 Subject: egl: use dlsym() to try to identify APIs --- src/gallium/winsys/egl_xlib/egl_xlib.c | 47 ++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 194bf2842a..85fc83a4dc 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -32,6 +32,7 @@ */ +#include #include #include "pipe/p_compiler.h" @@ -202,7 +203,6 @@ xlib_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, static EGLBoolean xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) { - return EGL_TRUE; } @@ -342,6 +342,10 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, /* API-dependent context creation */ switch (ctx->Base.ClientAPI) { + case EGL_OPENGL_ES_API: + _eglLog(_EGL_DEBUG, "Create Context for ES version %d\n", + ctx->Base.ClientVersion); + /* fall-through */ case EGL_OPENGL_API: /* create a softpipe context */ ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL); @@ -372,6 +376,8 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx) else { /* API-dependent clean-up */ switch (context->Base.ClientAPI) { + case EGL_OPENGL_ES_API: + /* fall-through */ case EGL_OPENGL_API: st_destroy_context(context->Context); break; @@ -554,6 +560,36 @@ xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) } +/** + * Determine which API(s) is(are) present by looking for some specific + * global symbols. + */ +static EGLint +find_supported_apis(void) +{ + EGLint mask = 0; + void *handle; + + handle = dlopen(NULL, 0); + + if (dlsym(handle, "st_api_OpenGL_ES1")) + mask |= EGL_OPENGL_ES_BIT; + + if (dlsym(handle, "st_api_OpenGL_ES2")) + mask |= EGL_OPENGL_ES2_BIT; + + if (dlsym(handle, "st_api_OpenGL")) + mask |= EGL_OPENGL_BIT; + + if (dlsym(handle, "st_api_OpenVG")) + mask |= EGL_OPENVG_BIT; + + dlclose(handle); + + return mask; +} + + /** * This is the main entrypoint into the driver. * Called by libEGL to instantiate an _EGLDriver object. @@ -584,7 +620,14 @@ _eglMain(_EGLDisplay *dpy, const char *args) xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent; xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers; - xdrv->Base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; + xdrv->Base.ClientAPIsMask = find_supported_apis(); + if (xdrv->Base.ClientAPIsMask == 0x0) { + /* the app isn't directly linked with any EGL-supprted APIs + * (such as libGLESv2.so) so use an EGL utility to see what + * APIs might be loaded dynamically on this system. + */ + xdrv->Base.ClientAPIsMask = _eglFindAPIs(); + } xdrv->Base.Name = "Xlib/softpipe"; -- cgit v1.2.3 From a87e717d0d302bc376eff29d17d35f1314ff1a57 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 20 Jun 2008 10:20:47 -0600 Subject: egl: added null ptr checks --- src/gallium/winsys/egl_xlib/egl_xlib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 85fc83a4dc..eeb15e30a9 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -413,7 +413,10 @@ xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, (draw_surf ? draw_surf->Framebuffer : NULL), (read_surf ? read_surf->Framebuffer : NULL)); - check_and_update_buffer_size(draw_surf); + if (draw_surf) + check_and_update_buffer_size(draw_surf); + if (read_surf && read_surf != draw_surf) + check_and_update_buffer_size(draw_surf); return EGL_TRUE; } -- cgit v1.2.3 From 78791d1065c93694a105d4c2cdaee7678a69213a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 20 Jun 2008 14:30:21 -0600 Subject: egl: added cpp assertions/sanity checks --- src/gallium/winsys/egl_xlib/sw_winsys.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index fd0cb9fb12..28cca9e581 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -194,6 +194,8 @@ surface_alloc_storage(struct pipe_winsys *winsys, surf->pitch = round_up(width, alignment / surf->cpp); surf->usage = flags; + assert(surf->cpp >= 1); + assert(surf->cpp <= 16); assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, -- cgit v1.2.3 From b750b5326df0a067f9baf237bee50d31ca69729d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 24 Jun 2008 11:40:25 +0900 Subject: gdi: Update for surface_alloc_storage changes. --- src/gallium/winsys/gdi/wmesa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c index 74a8292352..0b93f8c4c3 100644 --- a/src/gallium/winsys/gdi/wmesa.c +++ b/src/gallium/winsys/gdi/wmesa.c @@ -469,7 +469,8 @@ wm_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags) + unsigned flags, + unsigned tex_usage) { const unsigned alignment = 64; -- cgit v1.2.3 From 4802a687a7050b7b5dd3683ae43fd4f26c4a718e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 24 Jun 2008 14:00:10 +0900 Subject: dri/intel: Use standard integer types. --- src/gallium/winsys/dri/intel/intel_screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 8817a80a5a..1d61617ab5 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -418,8 +418,8 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML }; - u_int8_t depth_bits_array[3]; - u_int8_t stencil_bits_array[3]; + uint8_t depth_bits_array[3]; + uint8_t stencil_bits_array[3]; depth_bits_array[0] = 0; -- cgit v1.2.3 From 2d11411b19f725591e096b8a75dec94831d7bce7 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 24 Jun 2008 13:09:43 +0200 Subject: i915: Moved screen creation to intel_be_device --- .../winsys/common/intel_drm/intel_be_device.c | 9 ++++++++- .../winsys/common/intel_drm/intel_be_device.h | 7 ++++++- src/gallium/winsys/dri/intel/Makefile | 5 +++-- src/gallium/winsys/dri/intel/intel_context.c | 23 +++------------------- src/gallium/winsys/dri/intel/intel_screen.c | 10 ++++++---- 5 files changed, 26 insertions(+), 28 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c index 3eed0fe410..efb57a394e 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.c +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.c @@ -16,6 +16,8 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "i915simple/i915_screen.h" + /* Turn a pipe winsys into an intel/pipe winsys: */ static INLINE struct intel_be_device * @@ -192,7 +194,7 @@ intel_be_fence_finish( struct pipe_winsys *sws, */ boolean -intel_be_init_device(struct intel_be_device *dev, int fd) +intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id) { dev->fd = fd; dev->max_batch_size = 16 * 4096; @@ -252,6 +254,11 @@ intel_be_init_device(struct intel_be_device *dev, int fd) 1, 40, dev->max_batch_size * 16, 0, dev->fMan); + /* Fill in this struct with callbacks that i915simple will need to + * communicate with the window system, buffer manager, etc. + */ + dev->screen = i915_create_screen(&dev->base, id); + return true; } diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.h b/src/gallium/winsys/common/intel_drm/intel_be_device.h index ec5cace71c..abf0253917 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.h +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.h @@ -12,6 +12,11 @@ struct intel_be_device { struct pipe_winsys base; + /** + * Hw level screen + */ + struct pipe_screen *screen; + int fd; /**< Drm file discriptor */ size_t max_batch_size; @@ -28,7 +33,7 @@ struct intel_be_device }; boolean -intel_be_init_device(struct intel_be_device *device, int fd); +intel_be_init_device(struct intel_be_device *device, int fd, unsigned id); void intel_be_destroy_device(struct intel_be_device *dev); diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index 00ce21f690..5b51f0815d 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -6,8 +6,9 @@ LIBNAME = i915_dri.so PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ - $(TOP)/src/gallium/winsys/common/intel_drm/libinteldrm.a + $(TOP)/src/gallium/winsys/common/intel_drm/libinteldrm.a \ + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a + DRIVER_SOURCES = \ intel_winsys_softpipe.c \ diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 8284e0edbb..97ef731aaa 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -134,25 +134,6 @@ static const struct dri_debug_control debug_control[] = { -/** - * Create i915 hardware rendering context. - */ -static struct pipe_context * -intel_create_i915simple(struct intel_context *intel, - struct pipe_winsys *winsys) -{ - struct pipe_screen *screen; - - /* Fill in this struct with callbacks that i915simple will need to - * communicate with the window system, buffer manager, etc. - */ - screen = i915_create_screen(winsys, intel->intelScreen->deviceID); - - /* Create the i915simple context: - */ - return i915_create_context(screen, winsys, &intel->base.base ); -} - static void intel_lock_hardware(struct intel_be_context *context) { @@ -250,7 +231,9 @@ intelCreateContext(const __GLcontextModes * visual, case PCI_CHIP_Q35_G: case PCI_CHIP_I915_G: case PCI_CHIP_I915_GM: - pipe = intel_create_i915simple( intel, &intelScreen->base.base ); + pipe = i915_create_context(intelScreen->base.screen, + &intelScreen->base.base, + &intel->base.base); break; default: fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 1d61617ab5..809af2e553 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -198,10 +198,12 @@ intel_flush_frontbuffer( struct pipe_winsys *winsys, struct pipe_surface *surf, void *context_private) { - struct intel_context *intel = (struct intel_context *) context_private; - __DRIdrawablePrivate *dPriv = intel->driDrawable; + //struct intel_context *intel = (struct intel_context *) context_private; + //__DRIdrawablePrivate *dPriv = intel->driDrawable; - intelDisplaySurface(dPriv, surf, NULL); + assert((int)"Doesn't work currently" & 0); + + //intelDisplaySurface(dPriv, surf, NULL); } static boolean @@ -254,9 +256,9 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - intel_be_init_device(&intelScreen->base, sPriv->fd); intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; intelScreen->base.base.get_name = intel_get_name; + intel_be_init_device(&intelScreen->base, sPriv->fd, intelScreen->deviceID); return GL_TRUE; } -- cgit v1.2.3 From e95697758eda9b92a01a504bce823acd5201b48d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 24 Jun 2008 14:42:12 +0200 Subject: i915: Create a texture and surface for shared frontbuffer --- src/gallium/winsys/dri/intel/intel_screen.c | 67 +++++++++++++++++++++++++++-- src/gallium/winsys/dri/intel/intel_screen.h | 2 + 2 files changed, 66 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 809af2e553..18427a4586 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -38,10 +38,69 @@ #include "intel_drm/ws_dri_bufpool.h" #include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_inlines.h" #include "state_tracker/st_public.h" #include "state_tracker/st_cb_fbo.h" +static void +intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle); +static void +intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle) +{ + struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); + struct pipe_screen *screen = intelScreen->base.screen; + struct pipe_texture *texture; + struct pipe_texture templat; + struct pipe_surface *surface; + struct pipe_buffer *buffer = &be_buf->base; + unsigned pitch; + + assert(intelScreen->front.cpp == 4); + + /* XXX create a intel_be function for this */ + { + driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); + driBOSetReferenced(intelScreen->front.buffer, handle); + + memset(be_buf, 0, sizeof(*be_buf)); + buffer->refcount = 1; + buffer->alignment = 0; + buffer->usage = 0; + buffer->size = driBOSize(intelScreen->front.buffer); + be_buf->driBO = intelScreen->front.buffer; + } + + memset(&templat, 0, sizeof(templat)); + templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + templat.target = PIPE_TEXTURE_2D; + templat.last_level = 0; + templat.depth[0] = 1; + templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; + templat.cpp = intelScreen->front.cpp; + templat.width[0] = intelScreen->front.width; + templat.height[0] = intelScreen->front.height; + pitch = intelScreen->front.pitch / intelScreen->front.cpp; + + texture = screen->texture_blanket(screen, + &templat, + &pitch, + buffer); + + /* Unref the buffer we don't need it anyways */ + pipe_buffer_reference(screen->winsys, &buffer, NULL); + + surface = screen->get_tex_surface(screen, + texture, + 0, + 0, + 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + + intelScreen->front.texture = texture; + intelScreen->front.surface = surface; +} PUBLIC const char __driConfigOptions[] = DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE @@ -157,10 +216,12 @@ intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) } #else if (intelScreen->base.staticPool) { - if (intelScreen->front.buffer) + if (intelScreen->front.buffer) { driBOUnReference(intelScreen->front.buffer); - driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); - driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle); + pipe_surface_reference(&intelScreen->front.surface, NULL); + pipe_texture_reference(&intelScreen->front.texture, NULL); + } + intelCreateSurface(intelScreen, &intelScreen->base.base, sarea->front_bo_handle); } #endif } diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index 8036917903..e62f9e71ec 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -47,6 +47,8 @@ struct intel_screen /* We create a static dri buffer for the frontbuffer. */ struct _DriBufferObject *buffer; + struct pipe_surface *surface; + struct pipe_texture *texture; char *map; /* memory map */ int offset; /* from start of video mem, in bytes */ -- cgit v1.2.3 From 6106db4c5da6fc5ae9ef157c939ce0834cdc5b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 27 Jun 2008 13:01:37 +0900 Subject: scons: Fix i965/xlib build. --- src/gallium/winsys/xlib/SConscript | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 5e98a36abc..14a85ae0f2 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -3,7 +3,11 @@ Import('*') -if env['platform'] == 'linux' and 'mesa' in env['statetrackers'] and not env['dri']: +if env['platform'] == 'linux' \ + and 'mesa' in env['statetrackers'] \ + and 'softpipe' in env['drivers'] \ + and 'i965simple' in env['drivers'] \ + and not env['dri']: env = env.Clone() @@ -24,6 +28,7 @@ if env['platform'] == 'linux' and 'mesa' in env['statetrackers'] and not env['dr drivers = [ softpipe, + i965simple ] # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -- cgit v1.2.3 From 4ddd65967915ca4846f2831bc676c878a29dae4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 27 Jun 2008 19:37:56 +0900 Subject: gallium: Drop pipe_texture->cpp and pipe_surface->cpp. The chars-per-pixel concept falls apart with compressed and yuv images, where more than one pixel are coded in a single data block. --- src/gallium/winsys/xlib/brw_aub.c | 9 ++++++--- src/gallium/winsys/xlib/xm_winsys.c | 24 ++++++++++++++---------- src/gallium/winsys/xlib/xm_winsys_aub.c | 31 +++++++++++++++++-------------- 3 files changed, 37 insertions(+), 27 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c index 10eedd8402..6e814ce5d1 100644 --- a/src/gallium/winsys/xlib/brw_aub.c +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -322,7 +322,10 @@ void brw_aub_dump_bmp( struct brw_aubfile *aubfile, struct aub_dump_bmp db; unsigned format; - if (surface->cpp == 4) + assert(surface->block.width == 1); + assert(surface->block.height == 1); + + if (surface->block.size == 4) format = 0x7; else format = 0x3; @@ -331,8 +334,8 @@ void brw_aub_dump_bmp( struct brw_aubfile *aubfile, db.xmin = 0; db.ymin = 0; db.format = format; - db.bpp = surface->cpp * 8; - db.pitch = surface->pitch; + db.bpp = surface->block.size * 8; + db.pitch = surface->stride/surface->block.size; db.xsize = surface->width; db.ysize = surface->height; db.addr = gtt_offset; diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index b14758f333..9225ee510d 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -364,9 +364,10 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) return; } - if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { - alloc_shm_ximage(xm_buf, b, surf->pitch, surf->height); + assert(surf->block.width == 1); + assert(surf->block.height == 1); + alloc_shm_ximage(xm_buf, b, surf->stride/surf->block.size, surf->height); } ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; @@ -386,7 +387,7 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) /* update XImage's fields */ ximage->width = surf->width; ximage->height = surf->height; - ximage->bytes_per_line = surf->pitch * surf->cpp; + ximage->bytes_per_line = surf->stride; XPutImage(b->xm_visual->display, b->drawable, b->gc, ximage, 0, 0, 0, 0, surf->width, surf->height); @@ -497,18 +498,21 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, surf->width = width; surf->height = height; surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); surf->usage = flags; -#ifdef GALLIUM_CELL /* XXX a bit of a hack */ - height = round_up(height, TILE_SIZE); -#endif - assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); +#ifdef GALLIUM_CELL /* XXX a bit of a hack */ + surf->stride * round_up(surf->nblocksy, TILE_SIZE)); +#else + surf->stride * surf->nblocksy); +#endif + if(!surf->buffer) return -1; diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index 77376099f0..7fc9debdd5 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -279,22 +279,25 @@ aub_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned flags, unsigned tex_usage) { - const unsigned alignment = 64; - - surf->width = width; - surf->height = height; - surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->stride * surf->nblocksy); if(!surf->buffer) - return -1; + return -1; - return 0; + return 0; } static void -- cgit v1.2.3 From 4f45dbc6aa9b55d96cf6aeb32117e117e333b4a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 27 Jun 2008 20:56:29 +0900 Subject: gdi: Update for cpp removal. --- src/gallium/winsys/gdi/wmesa.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c index 0b93f8c4c3..86b085ab84 100644 --- a/src/gallium/winsys/gdi/wmesa.c +++ b/src/gallium/winsys/gdi/wmesa.c @@ -477,13 +477,15 @@ wm_surface_alloc_storage(struct pipe_winsys *winsys, surf->width = width; surf->height = height; surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); + surf->nblocksy * surf->stride); if(!surf->buffer) return -1; -- cgit v1.2.3 From 5b9d823545ec588ea97cc599a278626b99430d81 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 27 Jun 2008 14:16:42 +0200 Subject: i915: Fix the last of the stride/pitch changes --- src/gallium/winsys/dri/intel/intel_screen.c | 4 ++-- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 18427a4586..89de188ada 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -78,10 +78,10 @@ intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, templat.last_level = 0; templat.depth[0] = 1; templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; - templat.cpp = intelScreen->front.cpp; templat.width[0] = intelScreen->front.width; templat.height[0] = intelScreen->front.height; - pitch = intelScreen->front.pitch / intelScreen->front.cpp; + pf_get_block(templat.format, &templat.block); + pitch = intelScreen->front.pitch; texture = screen->texture_blanket(screen, &templat, diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 7f3babd98e..f58da97c64 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -89,7 +89,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, const drm_clip_rect_t *pbox = dPriv->pClipRects; const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; const int cpp = intelScreen->front.cpp; - const int srcpitch = surf->pitch; + const int srcpitch = surf->stride / cpp; int BR13, CMD; int i; -- cgit v1.2.3 From a1fb565ea7ac9f86beb4deece6a24d79e7b7860e Mon Sep 17 00:00:00 2001 From: Robert Ellison Date: Thu, 26 Jun 2008 08:55:00 -0600 Subject: egl: These changes allow an eglBindAPI(EGL_OPENGL_ES_API) to succeed, and to work correctly with GLES1 and GLES2. - egl_xdri.c just sets the EGL_OPENGL_ES_BIT as well as the EGL_OPENGL_BIT in ClientAPIsMask - eglconfig.c allows the renderable type to include EGL_OPENGL_ES2_BIT as well as EGL_OPENGL_ES_BIT. - egl_xlib.c sets the EGL_NATIVE_RENDERABLE attribute to EGL_FALSE for all softpipe configurations. (Otherwise, an eglChooseConfig() that looks for particular values of EGL_NATIVE_RENDERABLE will fail.) --- src/gallium/winsys/egl_xlib/egl_xlib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index eeb15e30a9..8045c0d0ca 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -172,6 +172,7 @@ create_configs(_EGLDriver *drv, EGLDisplay dpy) SET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE, sbits); SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_ID, visid); SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, vistype); + SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE); _eglAddConfig(disp, config); } -- cgit v1.2.3 From 429a08384c2ea66d446e46beb28e33ee3b764d52 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 27 Jun 2008 16:02:43 +0200 Subject: gallium: handle msaa --- src/gallium/winsys/dri/intel/intel_screen.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 89de188ada..cfecebdb8c 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -483,11 +483,13 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, 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; + msaa_samples_array[0] = 0; /* 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 @@ -521,7 +523,7 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, if (!driFillInModes(&m, fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_TRUE_COLOR)) { + back_buffer_factor, msaa_samples_array, 1, GLX_TRUE_COLOR)) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; @@ -529,7 +531,7 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, if (!driFillInModes(&m, fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_DIRECT_COLOR)) { + back_buffer_factor, msaa_samples_array, 1, GLX_DIRECT_COLOR)) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; -- cgit v1.2.3 From 838b0d6e480c9ae90abb067c1ba4aee413df6fd9 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 27 Jun 2008 15:56:09 -0400 Subject: eh, we need a buildbot... fix the compilation --- src/gallium/winsys/egl_xlib/egl_xlib.c | 2 +- src/gallium/winsys/egl_xlib/sw_winsys.c | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 8045c0d0ca..042d7a5457 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -291,7 +291,7 @@ display_surface(struct pipe_winsys *pws, ximage->data = data; ximage->width = psurf->width; ximage->height = psurf->height; - ximage->bytes_per_line = psurf->pitch * psurf->cpp; + ximage->bytes_per_line = psurf->stride; XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc, ximage, 0, 0, 0, 0, psurf->width, psurf->height); diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index 28cca9e581..6956fb5b6f 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -190,16 +190,14 @@ surface_alloc_storage(struct pipe_winsys *winsys, surf->width = width; surf->height = height; surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); + pf_get_block(format, &surf->block); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); surf->usage = flags; - assert(surf->cpp >= 1); - assert(surf->cpp <= 16); assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); + surf->stride * height); if(!surf->buffer) return -1; -- cgit v1.2.3 From a7499b7fc753653fd24a91b1ab6a5b68e479193b Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 27 Jun 2008 16:47:22 -0400 Subject: egl: helps if the stride is right --- src/gallium/winsys/egl_xlib/sw_winsys.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index 6956fb5b6f..f4199e6f89 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -190,7 +190,9 @@ surface_alloc_storage(struct pipe_winsys *winsys, surf->width = width; surf->height = height; surf->format = format; - pf_get_block(format, &surf->block); + pf_get_block(surf->format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); surf->usage = flags; -- cgit v1.2.3 From d4b100a6a1f13ceaedf603bdce5ce95c2ce7e12c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 28 Jun 2008 16:04:01 -0600 Subject: egl: set config's EGL_CONFORMANT, EGL_RENDERABLE_TYPE, EGL_SURFACE_TYPE attributes --- src/gallium/winsys/egl_xlib/egl_xlib.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 042d7a5457..83b8bb95b1 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -133,6 +133,10 @@ bitcount(unsigned int n) static void create_configs(_EGLDriver *drv, EGLDisplay dpy) { + static const EGLint all_apis = (EGL_OPENGL_ES_BIT | + EGL_OPENGL_ES2_BIT | + EGL_OPENVG_BIT | + EGL_OPENGL_BIT); _EGLDisplay *disp = _eglLookupDisplay(dpy); XVisualInfo *visInfo, visTemplate; int num_visuals, i; @@ -173,6 +177,9 @@ create_configs(_EGLDriver *drv, EGLDisplay dpy) SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_ID, visid); SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, vistype); SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE); + SET_CONFIG_ATTRIB(config, EGL_CONFORMANT, all_apis); + SET_CONFIG_ATTRIB(config, EGL_RENDERABLE_TYPE, all_apis); + SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT); _eglAddConfig(disp, config); } -- cgit v1.2.3 From b6478021d572d9ec30212d6e6992496ee4cf347d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 29 Jun 2008 13:26:04 +1000 Subject: nouveau: adapt to cpp->pf_block changes --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 9 +++- src/gallium/winsys/dri/nouveau/nouveau_screen.c | 7 ++- src/gallium/winsys/dri/nouveau/nv04_surface.c | 63 +++++++++++++----------- src/gallium/winsys/dri/nouveau/nv50_surface.c | 42 +++++++++------- 4 files changed, 71 insertions(+), 50 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index ef5fb7ec0d..74413c408f 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -167,9 +167,14 @@ nouveau_context_create(const __GLcontextModes *glVis, fb_buf->bo = &fb_bo->base; fb_surf = calloc(1, sizeof(struct pipe_surface)); - fb_surf->cpp = nv_screen->front_cpp; - fb_surf->pitch = nv_screen->front_pitch / fb_surf->cpp; + if (nv_screen->front_cpp == 2) + fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; + else + fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; + pf_get_block(fb_surf->format, &fb_surf->block); + fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; fb_surf->height = nv_screen->front_height; + fb_surf->stride = fb_surf->width * fb_surf->block.size; fb_surf->refcount = 1; fb_surf->buffer = &fb_buf->base; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c index 9041275a88..b15ee7509c 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -209,8 +209,9 @@ nouveau_fill_in_modes(unsigned pixel_bits, unsigned depth_bits, GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML }; - u_int8_t depth_bits_array[4] = { 0, 16, 24, 24 }; - u_int8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; + uint8_t depth_bits_array[4] = { 0, 16, 24, 24 }; + uint8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; + uint8_t msaa_samples_array[1] = { 0 }; depth_buffer_factor = 4; back_buffer_factor = (have_back_buffer) ? 3 : 1; @@ -229,6 +230,7 @@ nouveau_fill_in_modes(unsigned pixel_bits, unsigned depth_bits, depth_buffer_factor, back_buffer_modes, back_buffer_factor, + msaa_samples_array, 1, GLX_TRUE_COLOR)) { fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__ ); @@ -242,6 +244,7 @@ nouveau_fill_in_modes(unsigned pixel_bits, unsigned depth_bits, depth_buffer_factor, back_buffer_modes, back_buffer_factor, + msaa_samples_array, 1, GLX_DIRECT_COLOR)) { fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__ ); diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index 83c790db17..0085b1c345 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -1,26 +1,35 @@ #include "pipe/p_context.h" +#include "pipe/p_format.h" #include "nouveau_context.h" static INLINE int -nv04_surface_format(int cpp) +nv04_surface_format(enum pipe_format format) { - switch (cpp) { - case 1: return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; - case 2: return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; - case 4: return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; + switch (format) { + case PIPE_FORMAT_A8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; default: return -1; } } static INLINE int -nv04_rect_format(int cpp) +nv04_rect_format(enum pipe_format format) { - switch (cpp) { - case 1: return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; - case 2: return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; - case 4: return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + switch (format) { + case PIPE_FORMAT_A8_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; default: return -1; } @@ -35,8 +44,8 @@ nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, struct pipe_surface *src = nv->surf_src; unsigned dst_offset, src_offset; - dst_offset = dst->offset + (dy * dst->pitch + dx) * dst->cpp; - src_offset = src->offset + (sy * src->pitch + sx) * src->cpp; + dst_offset = dst->offset + (dy * dst->stride) + (dx * dst->block.size); + src_offset = src->offset + (sy * src->stride) + (sx * src->block.size); while (h) { int count = (h > 2047) ? 2047 : h; @@ -47,16 +56,16 @@ nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RING (chan, src->pitch * src->cpp); - OUT_RING (chan, dst->pitch * dst->cpp); - OUT_RING (chan, w * src->cpp); + OUT_RING (chan, src->stride); + OUT_RING (chan, dst->stride); + OUT_RING (chan, w * src->block.size); OUT_RING (chan, count); OUT_RING (chan, 0x0101); OUT_RING (chan, 0); h -= count; - src_offset += src->pitch * src->cpp * count; - dst_offset += dst->pitch * dst->cpp * count; + src_offset += src->stride * count; + dst_offset += dst->stride * count; } } @@ -79,7 +88,7 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, struct nouveau_channel *chan = nv->nvc->channel; int format; - if (src->cpp != dst->cpp) + if (src->format != dst->format) return 1; /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback @@ -100,8 +109,8 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, } - if ((format = nv04_surface_format(dst->cpp)) < 0) { - NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp); + if ((format = nv04_surface_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad surface format 0x%x\n", dst->format); return 1; } nv->surface_copy = nv04_surface_copy_blit; @@ -116,8 +125,7 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); OUT_RING (chan, format); - OUT_RING (chan, ((dst->pitch * dst->cpp) << 16) | - (src->pitch * src->cpp)); + OUT_RING (chan, (dst->stride << 16) | src->stride); OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, @@ -142,13 +150,13 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, struct nouveau_grobj *rect = nv->nvc->NvGdiRect; int cs2d_format, gdirect_format; - if ((cs2d_format = nv04_surface_format(dst->cpp)) < 0) { - NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp); + if ((cs2d_format = nv04_surface_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad format = %d\n", dst->format); return 1; } - if ((gdirect_format = nv04_rect_format(dst->cpp)) < 0) { - NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp); + if ((gdirect_format = nv04_rect_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad format = %d\n", dst->format); return 1; } @@ -159,8 +167,7 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); OUT_RING (chan, cs2d_format); - OUT_RING (chan, ((dst->pitch * dst->cpp) << 16) | - (dst->pitch * dst->cpp)); + OUT_RING (chan, (dst->stride << 16) | dst->stride); OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c index d6da116b77..cf76d76cf5 100644 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -1,15 +1,21 @@ #include "pipe/p_context.h" +#include "pipe/p_format.h" #include "nouveau_context.h" static INLINE int -nv50_format(int cpp) +nv50_format(enum pipe_format format) { - switch (cpp) { - case 4: return NV50_2D_DST_FORMAT_32BPP; - case 3: return NV50_2D_DST_FORMAT_24BPP; - case 2: return NV50_2D_DST_FORMAT_16BPP; - case 1: return NV50_2D_DST_FORMAT_8BPP; + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV50_2D_DST_FORMAT_32BPP; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return NV50_2D_DST_FORMAT_24BPP; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV50_2D_DST_FORMAT_16BPP; + case PIPE_FORMAT_A8_UNORM: + return NV50_2D_DST_FORMAT_8BPP; default: return -1; } @@ -23,9 +29,9 @@ nv50_surface_copy_prep(struct nouveau_context *nv, struct nouveau_grobj *eng2d = nv->nvc->Nv2D; int surf_format; - assert(src->cpp == dst->cpp); + assert(src->format == dst->format); - surf_format = nv50_format(dst->cpp); + surf_format = nv50_format(dst->format); assert(surf_format >= 0); BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2); @@ -38,8 +44,8 @@ nv50_surface_copy_prep(struct nouveau_context *nv, OUT_RING (chan, surf_format); OUT_RING (chan, 1); BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); - OUT_RING (chan, dst->pitch * dst->cpp); - OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->stride); + OUT_RING (chan, dst->width); OUT_RING (chan, dst->height); OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); @@ -48,15 +54,15 @@ nv50_surface_copy_prep(struct nouveau_context *nv, BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); OUT_RING (chan, 0); OUT_RING (chan, 0); - OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->width); OUT_RING (chan, dst->height); BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 2); OUT_RING (chan, surf_format); OUT_RING (chan, 1); BEGIN_RING(chan, eng2d, NV50_2D_SRC_PITCH, 5); - OUT_RING (chan, src->pitch * src->cpp); - OUT_RING (chan, src->pitch); + OUT_RING (chan, src->stride); + OUT_RING (chan, src->width); OUT_RING (chan, src->height); OUT_RELOCh(chan, nouveau_buffer(src->buffer)->bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); @@ -105,11 +111,11 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, struct nouveau_grobj *eng2d = nv->nvc->Nv2D; int surf_format, rect_format; - surf_format = nv50_format(dst->cpp); + surf_format = nv50_format(dst->format); if (surf_format < 0) return 1; - rect_format = nv50_format(dst->cpp); + rect_format = nv50_format(dst->format); if (rect_format < 0) return 1; @@ -120,8 +126,8 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, OUT_RING (chan, surf_format); OUT_RING (chan, 1); BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); - OUT_RING (chan, dst->pitch * dst->cpp); - OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->stride); + OUT_RING (chan, dst->width); OUT_RING (chan, dst->height); OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); @@ -130,7 +136,7 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); OUT_RING (chan, 0); OUT_RING (chan, 0); - OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->width); OUT_RING (chan, dst->height); BEGIN_RING(chan, eng2d, 0x0580, 3); -- cgit v1.2.3 From bf94027fdde51aed476e9bfdd4326aa9040440b0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 29 Jun 2008 15:59:24 +1000 Subject: nv50: fixes after rebase + commits note on the code that was just pushed. OK, seems a lot of people have been getting the idea that nouveau is dying lately - I decided to commit some of the work I've been doing lately to prove them wrong :) Progress on my side is slow due to lack of time mainly, but I'm still around. Firstly, don't even bother trying to use gallium on G8x/G9x yet, it won't work. I've deliberately left all the necessary winsys changes out of the commits for a very good reason - I don't know what we're going to need from the DRM exactly yet and don't want to be continually breaking interfaces as I discover additional requirements. On my side, I think I've gone through about 3 different DRM interface changes, and have just discovered that I may need more yet. It'd be very annoying for everyone who uses nouveau to keep things in sync. Once I've got it sorted - I'll commit a lot of cool stuff. Stay tuned. Also, don't look at the shader code.. it's horribly nasty and full of hacks, I used it as an opportunity to learn G8x GPU programs at the same time. New semi-decent code is in works, and will follow at some point. :) --- src/gallium/winsys/dri/nouveau/nouveau_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c index b15ee7509c..df1fe7e69b 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -13,7 +13,7 @@ #include "nouveau_screen.h" #include "nouveau_swapbuffers.h" -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 #error nouveau_drm.h version does not match expected version #endif -- cgit v1.2.3 From c6ddcc10e31f26d17c1c8181013268766aca9ac6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 29 Jun 2008 16:02:01 +1000 Subject: nouveau: oops, bump the drm patchlevel back down again --- src/gallium/winsys/dri/nouveau/nouveau_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c index df1fe7e69b..b15ee7509c 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -13,7 +13,7 @@ #include "nouveau_screen.h" #include "nouveau_swapbuffers.h" -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 #error nouveau_drm.h version does not match expected version #endif -- cgit v1.2.3 From 9833aec6cbd113d24277aa5da8625c1427d831ca Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 30 Jun 2008 19:26:22 -0400 Subject: g3dvl: Use block and stride instead of cpp and pitch. --- src/gallium/winsys/g3dvl/xsp_winsys.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index eb4c9085d6..d04c4be580 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -101,6 +101,12 @@ static struct pipe_surface* xsp_surface_alloc(struct pipe_winsys *pws) return surface; } +/* Borrowed from Mesa's xm_winsys */ +static unsigned int round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + static int xsp_surface_alloc_storage ( struct pipe_winsys *pws, @@ -120,10 +126,13 @@ static int xsp_surface_alloc_storage surface->width = width; surface->height = height; surface->format = format; - surface->cpp = pf_get_size(format); - surface->pitch = width; + pf_get_block(format, &surface->block); + surface->nblocksx = pf_get_nblocksx(&surface->block, width); + surface->nblocksy = pf_get_nblocksy(&surface->block, height); + surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); surface->usage = flags; - surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->pitch * surface->cpp * height); + /* XXX: Need to consider block dims? See xm_winsys.c */ + surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * height); return 0; } -- cgit v1.2.3 From e99ce4af8a6a6f9b257bfceb0f9133a29f06f2c7 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 1 Jul 2008 15:52:37 +0200 Subject: i915: Last reference to surface -> pitch --- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index f58da97c64..f751f97524 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -97,7 +97,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, ASSERT(surf->cpp == cpp); DBG(SWAP, "screen pitch %d src surface pitch %d\n", - pitch, surf->pitch); + pitch, surf->stride); if (cpp == 2) { BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); -- cgit v1.2.3 From d94c7063ec9e87dbefea386606f0f21cdbd1d6f3 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 3 Jul 2008 12:12:25 +0200 Subject: i915: EGL almost works again --- src/gallium/winsys/egl_drm/intel/intel_context.c | 3 + src/gallium/winsys/egl_drm/intel/intel_context.h | 3 +- src/gallium/winsys/egl_drm/intel/intel_egl.c | 85 +++++++++++++--------- src/gallium/winsys/egl_drm/intel/intel_screen.c | 4 +- src/gallium/winsys/egl_drm/intel/intel_screen.h | 3 + .../winsys/egl_drm/intel/intel_swapbuffers.c | 9 ++- 6 files changed, 67 insertions(+), 40 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c index fdbaa230e5..7205fa4483 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -172,6 +172,9 @@ intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes pipe->priv = intel; intel->st = st_create_context(pipe, visual, st_share); + + screen->dummy = intel; + return TRUE; } diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h index ccf8120761..f05a213ff0 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.h +++ b/src/gallium/winsys/egl_drm/intel/intel_context.h @@ -64,8 +64,7 @@ struct intel_framebuffer { struct st_framebuffer *stfb; - /* other fields TBD */ - int other; + struct intel_screen *screen; struct _DriBufferObject *front_buffer; struct egl_drm_frontbuffer *front; }; diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 3b4ab330f5..6865bfa3d4 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -74,9 +74,11 @@ struct drm_screen uint32_t fbID; drmModeCrtcPtr crtc; - /* currently only support one output */ - drmModeOutputPtr output; - uint32_t outputID; + /* currently only support one connector */ + drmModeConnectorPtr connector; + drmModeEncoderPtr encoder; + uint32_t connectorID; + uint32_t encoderID; struct drm_mode_modeinfo *mode; @@ -92,26 +94,39 @@ drm_update_res(struct drm_driver *drm_drv) } static void -drm_add_modes_from_output(_EGLScreen *screen, drmModeOutputPtr output) +drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) { struct drm_mode_modeinfo *m; int i; - for (i = 0; i < output->count_modes; i++) { - m = &output->modes[i]; + for (i = 0; i < connector->count_modes; i++) { + m = &connector->modes[i]; _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name); } } +static void +print_modes(drmModeConnectorPtr connector) +{ + struct drm_mode_modeinfo *m; + int i; + + for (i = 0; i < connector->count_modes; i++) { + m = &connector->modes[i]; + printf("dfm %p %i %i %i\n", m, m->hdisplay, m->vdisplay, m->vrefresh); + } +} + static EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) { + printf("%s enter\n", __FUNCTION__); _EGLDisplay *disp = _eglLookupDisplay(dpy); struct drm_driver *drm_drv = (struct drm_driver *)drv; struct drm_screen *screen = NULL; - drmModeOutputPtr output = NULL; + drmModeConnectorPtr connector = NULL; drmModeResPtr res = NULL; - unsigned count_outputs = 0; + unsigned count_connectors = 0; EGLint i; int fd; @@ -130,40 +145,41 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) drm_update_res(drm_drv); res = drm_drv->res; if (res) - count_outputs = res->count_outputs; + count_connectors = res->count_connectors; - for(i = 0; i < count_outputs; i++) { - output = drmModeGetOutput(fd, res->outputs[i]); + for(i = 0; i < count_connectors; i++) { + connector = drmModeGetConnector(fd, res->connectors[i]); - if (!output) + if (!connector) continue; - if (output->connection == DRM_MODE_DISCONNECTED) { - drmModeFreeOutput(output); + if (connector->connection == DRM_MODE_DISCONNECTED) { + drmModeFreeConnector(connector); continue; } screen = malloc(sizeof(struct drm_screen)); memset(screen, 0, sizeof(*screen)); - screen->outputID = res->outputs[i]; - screen->output = output; + screen->connectorID = res->connectors[i]; + screen->connector = connector; _eglInitScreen(&screen->base); _eglAddScreen(disp, &screen->base); - drm_add_modes_from_output(&screen->base, output); + drm_add_modes_from_connector(&screen->base, connector); } /* for now we only have one config */ - _EGLConfig config; - _eglInitConfig(&config, i + 1); - _eglSetConfigAttrib(&config, EGL_RED_SIZE, 8); - _eglSetConfigAttrib(&config, EGL_GREEN_SIZE, 8); - _eglSetConfigAttrib(&config, EGL_BLUE_SIZE, 8); - _eglSetConfigAttrib(&config, EGL_ALPHA_SIZE, 8); - _eglSetConfigAttrib(&config, EGL_BUFFER_SIZE, 32); - _eglSetConfigAttrib(&config, EGL_DEPTH_SIZE, 24); - _eglSetConfigAttrib(&config, EGL_STENCIL_SIZE, 8); - _eglSetConfigAttrib(&config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); - _eglAddConfig(disp, &config); + _EGLConfig *config = calloc(1, sizeof(*config)); + memset(config, 1, sizeof(*config)); + _eglInitConfig(config, 1); + _eglSetConfigAttrib(config, EGL_RED_SIZE, 8); + _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); + _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); + _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); + _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); + _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24); + _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); + _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); + _eglAddConfig(disp, config); drv->Initialized = EGL_TRUE; @@ -401,13 +417,13 @@ drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, } static struct drm_mode_modeinfo * -drm_find_mode(drmModeOutputPtr output, _EGLMode *mode) +drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) { int i; struct drm_mode_modeinfo *m; - for (i = 0; i < output->count_modes; i++) { - m = &output->modes[i]; + for (i = 0; i < connector->count_modes; i++) { + m = &connector->modes[i]; if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) break; m = NULL; @@ -493,7 +509,7 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, if (!scrn->fb) goto err_bo; - scrn->mode = drm_find_mode(scrn->output, mode); + scrn->mode = drm_find_mode(scrn->connector, mode); if (!scrn->mode) { printf("oh noes, no matching mode found\n"); goto err_fb; @@ -504,7 +520,7 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, drm_drv->res->crtcs[1], scrn->fbID, 0, 0, - &scrn->outputID, 1, + &scrn->connectorID, 1, scrn->mode); @@ -549,7 +565,6 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re struct drm_context *ctx = lookup_drm_context(context); EGLBoolean b; - printf("drm_make_current\n"); b = _eglMakeCurrent(drv, dpy, draw, read, context); if (!b) return EGL_FALSE; @@ -559,7 +574,6 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re (void) readSurf; (void) ctx; - printf("enter intel_make_current\n"); intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); return EGL_TRUE; } @@ -588,6 +602,7 @@ _EGLDriver * _eglMain(_EGLDisplay *dpy, const char *args) { struct drm_driver *drm; + printf("%s enter\n", __FUNCTION__); drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); if (!drm) { diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c index 96b0bf1b85..2818b9676c 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.c +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.c @@ -56,7 +56,7 @@ intel_init_driver(struct egl_drm_device *device) /** TODO JB: ugly hack */ intel_screen->deviceID = PCI_CHIP_I945_GM; - intel_be_init_device(&intel_screen->base, device->drmFD); + intel_be_init_device(&intel_screen->base, device->drmFD, PCI_CHIP_I945_GM); intel_screen->pipe = i915_create_screen(&intel_screen->base.base, intel_screen->deviceID); @@ -76,6 +76,8 @@ intel_create_drawable(struct egl_drm_drawable *drawable, if (!intelfb) return GL_FALSE; + intelfb->screen = drawable->device->priv; + if (visual->redBits == 5) colorFormat = PIPE_FORMAT_R5G6B5_UNORM; else diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_screen.h index 87c4406f54..9b990b48e7 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.h +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.h @@ -34,6 +34,7 @@ struct pipe_screen; struct egl_drm_device; +struct intel_context; struct intel_screen { @@ -42,6 +43,8 @@ struct intel_screen int deviceID; struct egl_drm_device *device; + + struct intel_context *dummy; }; #endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c index 24e55f1568..bfff6f935f 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c @@ -68,18 +68,23 @@ intel_display_surface(struct egl_drm_drawable *draw, //const int srcWidth = surf->width; //const int srcHeight = surf->height; - const int srcPitch = surf->pitch; + + intel = intel_fb->screen->dummy; + if (!intel) { + printf("No dummy context\n"); + return; + } const int dstWidth = intel_fb->front->width; const int dstHeight = intel_fb->front->height; const int dstPitch = intel_fb->front->pitch / 4;//draw->front.cpp; const int cpp = 4;//intel_fb->front->cpp; + const int srcPitch = surf->stride / cpp; int BR13, CMD; //int i; - BR13 = (dstPitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); -- cgit v1.2.3 From f6e8963bb152166c28dae896a0c8c83ce554f987 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 4 Jul 2008 19:20:08 +0200 Subject: i915: Clean up intel_egl.c a bit --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 6865bfa3d4..cc4fb247d5 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -33,8 +33,8 @@ egl_drm_create_device(int drmFD) device->drmFD = drmFD; if (!intel_init_driver(device)) { - printf("EGL: failed to initalize device\n"); free(device); + return NULL; } return device; @@ -105,22 +105,9 @@ drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) } } -static void -print_modes(drmModeConnectorPtr connector) -{ - struct drm_mode_modeinfo *m; - int i; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - printf("dfm %p %i %i %i\n", m, m->hdisplay, m->vdisplay, m->vrefresh); - } -} - static EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) { - printf("%s enter\n", __FUNCTION__); _EGLDisplay *disp = _eglLookupDisplay(dpy); struct drm_driver *drm_drv = (struct drm_driver *)drv; struct drm_screen *screen = NULL; @@ -490,10 +477,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, DRM_BO_FLAG_NO_EVICT, DRM_BO_HINT_DONT_FENCE, &scrn->buffer); - if (ret) { - printf("failed to create framebuffer (ret %d)\n", ret); + if (ret) return EGL_FALSE; - } prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); @@ -510,10 +495,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, goto err_bo; scrn->mode = drm_find_mode(scrn->connector, mode); - if (!scrn->mode) { - printf("oh noes, no matching mode found\n"); + if (!scrn->mode) goto err_fb; - } ret = drmModeSetCrtc( drm_drv->device->drmFD, @@ -602,7 +585,6 @@ _EGLDriver * _eglMain(_EGLDisplay *dpy, const char *args) { struct drm_driver *drm; - printf("%s enter\n", __FUNCTION__); drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); if (!drm) { -- cgit v1.2.3 From 74db8e9b3f354b5afa30f7cd52a511504693a3c8 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sat, 5 Jul 2008 14:04:02 +0200 Subject: i915: Fix haveDepth and haveStencil for visual in EGL --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index cc4fb247d5..a008d952bf 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -224,7 +224,9 @@ visual_from_config(_EGLConfig *conf) visual->doubleBufferMode = 1; visual->depthBits = 24; + visual->haveDepthBuffer = visual->depthBits > 0; visual->stencilBits = 8; + visual->haveStencilBuffer = visual->stencilBits > 0; return visual; } -- cgit v1.2.3 From c6d6a57424b77ff7de611333046c054d1948ae7a Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sat, 5 Jul 2008 15:58:42 +0200 Subject: i915: Added a intel be function to wrap a drm bo handle --- .../winsys/common/intel_drm/intel_be_device.c | 33 ++++++++++++++++++++++ .../winsys/common/intel_drm/intel_be_device.h | 13 +++++++-- src/gallium/winsys/dri/intel/intel_screen.c | 22 ++++++--------- 3 files changed, 52 insertions(+), 16 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c index efb57a394e..8db0329615 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.c +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.c @@ -125,6 +125,37 @@ intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned byte return &buffer->base; } +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle) +{ + struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); + struct pipe_buffer *buffer; + + if (!be_buf) + goto err; + + memset(be_buf, 0, sizeof(*be_buf)); + + driGenBuffers(device->staticPool, name, 1, &be_buf->driBO, 0, 0, 0); + driBOSetReferenced(be_buf->driBO, handle); + + if (0) /** XXX TODO check error */ + goto err_bo; + + buffer = &be_buf->base; + buffer->refcount = 1; + buffer->alignment = 0; + buffer->usage = 0; + buffer->size = driBOSize(be_buf->driBO); + + return buffer; +err_bo: + free(be_buf); +err: + return NULL; +} + /* * Surface functions. @@ -157,6 +188,7 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) assert((size_t)"intel_i915_surface_release is deprecated" & 0); } + /* * Fence functions */ @@ -189,6 +221,7 @@ intel_be_fence_finish( struct pipe_winsys *sws, return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); } + /* * Misc functions */ diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.h b/src/gallium/winsys/common/intel_drm/intel_be_device.h index abf0253917..3f8b3f585c 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.h +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.h @@ -48,14 +48,23 @@ struct intel_be_buffer { struct _DriBufferObject *driBO; }; +/** + * Create a be buffer from a drm bo handle + * + * Takes a reference + */ +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle); + static INLINE struct intel_be_buffer * -intel_be_buffer( struct pipe_buffer *buf ) +intel_be_buffer(struct pipe_buffer *buf) { return (struct intel_be_buffer *)buf; } static INLINE struct _DriBufferObject * -dri_bo( struct pipe_buffer *buf ) +dri_bo(struct pipe_buffer *buf) { return intel_be_buffer(buf)->driBO; } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index cfecebdb8c..f2412217f3 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -49,28 +49,22 @@ intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, static void intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle) { - struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); struct pipe_screen *screen = intelScreen->base.screen; struct pipe_texture *texture; struct pipe_texture templat; struct pipe_surface *surface; - struct pipe_buffer *buffer = &be_buf->base; + struct pipe_buffer *buffer; unsigned pitch; assert(intelScreen->front.cpp == 4); - /* XXX create a intel_be function for this */ - { - driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); - driBOSetReferenced(intelScreen->front.buffer, handle); - - memset(be_buf, 0, sizeof(*be_buf)); - buffer->refcount = 1; - buffer->alignment = 0; - buffer->usage = 0; - buffer->size = driBOSize(intelScreen->front.buffer); - be_buf->driBO = intelScreen->front.buffer; - } + buffer = intel_be_buffer_from_handle(&intelScreen->base, + "front", handle); + + if (!buffer) + return; + + intelScreen->front.buffer = dri_bo(buffer); memset(&templat, 0, sizeof(templat)); templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; -- cgit v1.2.3 From b30fb6d54019c84174379a773121438ba943557a Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sat, 5 Jul 2008 16:46:04 +0200 Subject: i915: Fix EGL version and name --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index a008d952bf..e078b9eda1 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -171,7 +171,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) drv->Initialized = EGL_TRUE; *major = 1; - *minor = 0; + *minor = 4; return EGL_TRUE; } @@ -610,6 +610,7 @@ _eglMain(_EGLDisplay *dpy, const char *args) drm->base.API.SwapBuffers = drm_swap_buffers; drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; + drm->base.Name = "DRM/Gallium"; /* enable supported extensions */ drm->base.Extensions.MESA_screen_surface = EGL_TRUE; -- cgit v1.2.3 From 1315f720ba80596b866103a7e153bfc2f2bd267b Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Jul 2008 13:24:09 +0200 Subject: i915: Destruction of surface, context and device in EGL --- src/gallium/winsys/egl_drm/intel/intel_context.c | 14 +++++++++++ src/gallium/winsys/egl_drm/intel/intel_egl.c | 21 ++++++++++++---- src/gallium/winsys/egl_drm/intel/intel_egl.h | 8 +++++- src/gallium/winsys/egl_drm/intel/intel_screen.c | 31 +++++++++++++++++++++--- 4 files changed, 65 insertions(+), 9 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c index 7205fa4483..7513f3feef 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -178,6 +178,20 @@ intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes return TRUE; } +int +intel_destroy_context(struct egl_drm_context *egl_context) +{ + struct intel_context *intel = egl_context->priv; + + if (intel->intel_screen->dummy == intel) + intel->intel_screen->dummy = NULL; + + st_destroy_context(intel->st); + intel_be_destroy_context(&intel->base); + free(intel); + return TRUE; +} + void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read) { diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index e078b9eda1..9e12a024eb 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -32,7 +32,7 @@ egl_drm_create_device(int drmFD) memset(device, 0, sizeof(*device)); device->drmFD = drmFD; - if (!intel_init_driver(device)) { + if (!intel_create_device(device)) { free(device); return NULL; } @@ -180,8 +180,15 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) static EGLBoolean drm_terminate(_EGLDriver *drv, EGLDisplay dpy) { - /* TODO: clean up */ - free(drv); + struct drm_driver *drm_drv = (struct drm_driver *)drv; + + intel_destroy_device(drm_drv->device); + + drmClose(drm_drv->device->drmFD); + + free(drm_drv->device); + free(drm_drv); + return EGL_TRUE; } @@ -303,6 +310,8 @@ drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) if (fc->base.IsBound) { fc->base.DeletePending = EGL_TRUE; } else { + intel_destroy_context(fc->context); + free(fc->context); free(fc); } return EGL_TRUE; @@ -322,6 +331,7 @@ drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, Nat return EGL_NO_SURFACE; } + static EGLSurface drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) @@ -534,14 +544,15 @@ drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) if (fs->base.IsBound) { fs->base.DeletePending = EGL_TRUE; } else { + intel_bind_frontbuffer(fs->drawable, NULL); + intel_destroy_drawable(fs->drawable); + free(fs->drawable); free(fs); } return EGL_TRUE; } - - static EGLBoolean drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) { diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h index 18e84e8eea..84b6c212bf 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.h +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.h @@ -32,9 +32,15 @@ struct egl_drm_frontbuffer #include "GL/internal/glcore.h" -int intel_init_driver(struct egl_drm_device *device); +int intel_create_device(struct egl_drm_device *device); +int intel_destroy_device(struct egl_drm_device *device); + int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate); +int intel_destroy_context(struct egl_drm_context *context); + int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual); +int intel_destroy_drawable(struct egl_drm_drawable *drawable); + void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read); void intel_swap_buffers(struct egl_drm_drawable *draw); void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front); diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c index 2818b9676c..12f605e0be 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.c +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.c @@ -41,7 +41,7 @@ extern const struct dri_extension card_extensions[]; int -intel_init_driver(struct egl_drm_device *device) +intel_create_device(struct egl_drm_device *device) { struct intel_screen *intel_screen; @@ -66,6 +66,19 @@ intel_init_driver(struct egl_drm_device *device) return TRUE; } +int +intel_destroy_device(struct egl_drm_device *device) +{ + struct intel_screen *intel_screen = (struct intel_screen *)device->priv; + + intel_be_destroy_device(&intel_screen->base); + + free(intel_screen); + device->priv = NULL; + + return TRUE; +} + int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual) @@ -108,6 +121,18 @@ intel_create_drawable(struct egl_drm_drawable *drawable, return GL_FALSE; } - drawable->priv = (void *) intelfb; - return GL_TRUE; + drawable->priv = (void *) intelfb; + return GL_TRUE; +} + +int +intel_destroy_drawable(struct egl_drm_drawable *drawable) +{ + struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; + drawable->priv = NULL; + + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); + return TRUE; } -- cgit v1.2.3 From 687c8d8941bb62fdb4fbdbb0ff5f359851c290b5 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Jul 2008 14:29:11 +0200 Subject: i915: Fetch the real deviceID for EGL --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 30 +++++++++++++++++++++++-- src/gallium/winsys/egl_drm/intel/intel_egl.h | 5 +++++ src/gallium/winsys/egl_drm/intel/intel_screen.c | 3 +-- 3 files changed, 34 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 9e12a024eb..ed96703e37 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -13,6 +13,7 @@ #include "eglmode.h" #include "eglscreen.h" #include "eglsurface.h" +#include "egllog.h" #include "intel_egl.h" @@ -23,15 +24,38 @@ #include "state_tracker/st_public.h" -struct egl_drm_device* egl_drm_create_device(int drmFD); +static void +drm_get_device_id(struct egl_drm_device *device) +{ + char path[512]; + FILE *file; + + /* TODO get the real minor */ + int minor = 0; + + snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor); + file = fopen(path, "r"); + if (!file) { + _eglLog(_EGL_WARNING, "Could not retrive device ID\n"); + return; + } -struct egl_drm_device* + fgets(path, sizeof( path ), file); + sscanf(path, "%x", &device->deviceID); + fclose(file); +} + +static struct egl_drm_device* egl_drm_create_device(int drmFD) { struct egl_drm_device *device = malloc(sizeof(*device)); memset(device, 0, sizeof(*device)); device->drmFD = drmFD; + device->version = drmGetVersion(device->drmFD); + + drm_get_device_id(device); + if (!intel_create_device(device)) { free(device); return NULL; @@ -105,6 +129,7 @@ drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) } } + static EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) { @@ -183,6 +208,7 @@ drm_terminate(_EGLDriver *drv, EGLDisplay dpy) struct drm_driver *drm_drv = (struct drm_driver *)drv; intel_destroy_device(drm_drv->device); + drmFreeVersion(drm_drv->device->version); drmClose(drm_drv->device->drmFD); diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h index 84b6c212bf..1ee27e0847 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.h +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.h @@ -2,10 +2,15 @@ #ifndef _INTEL_EGL_H_ #define _INTEL_EGL_H_ +#include + struct egl_drm_device { void *priv; int drmFD; + + drmVersionPtr version; + int deviceID; }; struct egl_drm_context diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c index 12f605e0be..8e6d184440 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.c +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.c @@ -53,8 +53,7 @@ intel_create_device(struct egl_drm_device *device) device->priv = (void *)intel_screen; intel_screen->device = device; - /** TODO JB: ugly hack */ - intel_screen->deviceID = PCI_CHIP_I945_GM; + intel_screen->deviceID = device->deviceID; intel_be_init_device(&intel_screen->base, device->drmFD, PCI_CHIP_I945_GM); -- cgit v1.2.3 From 88b806a0697efa9f7fde6aa59530675908f7294d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Jul 2008 15:26:47 +0200 Subject: i915: More cleanup of display --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index ed96703e37..4d7e0f4bd5 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -213,6 +213,8 @@ drm_terminate(_EGLDriver *drv, EGLDisplay dpy) drmClose(drm_drv->device->drmFD); free(drm_drv->device); + + _eglCleanupDisplay(drv); free(drm_drv); return EGL_TRUE; -- cgit v1.2.3 From 7420bc05a862db09b8d5f34a7760fa19b578b4d0 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Jul 2008 15:49:09 +0200 Subject: i915: Fix EGL make current --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 4d7e0f4bd5..98928979e7 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -593,12 +593,15 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re if (!b) return EGL_FALSE; - /* XXX this is where we'd do the hardware context switch */ - (void) drawSurf; - (void) readSurf; - (void) ctx; + if (ctx) { + if (!drawSurf || !readSurf) + return EGL_FALSE; + + intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); + } else { + intel_make_current(NULL, NULL, NULL); + } - intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); return EGL_TRUE; } -- cgit v1.2.3 From 3596339d31d05b7d5120290a7b866485c395b5f2 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Jul 2008 15:49:59 +0200 Subject: i915: Fix wrong pointer to cleanup --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 98928979e7..a476490b90 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -214,7 +214,7 @@ drm_terminate(_EGLDriver *drv, EGLDisplay dpy) free(drm_drv->device); - _eglCleanupDisplay(drv); + _eglCleanupDisplay(_eglLookupDisplay(dpy)); free(drm_drv); return EGL_TRUE; -- cgit v1.2.3 From fec4e427f8df3a6f257b2247dc760430b3dfc258 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 8 Jul 2008 01:32:32 +0200 Subject: nv04: Hook the lib into the build. --- src/gallium/winsys/dri/nouveau/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/Makefile b/src/gallium/winsys/dri/nouveau/Makefile index f637b2cebf..be630ff6d1 100644 --- a/src/gallium/winsys/dri/nouveau/Makefile +++ b/src/gallium/winsys/dri/nouveau/Makefile @@ -8,6 +8,7 @@ MINIGLX_SOURCES = PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/nv04/libnv04.a \ $(TOP)/src/gallium/drivers/nv10/libnv10.a \ $(TOP)/src/gallium/drivers/nv30/libnv30.a \ $(TOP)/src/gallium/drivers/nv40/libnv40.a \ -- cgit v1.2.3 From 06d87b44cffef9e335b9a0e70fd2aec61fcd171b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 Jul 2008 12:51:29 +1000 Subject: nv50: make use of nouveau drm 0.0.11 to get 3d going --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 16 +++ src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 1 + src/gallium/winsys/dri/nouveau/nouveau_screen.c | 2 +- .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 12 ++ src/gallium/winsys/dri/nouveau/nv50_surface.c | 158 +++++++++++---------- 5 files changed, 112 insertions(+), 77 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 57f5b7d1ae..b5942994d9 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -182,6 +182,13 @@ nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, nvbo->drm.alignment = align; nvbo->refcount = 1; + if (flags & NOUVEAU_BO_TILED) { + nvbo->tiled = 1; + if (flags & NOUVEAU_BO_ZTILE) + nvbo->tiled |= 2; + flags &= ~NOUVEAU_BO_TILED; + } + ret = nouveau_bo_set_status(&nvbo->base, flags); if (ret) { free(nvbo); @@ -332,6 +339,12 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) else if (flags & NOUVEAU_BO_GART) new_flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI); + + if (nvbo->tiled && flags) { + new_flags |= NOUVEAU_MEM_TILE; + if (nvbo->tiled & 2) + new_flags |= NOUVEAU_MEM_TILE_ZETA; + } if (new_flags) { ret = nouveau_mem_alloc(bo->device, bo->size, @@ -347,9 +360,12 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) /* Copy old -> new */ /*XXX: use M2MF */ if (nvbo->sysmem || nvbo->map) { + struct nouveau_pushbuf_bo *pbo = nvbo->pending; + nvbo->pending = NULL; nouveau_bo_map(bo, NOUVEAU_BO_RD); memcpy(new_map, bo->map, bo->size); nouveau_bo_unmap(bo); + nvbo->pending = pbo; } /* Free old memory */ diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h index 5829f649cd..dcd6a5eb0a 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -259,6 +259,7 @@ struct nouveau_bo_priv { uint64_t offset; uint64_t flags; + int tiled; }; #define nouveau_bo(n) ((struct nouveau_bo_priv *)(n)) diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c index b15ee7509c..df1fe7e69b 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -13,7 +13,7 @@ #include "nouveau_screen.h" #include "nouveau_swapbuffers.h" -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 #error nouveau_drm.h version does not match expected version #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index ba5dd2eea4..765ea36f88 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -76,6 +76,18 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) flags |= NOUVEAU_BO_GART; flags |= NOUVEAU_BO_VRAM; + + switch (dev->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) { diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c index cf76d76cf5..c8ab7f690f 100644 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -22,52 +22,70 @@ nv50_format(enum pipe_format format) } static int -nv50_surface_copy_prep(struct nouveau_context *nv, - struct pipe_surface *dst, struct pipe_surface *src) +nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) { struct nouveau_channel *chan = nv->nvc->channel; struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - int surf_format; - - assert(src->format == dst->format); + struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->bo; + int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; + int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); + + surf_format = nv50_format(surf->format); + if (surf_format < 0) + return 1; + + if (!nouveau_bo(bo)->tiled) { + BEGIN_RING(chan, eng2d, mthd, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, mthd + 0x14, 5); + OUT_RING (chan, surf->stride); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + OUT_RELOCh(chan, bo, surf->offset, flags); + OUT_RELOCl(chan, bo, surf->offset, flags); + } else { + BEGIN_RING(chan, eng2d, mthd, 5); + OUT_RING (chan, surf_format); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, mthd + 0x18, 4); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + OUT_RELOCh(chan, bo, surf->offset, flags); + OUT_RELOCl(chan, bo, surf->offset, flags); + } + +#if 0 + if (dst) { + BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + } +#endif + + return 0; +} - surf_format = nv50_format(dst->format); - assert(surf_format >= 0); +static int +nv50_surface_copy_prep(struct nouveau_context *nv, + struct pipe_surface *dst, struct pipe_surface *src) +{ + int ret; - BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + assert(src->format == dst->format); - BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); - OUT_RING (chan, surf_format); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); - OUT_RING (chan, dst->stride); - OUT_RING (chan, dst->width); - OUT_RING (chan, dst->height); - OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, dst->width); - OUT_RING (chan, dst->height); + ret = nv50_surface_set(nv, dst, 1); + if (ret) + return ret; - BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 2); - OUT_RING (chan, surf_format); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, NV50_2D_SRC_PITCH, 5); - OUT_RING (chan, src->stride); - OUT_RING (chan, src->width); - OUT_RING (chan, src->height); - OUT_RELOCh(chan, nouveau_buffer(src->buffer)->bo, src->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + ret = nv50_surface_set(nv, src, 0); + if (ret) + return ret; return 0; } @@ -79,17 +97,19 @@ nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, struct nouveau_channel *chan = nv->nvc->channel; struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - BEGIN_RING(chan, eng2d, 0x0110, 1); + BEGIN_RING(chan, eng2d, 0x088c, 1); OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12); + BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4); OUT_RING (chan, dx); OUT_RING (chan, dy); OUT_RING (chan, w); OUT_RING (chan, h); + BEGIN_RING(chan, eng2d, 0x08c0, 4); OUT_RING (chan, 0); OUT_RING (chan, 1); OUT_RING (chan, 0); OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, 0x08d0, 4); OUT_RING (chan, 0); OUT_RING (chan, sx); OUT_RING (chan, 0); @@ -109,35 +129,15 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, { struct nouveau_channel *chan = nv->nvc->channel; struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - int surf_format, rect_format; - - surf_format = nv50_format(dst->format); - if (surf_format < 0) - return 1; + int rect_format, ret; rect_format = nv50_format(dst->format); if (rect_format < 0) return 1; - BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY1, 1); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); - OUT_RING (chan, surf_format); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); - OUT_RING (chan, dst->stride); - OUT_RING (chan, dst->width); - OUT_RING (chan, dst->height); - OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, dst->width); - OUT_RING (chan, dst->height); + ret = nv50_surface_set(nv, dst, 1); + if (ret) + return ret; BEGIN_RING(chan, eng2d, 0x0580, 3); OUT_RING (chan, 4); @@ -151,27 +151,33 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, OUT_RING (chan, dy + h); FIRE_RING(chan); - return 0; } int nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) { + struct nouveau_channel *chan = nvc->channel; + struct nouveau_grobj *eng2d = NULL; int ret; - ret = nouveau_grobj_alloc(nvc->channel, nvc->next_handle++, NV50_2D, - &nvc->Nv2D); + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d); if (ret) return ret; - BIND_RING (nvc->channel, nvc->Nv2D, nvc->next_subchannel++); - BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_NOTIFY, 1); - OUT_RING (nvc->channel, nvc->sync_notifier->handle); - BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); - OUT_RING (nvc->channel, nvc->channel->vram->handle); - OUT_RING (nvc->channel, nvc->channel->vram->handle); - BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_OPERATION, 1); - OUT_RING (nvc->channel, NV50_2D_OPERATION_SRCCOPY); + nvc->Nv2D = eng2d; + + BIND_RING (chan, eng2d, nvc->next_subchannel++); + BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4); + OUT_RING (chan, nvc->sync_notifier->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1); + OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); + BEGIN_RING(chan, eng2d, 0x0290, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, 0x0888, 1); + OUT_RING (chan, 1); return 0; } -- cgit v1.2.3 From b13b1210c0174e4fd315bad3e6e18b6cbeeb1518 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Jul 2008 14:16:15 +0200 Subject: i915: Renamed intel_screen to intel_device The renameing makes more sense, why because: In egl you have a display/driver/device as the basis, and you have screens as outputs. --- src/gallium/winsys/egl_drm/intel/Makefile | 2 +- src/gallium/winsys/egl_drm/intel/intel_context.c | 12 +- src/gallium/winsys/egl_drm/intel/intel_context.h | 4 +- src/gallium/winsys/egl_drm/intel/intel_device.c | 137 +++++++++++++++++++++ src/gallium/winsys/egl_drm/intel/intel_device.h | 50 ++++++++ src/gallium/winsys/egl_drm/intel/intel_screen.c | 137 --------------------- src/gallium/winsys/egl_drm/intel/intel_screen.h | 50 -------- .../winsys/egl_drm/intel/intel_swapbuffers.c | 2 +- 8 files changed, 197 insertions(+), 197 deletions(-) create mode 100644 src/gallium/winsys/egl_drm/intel/intel_device.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_device.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_screen.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_screen.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile index 9c7ff065ff..e67b49f3ad 100644 --- a/src/gallium/winsys/egl_drm/intel/Makefile +++ b/src/gallium/winsys/egl_drm/intel/Makefile @@ -12,7 +12,7 @@ PIPE_DRIVERS = \ DRIVER_SOURCES = \ intel_swapbuffers.c \ intel_context.c \ - intel_screen.c \ + intel_device.c \ intel_egl.c C_SOURCES = \ diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c index 7513f3feef..c2003f5e0e 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -27,7 +27,7 @@ #include "i915simple/i915_screen.h" -#include "intel_screen.h" +#include "intel_device.h" #include "intel_context.h" #include "intel_batchbuffer.h" @@ -147,13 +147,13 @@ int intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) { struct intel_context *intel = CALLOC_STRUCT(intel_context); - struct intel_screen *screen = (struct intel_screen *)egl_context->device->priv; + struct intel_device *screen = (struct intel_device *)egl_context->device->priv; struct pipe_context *pipe; struct st_context *st_share = NULL; egl_context->priv = intel; - intel->intel_screen = screen; + intel->intel_device = screen; intel->egl_context = egl_context; intel->egl_device = egl_context->device; @@ -183,8 +183,8 @@ intel_destroy_context(struct egl_drm_context *egl_context) { struct intel_context *intel = egl_context->priv; - if (intel->intel_screen->dummy == intel) - intel->intel_screen->dummy = NULL; + if (intel->intel_device->dummy == intel) + intel->intel_device->dummy = NULL; st_destroy_context(intel->st); intel_be_destroy_context(&intel->base); @@ -220,7 +220,7 @@ intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *dra void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) { - struct intel_screen *intelScreen = (struct intel_screen *)draw->device->priv; + struct intel_device *intelScreen = (struct intel_device *)draw->device->priv; struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; if (draw_fb->front_buffer) diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h index f05a213ff0..48f9e21b5d 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.h +++ b/src/gallium/winsys/egl_drm/intel/intel_context.h @@ -47,7 +47,7 @@ struct intel_context struct st_context *st; - struct intel_screen *intel_screen; + struct intel_device *intel_device; /* new egl stuff */ struct egl_drm_device *egl_device; @@ -64,7 +64,7 @@ struct intel_framebuffer { struct st_framebuffer *stfb; - struct intel_screen *screen; + struct intel_device *screen; struct _DriBufferObject *front_buffer; struct egl_drm_frontbuffer *front; }; diff --git a/src/gallium/winsys/egl_drm/intel/intel_device.c b/src/gallium/winsys/egl_drm/intel/intel_device.c new file mode 100644 index 0000000000..7496c1bb30 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_device.c @@ -0,0 +1,137 @@ +/************************************************************************** + * + * 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 "utils.h" + +#include "state_tracker/st_public.h" +#include "i915simple/i915_screen.h" + +#include "intel_context.h" +#include "intel_device.h" +#include "intel_batchbuffer.h" +#include "intel_egl.h" + + +extern const struct dri_extension card_extensions[]; + + +int +intel_create_device(struct egl_drm_device *device) +{ + struct intel_device *intel_device; + + /* Allocate the private area */ + intel_device = CALLOC_STRUCT(intel_device); + if (!intel_device) + return FALSE; + + device->priv = (void *)intel_device; + intel_device->device = device; + + intel_device->deviceID = device->deviceID; + + intel_be_init_device(&intel_device->base, device->drmFD, PCI_CHIP_I945_GM); + + intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID); + + /* hack */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + + return TRUE; +} + +int +intel_destroy_device(struct egl_drm_device *device) +{ + struct intel_device *intel_device = (struct intel_device *)device->priv; + + intel_be_destroy_device(&intel_device->base); + + free(intel_device); + device->priv = NULL; + + return TRUE; +} + +int +intel_create_drawable(struct egl_drm_drawable *drawable, + const __GLcontextModes * visual) +{ + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + + if (!intelfb) + return GL_FALSE; + + intelfb->screen = drawable->device->priv; + + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + drawable->w, + drawable->h, + (void*) intelfb); + + if (!intelfb->stfb) { + free(intelfb); + return GL_FALSE; + } + + drawable->priv = (void *) intelfb; + return GL_TRUE; +} + +int +intel_destroy_drawable(struct egl_drm_drawable *drawable) +{ + struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; + drawable->priv = NULL; + + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); + return TRUE; +} diff --git a/src/gallium/winsys/egl_drm/intel/intel_device.h b/src/gallium/winsys/egl_drm/intel/intel_device.h new file mode 100644 index 0000000000..2f9d4f887e --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_device.h @@ -0,0 +1,50 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef _INTEL_SCREEN_H_ +#define _INTEL_SCREEN_H_ + +#include "intel_drm/intel_be_device.h" + +#include "pipe/p_compiler.h" + +struct pipe_screen; +struct egl_drm_device; +struct intel_context; + +struct intel_device +{ + struct intel_be_device base; + struct pipe_screen *pipe; + + int deviceID; + struct egl_drm_device *device; + + struct intel_context *dummy; +}; + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c deleted file mode 100644 index 8e6d184440..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.c +++ /dev/null @@ -1,137 +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 "utils.h" - -#include "state_tracker/st_public.h" -#include "i915simple/i915_screen.h" - -#include "intel_context.h" -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_egl.h" - - -extern const struct dri_extension card_extensions[]; - - -int -intel_create_device(struct egl_drm_device *device) -{ - struct intel_screen *intel_screen; - - /* Allocate the private area */ - intel_screen = CALLOC_STRUCT(intel_screen); - if (!intel_screen) - return FALSE; - - device->priv = (void *)intel_screen; - intel_screen->device = device; - - intel_screen->deviceID = device->deviceID; - - intel_be_init_device(&intel_screen->base, device->drmFD, PCI_CHIP_I945_GM); - - intel_screen->pipe = i915_create_screen(&intel_screen->base.base, intel_screen->deviceID); - - /* hack */ - driInitExtensions(NULL, card_extensions, GL_FALSE); - - return TRUE; -} - -int -intel_destroy_device(struct egl_drm_device *device) -{ - struct intel_screen *intel_screen = (struct intel_screen *)device->priv; - - intel_be_destroy_device(&intel_screen->base); - - free(intel_screen); - device->priv = NULL; - - return TRUE; -} - -int -intel_create_drawable(struct egl_drm_drawable *drawable, - const __GLcontextModes * visual) -{ - enum pipe_format colorFormat, depthFormat, stencilFormat; - struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); - - if (!intelfb) - return GL_FALSE; - - intelfb->screen = drawable->device->priv; - - if (visual->redBits == 5) - colorFormat = PIPE_FORMAT_R5G6B5_UNORM; - else - colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; - - if (visual->depthBits == 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (visual->depthBits == 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_NONE; - - if (visual->stencilBits == 8) - stencilFormat = PIPE_FORMAT_S8Z24_UNORM; - else - stencilFormat = PIPE_FORMAT_NONE; - - intelfb->stfb = st_create_framebuffer(visual, - colorFormat, - depthFormat, - stencilFormat, - drawable->w, - drawable->h, - (void*) intelfb); - - if (!intelfb->stfb) { - free(intelfb); - return GL_FALSE; - } - - drawable->priv = (void *) intelfb; - return GL_TRUE; -} - -int -intel_destroy_drawable(struct egl_drm_drawable *drawable) -{ - struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; - drawable->priv = NULL; - - assert(intelfb->stfb); - st_unreference_framebuffer(&intelfb->stfb); - free(intelfb); - return TRUE; -} diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_screen.h deleted file mode 100644 index 9b990b48e7..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.h +++ /dev/null @@ -1,50 +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. - * - **************************************************************************/ - -#ifndef _INTEL_SCREEN_H_ -#define _INTEL_SCREEN_H_ - -#include "intel_drm/intel_be_device.h" - -#include "pipe/p_compiler.h" - -struct pipe_screen; -struct egl_drm_device; -struct intel_context; - -struct intel_screen -{ - struct intel_be_device base; - struct pipe_screen *pipe; - - int deviceID; - struct egl_drm_device *device; - - struct intel_context *dummy; -}; - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c index bfff6f935f..86e4a0f92a 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "intel_screen.h" +#include "intel_device.h" #include "intel_context.h" #include "intel_batchbuffer.h" #include "intel_reg.h" -- cgit v1.2.3 From 0c6efeb02beba32a35dda7c5d5a3086ca2d8cbc4 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Jul 2008 14:41:17 +0200 Subject: i915: Complete the screen -> device renaming --- src/gallium/winsys/egl_drm/intel/intel_context.c | 14 +++++++------- src/gallium/winsys/egl_drm/intel/intel_context.h | 2 +- src/gallium/winsys/egl_drm/intel/intel_device.c | 2 +- src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c index c2003f5e0e..927addb834 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -147,13 +147,13 @@ int intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) { struct intel_context *intel = CALLOC_STRUCT(intel_context); - struct intel_device *screen = (struct intel_device *)egl_context->device->priv; + struct intel_device *device = (struct intel_device *)egl_context->device->priv; struct pipe_context *pipe; struct st_context *st_share = NULL; egl_context->priv = intel; - intel->intel_device = screen; + intel->intel_device = device; intel->egl_context = egl_context; intel->egl_device = egl_context->device; @@ -161,19 +161,19 @@ intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes intel->base.hardware_unlock = intel_unlock_hardware; intel->base.hardware_locked = intel_locked_hardware; - intel_be_init_context(&intel->base, &screen->base); + intel_be_init_context(&intel->base, &device->base); #if 0 pipe = intel_create_softpipe(intel, screen->winsys); #else - pipe = i915_create_context(screen->pipe, &screen->base.base, &intel->base.base); + pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base); #endif pipe->priv = intel; intel->st = st_create_context(pipe, visual, st_share); - screen->dummy = intel; + device->dummy = intel; return TRUE; } @@ -220,7 +220,7 @@ intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *dra void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) { - struct intel_device *intelScreen = (struct intel_device *)draw->device->priv; + struct intel_device *device = (struct intel_device *)draw->device->priv; struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; if (draw_fb->front_buffer) @@ -235,7 +235,7 @@ intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer draw_fb->front = front; - driGenBuffers(intelScreen->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); + driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); driBOSetReferenced(draw_fb->front_buffer, front->handle); st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h index 48f9e21b5d..dfa4720b08 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.h +++ b/src/gallium/winsys/egl_drm/intel/intel_context.h @@ -64,7 +64,7 @@ struct intel_framebuffer { struct st_framebuffer *stfb; - struct intel_device *screen; + struct intel_device *device; struct _DriBufferObject *front_buffer; struct egl_drm_frontbuffer *front; }; diff --git a/src/gallium/winsys/egl_drm/intel/intel_device.c b/src/gallium/winsys/egl_drm/intel/intel_device.c index 7496c1bb30..a601904ba4 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_device.c +++ b/src/gallium/winsys/egl_drm/intel/intel_device.c @@ -88,7 +88,7 @@ intel_create_drawable(struct egl_drm_drawable *drawable, if (!intelfb) return GL_FALSE; - intelfb->screen = drawable->device->priv; + intelfb->device = drawable->device->priv; if (visual->redBits == 5) colorFormat = PIPE_FORMAT_R5G6B5_UNORM; diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c index 86e4a0f92a..2edcbc79ff 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c @@ -69,7 +69,7 @@ intel_display_surface(struct egl_drm_drawable *draw, //const int srcWidth = surf->width; //const int srcHeight = surf->height; - intel = intel_fb->screen->dummy; + intel = intel_fb->device->dummy; if (!intel) { printf("No dummy context\n"); return; -- cgit v1.2.3 From 1257bb9b130c9487a32e422a8ce8ddba2f14a568 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Jul 2008 14:44:23 +0200 Subject: i915: Use deviceID in EGL device create --- src/gallium/winsys/egl_drm/intel/intel_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_device.c b/src/gallium/winsys/egl_drm/intel/intel_device.c index a601904ba4..b9649cbec7 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_device.c +++ b/src/gallium/winsys/egl_drm/intel/intel_device.c @@ -55,7 +55,7 @@ intel_create_device(struct egl_drm_device *device) intel_device->deviceID = device->deviceID; - intel_be_init_device(&intel_device->base, device->drmFD, PCI_CHIP_I945_GM); + intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID); intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID); -- cgit v1.2.3 From 2e7e1837512c1959a97f51903a770cf182fc9820 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Jul 2008 16:54:22 +0200 Subject: i915: Takedown EGL screen --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 81 ++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 10 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index a476490b90..55f4d92afb 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -24,6 +24,8 @@ #include "state_tracker/st_public.h" +#define MAX_SCREENS 16 + static void drm_get_device_id(struct egl_drm_device *device) { @@ -66,11 +68,17 @@ egl_drm_create_device(int drmFD) __GLcontextModes* _gl_context_modes_create( unsigned count, size_t minimum_size ); +struct drm_screen; + struct drm_driver { _EGLDriver base; /* base class/object */ drmModeResPtr res; + + struct drm_screen *screens[MAX_SCREENS]; + size_t count_screens; + struct egl_drm_device *device; }; @@ -92,17 +100,26 @@ struct drm_screen { _EGLScreen base; - /* backing buffer and crtc */ + /* currently only support one connector */ + drmModeConnectorPtr connector; + uint32_t connectorID; + + /* Has this screen been shown */ + int shown; + + /* Surface that is currently attached to this screen */ + struct drm_surface *surf; + + /* backing buffer */ drmBO buffer; + + /* framebuffer */ drmModeFBPtr fb; uint32_t fbID; - drmModeCrtcPtr crtc; - /* currently only support one connector */ - drmModeConnectorPtr connector; - drmModeEncoderPtr encoder; - uint32_t connectorID; - uint32_t encoderID; + /* crtc and mode used */ + drmModeCrtcPtr crtc; + uint32_t crtcID; struct drm_mode_modeinfo *mode; @@ -139,6 +156,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) drmModeConnectorPtr connector = NULL; drmModeResPtr res = NULL; unsigned count_connectors = 0; + int num_screens = 0; EGLint i; int fd; @@ -159,13 +177,13 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) if (res) count_connectors = res->count_connectors; - for(i = 0; i < count_connectors; i++) { + for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { connector = drmModeGetConnector(fd, res->connectors[i]); if (!connector) continue; - if (connector->connection == DRM_MODE_DISCONNECTED) { + if (connector->connection != DRM_MODE_CONNECTED) { drmModeFreeConnector(connector); continue; } @@ -177,7 +195,9 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) _eglInitScreen(&screen->base); _eglAddScreen(disp, &screen->base); drm_add_modes_from_connector(&screen->base, connector); + drm_drv->screens[num_screens++] = screen; } + drm_drv->count_screens = num_screens; /* for now we only have one config */ _EGLConfig *config = calloc(1, sizeof(*config)); @@ -201,15 +221,52 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) return EGL_TRUE; } +static void +drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + + intel_bind_frontbuffer(screen->surf->drawable, NULL); + screen->surf = NULL; + + drmModeSetCrtc( + drm_drv->device->drmFD, + drm_drv->res->crtcs[1], + 0, // FD + 0, 0, + NULL, 0, // List of output ids + NULL); + + drmModeRmFB(drm_drv->device->drmFD, screen->fbID); + drmModeFreeFB(screen->fb); + screen->fb = NULL; + + drmBOUnreference(drm_drv->device->drmFD, &screen->buffer); + + screen->shown = 0; +} static EGLBoolean drm_terminate(_EGLDriver *drv, EGLDisplay dpy) { struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_screen *screen; + int i = 0; intel_destroy_device(drm_drv->device); drmFreeVersion(drm_drv->device->version); + for (i = 0; i < drm_drv->count_screens; i++) { + screen = drm_drv->screens[i]; + + if (screen->shown) + drm_takedown_shown_screen(drv, screen); + + drmModeFreeConnector(screen->connector); + _eglDestroyScreen(&screen->base); + drm_drv->screens[i] = NULL; + } + drmClose(drm_drv->device->drmFD); free(drm_drv->device); @@ -507,7 +564,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, size_t size = mode->Height * pitch; int ret; - /* TODO if allready shown take down */ + if (scrn->shown) + drm_takedown_shown_screen(drv, scrn); ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, DRM_BO_FLAG_READ | @@ -552,8 +610,11 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, scrn->front.width = mode->Width; scrn->front.height = mode->Height; + scrn->surf = surf; intel_bind_frontbuffer(surf->drawable, &scrn->front); + scrn->shown = 1; + return EGL_TRUE; err_fb: -- cgit v1.2.3 From 48b8a32c6dcd259046958b187927ac584b1a564a Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 9 Jul 2008 10:20:28 -0400 Subject: egl: plug a small memleak --- src/gallium/winsys/egl_xlib/egl_xlib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 83b8bb95b1..708a58b781 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -535,6 +535,7 @@ xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) surf->Base.DeletePending = EGL_TRUE; } else { + XFreeGC(surf->Dpy, surf->Gc); st_unreference_framebuffer(&surf->Framebuffer); free(surf); } -- cgit v1.2.3 From f5cdc657b244ec7840cff1f36892f105b4aa2ef2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 10 Jul 2008 13:30:37 -0600 Subject: egl: added EGL_OPENVG_API case (allow all APIs) --- src/gallium/winsys/egl_xlib/egl_xlib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 708a58b781..829732eea8 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -350,6 +350,7 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, /* API-dependent context creation */ switch (ctx->Base.ClientAPI) { + case EGL_OPENVG_API: case EGL_OPENGL_ES_API: _eglLog(_EGL_DEBUG, "Create Context for ES version %d\n", ctx->Base.ClientVersion); -- cgit v1.2.3 From 5180a668a7da627a40e024a2ed765458d5bac43e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 11 Jul 2008 22:24:24 +1000 Subject: nouveau: winsys surface funcs deprecated, remove them --- .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 30 ---------------------- 1 file changed, 30 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index 765ea36f88..8a2870a2ff 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -25,33 +25,6 @@ nouveau_get_name(struct pipe_winsys *pws) return "Nouveau/DRI"; } -static struct pipe_surface * -nouveau_surface_alloc(struct pipe_winsys *ws) -{ - struct pipe_surface *surf; - - surf = CALLOC_STRUCT(pipe_surface); - if (!surf) - return NULL; - - surf->refcount = 1; - surf->winsys = ws; - return surf; -} - -static void -nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - - *s = NULL; - if (--surf->refcount <= 0) { - if (surf->buffer) - pipe_buffer_reference(ws, &surf->buffer, NULL); - free(surf); - } -} - static struct pipe_buffer * nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, unsigned usage, unsigned size) @@ -215,9 +188,6 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv) pws->flush_frontbuffer = nouveau_flush_frontbuffer; - pws->surface_alloc = nouveau_surface_alloc; - pws->surface_release = nouveau_surface_release; - pws->buffer_create = nouveau_pipe_bo_create; pws->buffer_destroy = nouveau_pipe_bo_del; pws->user_buffer_create = nouveau_pipe_bo_user_create; -- cgit v1.2.3 From 6e938e4f82755c20472532907cc47c2d501aaee2 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 11 Jul 2008 20:01:33 +0200 Subject: gallium: Make dri drivers create a egl_name_dri.so if supported --- src/gallium/winsys/dri/Makefile.template | 10 +++++++++- src/gallium/winsys/dri/intel/Makefile | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index 07abfa53f3..80e817b808 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -79,17 +79,25 @@ SHARED_INCLUDES = \ ##### TARGETS ##### -default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) +default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR)/$(LIBNAME_EGL) $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template $(TOP)/bin/mklib -noprefix -o $@ \ $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) +$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS) + $(TOP)/bin/mklib -o $(LIBNAME_EGL) \ + -linker "$(CC)" \ + -noprefix \ + $(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \ + --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive $(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) +$(TOP)/$(LIB_DIR)/$(LIBNAME_EGL): $(LIBNAME_EGL) + $(INSTALL) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR) depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) rm -f depend diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index 5b51f0815d..e0716ea28e 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -3,6 +3,7 @@ TOP = ../../../../.. include $(TOP)/configs/current LIBNAME = i915_dri.so +LIBNAME_EGL = egl_i915_dri.so PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ -- cgit v1.2.3 From 930a863c4f6f11d0fd5cf396ef76054d52c69b9f Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 10 Jul 2008 20:20:46 +0200 Subject: i915: WIP swap rework --- src/gallium/winsys/dri/intel/intel_context.h | 6 + src/gallium/winsys/dri/intel/intel_swapbuffers.c | 303 ++++++++++------------- src/gallium/winsys/dri/intel/intel_swapbuffers.h | 4 +- 3 files changed, 144 insertions(+), 169 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h index ced18da143..18b96217ac 100644 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -32,6 +32,7 @@ #include "drm.h" #include "pipe/p_debug.h" +#include "util/u_blit.h" #include "intel_screen.h" #include "i915_drm.h" @@ -82,6 +83,11 @@ struct intel_context * Configuration cache */ driOptionCache optionCache; + + /** + * Blit state for swapbuffers + */ + struct blit_state *blit; }; diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index f751f97524..6e10235e89 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -28,16 +28,13 @@ #include "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" - +#include "intel_batchbuffer.h" #include "intel_reg.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 "intel_drm/ws_dri_bufmgr.h" -#include "intel_batchbuffer.h" + /** * Display a colorbuffer surface in an X window. @@ -49,158 +46,130 @@ */ void intelDisplaySurface(__DRIdrawablePrivate *dPriv, - struct pipe_surface *surf, - const drm_clip_rect_t *rect) + struct pipe_texture *tex, + const drm_clip_rect_t *rect) { - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - struct intel_context *intel = intelScreen->dummyContext; - - DBG(SWAP, "%s\n", __FUNCTION__); - - if (!intel) { - /* XXX this is where some kind of extra/meta context could be useful */ - return; - } - - if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); - driFenceUnReference(&intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - intel->last_swap_fence = intel->first_swap_fence; - intel->first_swap_fence = NULL; - - /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets - * should work regardless. - */ - LOCK_HARDWARE(intel); - /* if this drawable isn't currently bound the LOCK_HARDWARE done on the - * current context (which is what intelScreenContext should return) might - * not get a contended lock and thus cliprects not updated (tests/manywin) - */ - if (intel_context(dPriv->driContextPriv) != intel) - DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); - - - if (dPriv && dPriv->numClipRects) { - const int srcWidth = surf->width; - const int srcHeight = surf->height; - const int nbox = dPriv->numClipRects; - const drm_clip_rect_t *pbox = dPriv->pClipRects; - const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; - const int cpp = intelScreen->front.cpp; - const int srcpitch = surf->stride / cpp; - int BR13, CMD; - int i; - - ASSERT(surf->buffer); - ASSERT(surf->cpp == cpp); - - DBG(SWAP, "screen pitch %d src surface pitch %d\n", - pitch, surf->stride); - - if (cpp == 2) { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); - CMD = XY_SRC_COPY_BLT_CMD; - } - else { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - } - - for (i = 0; i < nbox; i++, pbox++) { - drm_clip_rect_t box; - drm_clip_rect_t sbox; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > intelScreen->front.width || - pbox->y2 > intelScreen->front.height) { - /* invalid cliprect, skip it */ - continue; - } - - box = *pbox; - - if (rect) { - /* intersect cliprect with user-provided src rect */ - drm_clip_rect_t rrect; - - rrect.x1 = dPriv->x + rect->x1; - rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; - rrect.x2 = rect->x2 + rrect.x1; - rrect.y2 = rect->y2 + rrect.y1; - if (rrect.x1 > box.x1) - box.x1 = rrect.x1; - if (rrect.y1 > box.y1) - box.y1 = rrect.y1; - if (rrect.x2 < box.x2) - box.x2 = rrect.x2; - if (rrect.y2 < box.y2) - box.y2 = rrect.y2; - - if (box.x1 > box.x2 || box.y1 > box.y2) - continue; - } - - /* restrict blit to size of actually rendered area */ - if (box.x2 - box.x1 > srcWidth) - box.x2 = srcWidth + box.x1; - if (box.y2 - box.y1 > srcHeight) - box.y2 = srcHeight + box.y1; - - DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", - box.x1, box.x2, box.y1, box.y2); - - sbox.x1 = box.x1 - dPriv->x; - sbox.y1 = box.y1 - dPriv->y; - - assert(box.x1 < box.x2); - assert(box.y1 < box.y2); - - /* XXX this could be done with pipe->surface_copy() */ - /* XXX should have its own batch buffer */ - if (!BEGIN_BATCH(8, 2)) { - /* - * Since we share this batch buffer with a context - * we can't flush it since that risks a GPU lockup - */ - assert(0); - continue; - } - - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((box.y1 << 16) | box.x1); - OUT_BATCH((box.y2 << 16) | box.x2); - - OUT_RELOC(intelScreen->front.buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); - OUT_BATCH((sbox.y1 << 16) | sbox.x1); - OUT_BATCH((srcpitch * cpp) & 0xffff); - OUT_RELOC(dri_bo(surf->buffer), - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - - } - - if (intel->first_swap_fence) - driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); - } - - UNLOCK_HARDWARE(intel); - - if (intel->lastStamp != dPriv->lastStamp) { - intelUpdateWindowSize(dPriv); - intel->lastStamp = dPriv->lastStamp; - } + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + struct intel_context *intel = intelScreen->dummyContext; + + DBG(SWAP, "%s\n", __FUNCTION__); + + if (!intel) { + /* XXX this is where some kind of extra/meta context could be useful */ + return; + } else if (!intel->blit) { + intel->blit = util_create_blit(intel->st->pipe, intel->st->cso_context); + } + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); + driFenceUnReference(&intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + /* if this drawable isn't currently bound the LOCK_HARDWARE done on the + * current context (which is what intelScreenContext should return) might + * not get a contended lock and thus cliprects not updated (tests/manywin) + */ + if (intel_context(dPriv->driContextPriv) != intel) + DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); + + if (dPriv && dPriv->numClipRects) { + const int srcWidth = tex->width[0]; + const int srcHeight = tex->height[0]; + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + int i; + + assert(surf->buffer); + assert(surf->cpp == cpp); + + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + drm_clip_rect_t sbox; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->front.width || + pbox->y2 > intelScreen->front.height) { + /* invalid cliprect, skip it */ + continue; + } + + box = *pbox; + + if (rect) { + /* intersect cliprect with user-provided src rect */ + drm_clip_rect_t rrect; + + rrect.x1 = dPriv->x + rect->x1; + rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; + rrect.x2 = rect->x2 + rrect.x1; + rrect.y2 = rect->y2 + rrect.y1; + if (rrect.x1 > box.x1) + box.x1 = rrect.x1; + if (rrect.y1 > box.y1) + box.y1 = rrect.y1; + if (rrect.x2 < box.x2) + box.x2 = rrect.x2; + if (rrect.y2 < box.y2) + box.y2 = rrect.y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + /* restrict blit to size of actually rendered area */ + if (box.x2 - box.x1 > srcWidth) + box.x2 = srcWidth + box.x1; + if (box.y2 - box.y1 > srcHeight) + box.y2 = srcHeight + box.y1; + + DBG(SWAP, "\tdbox x1 x2 y1 y2 %d %d %d %d\n", + box.x1, box.x2, box.y1, box.y2); + + sbox.x1 = box.x1 - dPriv->x; + sbox.y1 = box.y1 - dPriv->y; + sbox.x2 = box.x2 - dPriv->x; + sbox.y2 = box.y2 - dPriv->y; + DBG(SWAP, "\tsbox x1 x2 y1 y2 %d %d %d %d\n", + sbox.x1, sbox.x2, sbox.y1, sbox.y2); + + assert(box.x1 < box.x2); + assert(box.y1 < box.y2); + + util_blit_pixels_tex(intel->blit, + tex, + sbox.x1, sbox.y1, + sbox.x2, sbox.y2, + intelScreen->front.surface, + box.x1, box.y1, + box.x2, box.y2, + 0.0, + PIPE_TEX_MIPFILTER_NEAREST); + } + + if (intel->first_swap_fence) + driFenceUnReference(&intel->first_swap_fence); + intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); + } + + + UNLOCK_HARDWARE(intel); + + if (intel->lastStamp != dPriv->lastStamp) { + intelUpdateWindowSize(dPriv); + intel->lastStamp = dPriv->lastStamp; + } } - - /** * This will be called whenever the currently bound window is moved/resized. */ @@ -212,27 +181,27 @@ intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); } - - +/** + * Called from glx code + */ void intelSwapBuffers(__DRIdrawablePrivate * dPriv) { struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_surface *back_surf; + struct pipe_texture *back_tex; assert(intel_fb); assert(intel_fb->stfb); - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_surf) { + back_tex = st_get_framebuffer_texture(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_tex) { st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_surf, NULL); + intelDisplaySurface(dPriv, back_tex, NULL); st_notify_swapbuffers_complete(intel_fb->stfb); } } - /** * Called via glXCopySubBufferMESA() to copy a subrect of the back * buffer to the front buffer/screen. @@ -241,14 +210,14 @@ void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) { struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_surface *back_surf; + struct pipe_texture *back_tex; assert(intel_fb); assert(intel_fb->stfb); - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_surf) { + back_tex = st_get_framebuffer_texture(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_tex) { drm_clip_rect_t rect; rect.x1 = x; rect.y1 = y; @@ -256,6 +225,6 @@ intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) rect.y2 = h; st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_surf, &rect); + intelDisplaySurface(dPriv, back_tex, &rect); } } diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.h b/src/gallium/winsys/dri/intel/intel_swapbuffers.h index 46c9bab3af..88c479f81d 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.h +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.h @@ -29,11 +29,11 @@ #define INTEL_SWAPBUFFERS_H -struct pipe_surface; +struct pipe_texture; extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, - struct pipe_surface *surf, + struct pipe_texture *surf, const drm_clip_rect_t * rect); extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); -- cgit v1.2.3 From 16c2267d55fb14d0ffcb676540345a14ecc0f323 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sun, 13 Jul 2008 18:55:38 +0200 Subject: i915: Ops should not have pushed that This reverts commit 930a863c4f6f11d0fd5cf396ef76054d52c69b9f. --- src/gallium/winsys/dri/intel/intel_context.h | 6 - src/gallium/winsys/dri/intel/intel_swapbuffers.c | 303 +++++++++++++---------- src/gallium/winsys/dri/intel/intel_swapbuffers.h | 4 +- 3 files changed, 169 insertions(+), 144 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h index 18b96217ac..ced18da143 100644 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -32,7 +32,6 @@ #include "drm.h" #include "pipe/p_debug.h" -#include "util/u_blit.h" #include "intel_screen.h" #include "i915_drm.h" @@ -83,11 +82,6 @@ struct intel_context * Configuration cache */ driOptionCache optionCache; - - /** - * Blit state for swapbuffers - */ - struct blit_state *blit; }; diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 6e10235e89..f751f97524 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -28,13 +28,16 @@ #include "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" -#include "intel_batchbuffer.h" + #include "intel_reg.h" +#include "pipe/p_context.h" #include "state_tracker/st_public.h" #include "state_tracker/st_context.h" -#include "intel_drm/ws_dri_bufmgr.h" +#include "state_tracker/st_cb_fbo.h" +#include "intel_drm/ws_dri_bufmgr.h" +#include "intel_batchbuffer.h" /** * Display a colorbuffer surface in an X window. @@ -46,130 +49,158 @@ */ void intelDisplaySurface(__DRIdrawablePrivate *dPriv, - struct pipe_texture *tex, - const drm_clip_rect_t *rect) + struct pipe_surface *surf, + const drm_clip_rect_t *rect) { - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - struct intel_context *intel = intelScreen->dummyContext; - - DBG(SWAP, "%s\n", __FUNCTION__); - - if (!intel) { - /* XXX this is where some kind of extra/meta context could be useful */ - return; - } else if (!intel->blit) { - intel->blit = util_create_blit(intel->st->pipe, intel->st->cso_context); - } - - if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); - driFenceUnReference(&intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - intel->last_swap_fence = intel->first_swap_fence; - intel->first_swap_fence = NULL; - - /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets - * should work regardless. - */ - LOCK_HARDWARE(intel); - /* if this drawable isn't currently bound the LOCK_HARDWARE done on the - * current context (which is what intelScreenContext should return) might - * not get a contended lock and thus cliprects not updated (tests/manywin) - */ - if (intel_context(dPriv->driContextPriv) != intel) - DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); - - if (dPriv && dPriv->numClipRects) { - const int srcWidth = tex->width[0]; - const int srcHeight = tex->height[0]; - const int nbox = dPriv->numClipRects; - const drm_clip_rect_t *pbox = dPriv->pClipRects; - int i; - - assert(surf->buffer); - assert(surf->cpp == cpp); - - - for (i = 0; i < nbox; i++, pbox++) { - drm_clip_rect_t box; - drm_clip_rect_t sbox; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > intelScreen->front.width || - pbox->y2 > intelScreen->front.height) { - /* invalid cliprect, skip it */ - continue; - } - - box = *pbox; - - if (rect) { - /* intersect cliprect with user-provided src rect */ - drm_clip_rect_t rrect; - - rrect.x1 = dPriv->x + rect->x1; - rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; - rrect.x2 = rect->x2 + rrect.x1; - rrect.y2 = rect->y2 + rrect.y1; - if (rrect.x1 > box.x1) - box.x1 = rrect.x1; - if (rrect.y1 > box.y1) - box.y1 = rrect.y1; - if (rrect.x2 < box.x2) - box.x2 = rrect.x2; - if (rrect.y2 < box.y2) - box.y2 = rrect.y2; - - if (box.x1 > box.x2 || box.y1 > box.y2) - continue; - } - - /* restrict blit to size of actually rendered area */ - if (box.x2 - box.x1 > srcWidth) - box.x2 = srcWidth + box.x1; - if (box.y2 - box.y1 > srcHeight) - box.y2 = srcHeight + box.y1; - - DBG(SWAP, "\tdbox x1 x2 y1 y2 %d %d %d %d\n", - box.x1, box.x2, box.y1, box.y2); - - sbox.x1 = box.x1 - dPriv->x; - sbox.y1 = box.y1 - dPriv->y; - sbox.x2 = box.x2 - dPriv->x; - sbox.y2 = box.y2 - dPriv->y; - DBG(SWAP, "\tsbox x1 x2 y1 y2 %d %d %d %d\n", - sbox.x1, sbox.x2, sbox.y1, sbox.y2); - - assert(box.x1 < box.x2); - assert(box.y1 < box.y2); - - util_blit_pixels_tex(intel->blit, - tex, - sbox.x1, sbox.y1, - sbox.x2, sbox.y2, - intelScreen->front.surface, - box.x1, box.y1, - box.x2, box.y2, - 0.0, - PIPE_TEX_MIPFILTER_NEAREST); - } - - if (intel->first_swap_fence) - driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); - } - - - UNLOCK_HARDWARE(intel); - - if (intel->lastStamp != dPriv->lastStamp) { - intelUpdateWindowSize(dPriv); - intel->lastStamp = dPriv->lastStamp; - } + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + struct intel_context *intel = intelScreen->dummyContext; + + DBG(SWAP, "%s\n", __FUNCTION__); + + if (!intel) { + /* XXX this is where some kind of extra/meta context could be useful */ + return; + } + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); + driFenceUnReference(&intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + /* if this drawable isn't currently bound the LOCK_HARDWARE done on the + * current context (which is what intelScreenContext should return) might + * not get a contended lock and thus cliprects not updated (tests/manywin) + */ + if (intel_context(dPriv->driContextPriv) != intel) + DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); + + + if (dPriv && dPriv->numClipRects) { + const int srcWidth = surf->width; + const int srcHeight = surf->height; + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; + const int cpp = intelScreen->front.cpp; + const int srcpitch = surf->stride / cpp; + int BR13, CMD; + int i; + + ASSERT(surf->buffer); + ASSERT(surf->cpp == cpp); + + DBG(SWAP, "screen pitch %d src surface pitch %d\n", + pitch, surf->stride); + + if (cpp == 2) { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + } + else { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + } + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + drm_clip_rect_t sbox; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->front.width || + pbox->y2 > intelScreen->front.height) { + /* invalid cliprect, skip it */ + continue; + } + + box = *pbox; + + if (rect) { + /* intersect cliprect with user-provided src rect */ + drm_clip_rect_t rrect; + + rrect.x1 = dPriv->x + rect->x1; + rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; + rrect.x2 = rect->x2 + rrect.x1; + rrect.y2 = rect->y2 + rrect.y1; + if (rrect.x1 > box.x1) + box.x1 = rrect.x1; + if (rrect.y1 > box.y1) + box.y1 = rrect.y1; + if (rrect.x2 < box.x2) + box.x2 = rrect.x2; + if (rrect.y2 < box.y2) + box.y2 = rrect.y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + /* restrict blit to size of actually rendered area */ + if (box.x2 - box.x1 > srcWidth) + box.x2 = srcWidth + box.x1; + if (box.y2 - box.y1 > srcHeight) + box.y2 = srcHeight + box.y1; + + DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", + box.x1, box.x2, box.y1, box.y2); + + sbox.x1 = box.x1 - dPriv->x; + sbox.y1 = box.y1 - dPriv->y; + + assert(box.x1 < box.x2); + assert(box.y1 < box.y2); + + /* XXX this could be done with pipe->surface_copy() */ + /* XXX should have its own batch buffer */ + if (!BEGIN_BATCH(8, 2)) { + /* + * Since we share this batch buffer with a context + * we can't flush it since that risks a GPU lockup + */ + assert(0); + continue; + } + + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((box.y1 << 16) | box.x1); + OUT_BATCH((box.y2 << 16) | box.x2); + + OUT_RELOC(intelScreen->front.buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + OUT_BATCH((sbox.y1 << 16) | sbox.x1); + OUT_BATCH((srcpitch * cpp) & 0xffff); + OUT_RELOC(dri_bo(surf->buffer), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + } + + if (intel->first_swap_fence) + driFenceUnReference(&intel->first_swap_fence); + intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); + } + + UNLOCK_HARDWARE(intel); + + if (intel->lastStamp != dPriv->lastStamp) { + intelUpdateWindowSize(dPriv); + intel->lastStamp = dPriv->lastStamp; + } } + + /** * This will be called whenever the currently bound window is moved/resized. */ @@ -181,27 +212,27 @@ intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); } -/** - * Called from glx code - */ + + void intelSwapBuffers(__DRIdrawablePrivate * dPriv) { struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_texture *back_tex; + struct pipe_surface *back_surf; assert(intel_fb); assert(intel_fb->stfb); - back_tex = st_get_framebuffer_texture(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_tex) { + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_tex, NULL); + intelDisplaySurface(dPriv, back_surf, NULL); st_notify_swapbuffers_complete(intel_fb->stfb); } } + /** * Called via glXCopySubBufferMESA() to copy a subrect of the back * buffer to the front buffer/screen. @@ -210,14 +241,14 @@ void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) { struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_texture *back_tex; + struct pipe_surface *back_surf; assert(intel_fb); assert(intel_fb->stfb); - back_tex = st_get_framebuffer_texture(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_tex) { + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { drm_clip_rect_t rect; rect.x1 = x; rect.y1 = y; @@ -225,6 +256,6 @@ intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) rect.y2 = h; st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_tex, &rect); + intelDisplaySurface(dPriv, back_surf, &rect); } } diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.h b/src/gallium/winsys/dri/intel/intel_swapbuffers.h index 88c479f81d..46c9bab3af 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.h +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.h @@ -29,11 +29,11 @@ #define INTEL_SWAPBUFFERS_H -struct pipe_texture; +struct pipe_surface; extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, - struct pipe_texture *surf, + struct pipe_surface *surf, const drm_clip_rect_t * rect); extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); -- cgit v1.2.3 From 8878d8d4b35c9550632f5684bdc97f3958bf43c5 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Thu, 10 Jul 2008 00:32:18 -0400 Subject: g3dvl: Minor SP winsys cleanup. --- src/gallium/winsys/g3dvl/xsp_winsys.c | 46 ++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 17 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index d04c4be580..7c5c592fc7 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -62,6 +62,7 @@ static void* xsp_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buffer, assert(buffer); xsp_buf->mapped_data = xsp_buf->data; + return xsp_buf->mapped_data; } @@ -131,8 +132,7 @@ static int xsp_surface_alloc_storage surface->nblocksy = pf_get_nblocksy(&surface->block, height); surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); surface->usage = flags; - /* XXX: Need to consider block dims? See xm_winsys.c */ - surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * height); + surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * surface->nblocksy); return 0; } @@ -158,6 +158,29 @@ static void xsp_surface_release(struct pipe_winsys *pws, struct pipe_surface **s *surface = NULL; } +static void xsp_fence_reference(struct pipe_winsys *pws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence) +{ + assert(pws); + assert(ptr); + assert(fence); +} + +static int xsp_fence_signalled(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag) +{ + assert(pws); + assert(fence); + + return 0; +} + +static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag) +{ + assert(pws); + assert(fence); + + return 0; +} + static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private) { struct xsp_pipe_winsys *xsp_winsys; @@ -196,22 +219,11 @@ static const char* xsp_get_name(struct pipe_winsys *pws) return "X11 SoftPipe"; } -/* softpipe_winsys implementation */ - -static boolean xsp_is_format_supported(struct softpipe_winsys *spws, enum pipe_format format) -{ - assert(spws); - - /* TODO: Test that 'format' is equal to our output window's format */ - return TRUE; -} - /* Show starts here */ struct pipe_context* create_pipe_context(Display *display) { struct xsp_pipe_winsys *xsp_winsys; - struct softpipe_winsys *sp_winsys; struct pipe_screen *p_screen; struct pipe_context *p_context; @@ -226,6 +238,9 @@ struct pipe_context* create_pipe_context(Display *display) xsp_winsys->base.surface_alloc = xsp_surface_alloc; xsp_winsys->base.surface_alloc_storage = xsp_surface_alloc_storage; xsp_winsys->base.surface_release = xsp_surface_release; + xsp_winsys->base.fence_reference = xsp_fence_reference; + xsp_winsys->base.fence_signalled = xsp_fence_signalled; + xsp_winsys->base.fence_finish = xsp_fence_finish; xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer; xsp_winsys->base.get_name = xsp_get_name; xsp_winsys->display = display; @@ -253,12 +268,9 @@ struct pipe_context* create_pipe_context(Display *display) XDestroyImage(template); } - - sp_winsys = calloc(1, sizeof(struct softpipe_winsys)); - sp_winsys->is_format_supported = xsp_is_format_supported; p_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); - p_context = softpipe_create(p_screen, (struct pipe_winsys*)xsp_winsys, sp_winsys); + p_context = softpipe_create(p_screen, (struct pipe_winsys*)xsp_winsys, NULL); return p_context; } -- cgit v1.2.3 From c243573fafe8e83d4964535b201c499164d7c172 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 19 Jul 2008 16:22:56 -0400 Subject: g3dvl: Fix some memory leaks in the winsys. --- src/gallium/winsys/g3dvl/xsp_winsys.c | 26 +++++++++++++++++++++----- src/gallium/winsys/g3dvl/xsp_winsys.h | 1 + 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index 7c5c592fc7..c660c6e018 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -224,8 +224,8 @@ static const char* xsp_get_name(struct pipe_winsys *pws) struct pipe_context* create_pipe_context(Display *display) { struct xsp_pipe_winsys *xsp_winsys; - struct pipe_screen *p_screen; - struct pipe_context *p_context; + struct pipe_screen *screen; + struct pipe_context *pipe; assert(display); @@ -269,9 +269,25 @@ struct pipe_context* create_pipe_context(Display *display) XDestroyImage(template); } - p_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); - p_context = softpipe_create(p_screen, (struct pipe_winsys*)xsp_winsys, NULL); + screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); + pipe = softpipe_create(screen, (struct pipe_winsys*)xsp_winsys, NULL); - return p_context; + return pipe; +} + +int destroy_pipe_context(struct pipe_context *pipe) +{ + struct pipe_screen *screen; + struct pipe_winsys *winsys; + + assert(pipe); + + screen = pipe->screen; + winsys = pipe->winsys; + pipe->destroy(pipe); + screen->destroy(screen); + free(winsys); + + return 0; } diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.h b/src/gallium/winsys/g3dvl/xsp_winsys.h index 47a6ac6e25..cb163dc24d 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.h +++ b/src/gallium/winsys/g3dvl/xsp_winsys.h @@ -6,6 +6,7 @@ struct pipe_context; struct pipe_context* create_pipe_context(Display *display); +int destroy_pipe_context(struct pipe_context *pipe); #endif -- cgit v1.2.3 From 0c25ac52425e6d6eb037b99ab90f41b47e3f4491 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Tue, 22 Jul 2008 22:26:26 -0400 Subject: g3dvl: Add Nouveau winsys, libdriclient. Nouveau winsys is based on Mesa's Nouveau winsys and soft-links to most of it. The 'nouveau_context' and 'nouveau_screen' code contains most of the changes, 'nouveau_winsys_pipe', 'nouveau_swapbuffers' and 'nouveau_lock' contain some minor changes. The driclient library contains the DRI userland stuff, most of which was based on Mesa's DRI code. --- src/gallium/winsys/g3dvl/nouveau/Makefile | 46 +++ src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_context.c | 371 +++++++++++++++++++++ src/gallium/winsys/g3dvl/nouveau/nouveau_context.h | 105 ++++++ src/gallium/winsys/g3dvl/nouveau/nouveau_device.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_local.h | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c | 92 +++++ .../winsys/g3dvl/nouveau/nouveau_notifier.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c | 1 + .../winsys/g3dvl/nouveau/nouveau_resource.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c | 88 +++++ src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h | 24 ++ .../winsys/g3dvl/nouveau/nouveau_swapbuffers.c | 64 ++++ .../winsys/g3dvl/nouveau/nouveau_swapbuffers.h | 10 + src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c | 1 + .../winsys/g3dvl/nouveau/nouveau_winsys_pipe.c | 261 +++++++++++++++ .../winsys/g3dvl/nouveau/nouveau_winsys_pipe.h | 1 + .../winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c | 1 + src/gallium/winsys/g3dvl/nouveau/nv04_surface.c | 1 + src/gallium/winsys/g3dvl/nouveau/nv50_surface.c | 1 + src/gallium/winsys/g3dvl/vl_winsys.h | 14 + src/gallium/winsys/g3dvl/xsp_winsys.c | 72 +++- src/gallium/winsys/g3dvl/xsp_winsys.h | 12 - 30 files changed, 1151 insertions(+), 26 deletions(-) create mode 100644 src/gallium/winsys/g3dvl/nouveau/Makefile create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_context.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_context.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_device.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_local.h create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nv04_surface.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nv50_surface.c create mode 100644 src/gallium/winsys/g3dvl/vl_winsys.h delete mode 100644 src/gallium/winsys/g3dvl/xsp_winsys.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile new file mode 100644 index 0000000000..644ac083e6 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -0,0 +1,46 @@ +TARGET = libnouveau_dri.so +GALLIUMDIR = ../../.. +DRMDIR ?= /usr +DRIDIR = ../../../../driclient + +OBJECTS = nouveau_bo.o nouveau_fence.o nouveau_swapbuffers.o nouveau_channel.o \ + nouveau_grobj.o nouveau_context.o nouveau_winsys.o nouveau_lock.o \ + nouveau_winsys_pipe.o nouveau_device.o nouveau_notifier.o nouveau_dma.o \ + nouveau_pushbuf.o nouveau_resource.o nouveau_screen.o nv04_surface.o \ + nv50_surface.o #nouveau_winsys_softpipe.o + +CFLAGS += -g -Wall -Werror -fPIC \ + -I${GALLIUMDIR}/include \ + -I${GALLIUMDIR}/winsys/g3dvl \ + -I${DRMDIR}/include \ + -I${DRMDIR}/include/drm \ + -I${GALLIUMDIR}/drivers \ + -I${GALLIUMDIR}/auxiliary \ + -I${DRIDIR}/include + +LDFLAGS += -L${DRMDIR}/lib \ + -L${DRIDIR}/lib \ + -L${GALLIUMDIR}/auxiliary/draw \ + -L${GALLIUMDIR}/auxiliary/tgsi \ + -L${GALLIUMDIR}/auxiliary/translate \ + -L${GALLIUMDIR}/auxiliary/rtasm \ + -L${GALLIUMDIR}/auxiliary/cso_cache \ + -L${GALLIUMDIR}/drivers/nv10 \ + -L${GALLIUMDIR}/drivers/nv30 \ + -L${GALLIUMDIR}/drivers/nv40 \ + -L${GALLIUMDIR}/drivers/nv50 + +LIBS += -ldriclient -ldrm -lnv10 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm + +############################################# + +.PHONY = all clean + +all: ${TARGET} + +${TARGET}: ${OBJECTS} + $(CC) ${LDFLAGS} -shared -o $@ $^ ${LIBS} + +clean: + rm -rf ${OBJECTS} ${TARGET} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c new file mode 120000 index 0000000000..73ac4a4171 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_bo.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c new file mode 120000 index 0000000000..6c9b2c48d8 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_channel.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c new file mode 100644 index 0000000000..5e173c7672 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c @@ -0,0 +1,371 @@ +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nouveau_context.h" +#include "nouveau_dri.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_winsys_pipe.h" + +/* +#ifdef DEBUG +static const struct dri_debug_control debug_control[] = { + { "bo", DEBUG_BO }, + { NULL, 0 } +}; +int __nouveau_debug = 0; +#endif +*/ + +/* + * TODO: Re-examine dri_screen, dri_context, nouveau_screen, nouveau_context + * relationships, seems like there is a lot of room for simplification there. + */ + +static void +nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) +{ + nouveau_grobj_free(&nvc->NvCtxSurf2D); + nouveau_grobj_free(&nvc->NvImageBlit); + nouveau_grobj_free(&nvc->NvGdiRect); + nouveau_grobj_free(&nvc->NvM2MF); + nouveau_grobj_free(&nvc->Nv2D); + nouveau_grobj_free(&nvc->NvSwzSurf); + nouveau_grobj_free(&nvc->NvSIFM); + + nouveau_notifier_free(&nvc->sync_notifier); + + nouveau_channel_free(&nvc->channel); + + FREE(nvc); +} + +static struct nouveau_channel_context * +nouveau_channel_context_create(struct nouveau_device *dev) +{ + struct nouveau_channel_context *nvc; + int ret; + + nvc = CALLOC_STRUCT(nouveau_channel_context); + if (!nvc) + return NULL; + + if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002, + &nvc->channel))) { + NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + nvc->next_handle = 0x80000000; + + if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, + &nvc->sync_notifier))) { + NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + ret = nouveau_surface_channel_create_nv50(nvc); + break; + default: + ret = nouveau_surface_channel_create_nv04(nvc); + break; + } + + if (ret) { + NOUVEAU_ERR("Error initialising surface objects: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + return nvc; +} + +int +nouveau_context_create(dri_context_t *dri_context) +{ + dri_screen_t *dri_screen = dri_context->dri_screen; + struct nouveau_screen *nv_screen = dri_screen->private; + struct nouveau_context *nv = CALLOC_STRUCT(nouveau_context); + struct pipe_context *pipe = NULL; + struct nouveau_channel_context *nvc = NULL; + struct nouveau_device *dev = nv_screen->device; + int i; + + switch (dev->chipset & 0xf0) { + case 0x10: + case 0x20: + /* NV10 */ + case 0x30: + /* NV30 */ + case 0x40: + case 0x60: + /* NV40 */ + case 0x50: + case 0x80: + case 0x90: + /* G80 */ + break; + default: + NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset); + return 1; + } + + dri_context->private = (void*)nv; + nv->dri_context = dri_context; + nv->nv_screen = nv_screen; + + { + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + nvdev->ctx = dri_context->drm_context; + nvdev->lock = (drmLock*)&dri_screen->sarea->lock; + } + + /* + driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, + nv->dri_screen->myNum, "nouveau"); +#ifdef DEBUG + __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"), + debug_control); +#endif + */ + + /*XXX: Hack up a fake region and buffer object for front buffer. + * This will go away with TTM, replaced with a simple reference + * of the front buffer handle passed to us by the DDX. + */ + { + struct pipe_surface *fb_surf; + struct nouveau_pipe_buffer *fb_buf; + struct nouveau_bo_priv *fb_bo; + + fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); + fb_bo->drm.offset = nv_screen->front_offset; + fb_bo->drm.flags = NOUVEAU_MEM_FB; + fb_bo->drm.size = nv_screen->front_pitch * + nv_screen->front_height; + fb_bo->refcount = 1; + fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; + fb_bo->base.offset = fb_bo->drm.offset; + fb_bo->base.handle = (unsigned long)fb_bo; + fb_bo->base.size = fb_bo->drm.size; + fb_bo->base.device = nv_screen->device; + + fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); + fb_buf->bo = &fb_bo->base; + + fb_surf = calloc(1, sizeof(struct pipe_surface)); + if (nv_screen->front_cpp == 2) + fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; + else + fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; + pf_get_block(fb_surf->format, &fb_surf->block); + fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; + fb_surf->height = nv_screen->front_height; + fb_surf->stride = fb_surf->width * fb_surf->block.size; + fb_surf->refcount = 1; + fb_surf->buffer = &fb_buf->base; + + nv->frontbuffer = fb_surf; + } + + nvc = nv_screen->nvc; + + if (!nvc) { + nvc = nouveau_channel_context_create(dev); + if (!nvc) { + NOUVEAU_ERR("Failed initialising GPU context\n"); + return 1; + } + nv_screen->nvc = nvc; + } + + nvc->refcount++; + nv->nvc = nvc; + + /* Find a free slot for a pipe context, allocate a new one if needed */ + nv->pctx_id = -1; + for (i = 0; i < nvc->nr_pctx; i++) { + if (nvc->pctx[i] == NULL) { + nv->pctx_id = i; + break; + } + } + + if (nv->pctx_id < 0) { + nv->pctx_id = nvc->nr_pctx++; + nvc->pctx = + realloc(nvc->pctx, + sizeof(struct pipe_context *) * nvc->nr_pctx); + } + + /* Create pipe */ + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + if (nouveau_surface_init_nv50(nv)) + return 1; + break; + default: + if (nouveau_surface_init_nv04(nv)) + return 1; + break; + } + + if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { + struct pipe_screen *pscreen; + + pipe = nouveau_pipe_create(nv); + if (!pipe) + NOUVEAU_ERR("Couldn't create hw pipe\n"); + pscreen = nvc->pscreen; + + nv->cap.hw_vertex_buffer = + pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF); + nv->cap.hw_index_buffer = + pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF); + } + + /* XXX: nouveau_winsys_softpipe needs a mesa header removed before we can compile it. */ + /* + if (!pipe) { + NOUVEAU_MSG("Using softpipe\n"); + pipe = nouveau_create_softpipe(nv); + if (!pipe) { + NOUVEAU_ERR("Error creating pipe, bailing\n"); + return 1; + } + } + */ + if (!pipe) { + NOUVEAU_ERR("Error creating pipe, bailing\n"); + return 1; + } + + pipe->priv = nv; + + return 0; +} + +void +nouveau_context_destroy(dri_context_t *dri_context) +{ + struct nouveau_context *nv = dri_context->private; + struct nouveau_channel_context *nvc = nv->nvc; + + assert(nv); + + if (nv->pctx_id >= 0) { + nvc->pctx[nv->pctx_id] = NULL; + if (--nvc->refcount <= 0) { + nouveau_channel_context_destroy(nvc); + nv->nv_screen->nvc = NULL; + } + } + + free(nv); +} + +int +nouveau_context_bind(struct nouveau_context *nv, dri_drawable_t *dri_drawable) +{ + assert(nv); + assert(dri_drawable); + + if (nv->dri_drawable != dri_drawable) + { + nv->dri_drawable = dri_drawable; + dri_drawable->private = nv; + } + + return 0; +} + +int +nouveau_context_unbind(struct nouveau_context *nv) +{ + assert(nv); + + nv->dri_drawable = NULL; + + return 0; +} + +/* Show starts here */ + +int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) +{ + struct nouveau_context *nv; + dri_drawable_t *dri_drawable; + + nv = pipe->priv; + + driCreateDrawable(nv->nv_screen->dri_screen, drawable, &dri_drawable); + + nouveau_context_bind(nv, dri_drawable); + + return 0; +} + +int unbind_pipe_drawable(struct pipe_context *pipe) +{ + nouveau_context_unbind(pipe->priv); + + return 0; +} + +struct pipe_context* create_pipe_context(Display *display, int screen) +{ + dri_screen_t *dri_screen; + dri_framebuffer_t dri_framebuf; + dri_context_t *dri_context; + struct nouveau_context *nv; + + driCreateScreen(display, screen, &dri_screen, &dri_framebuf); + driCreateContext(dri_screen, XDefaultVisual(display, screen), &dri_context); + + nouveau_screen_create(dri_screen, &dri_framebuf); + nouveau_context_create(dri_context); + + nv = dri_context->private; + + return nv->nvc->pctx[nv->pctx_id]; +} + +int destroy_pipe_context(struct pipe_context *pipe) +{ + struct pipe_screen *screen; + struct pipe_winsys *winsys; + struct nouveau_context *nv; + dri_screen_t *dri_screen; + dri_context_t *dri_context; + + assert(pipe); + + screen = pipe->screen; + winsys = pipe->winsys; + nv = pipe->priv; + dri_context = nv->dri_context; + dri_screen = dri_context->dri_screen; + + pipe->destroy(pipe); + screen->destroy(screen); + free(winsys); + + nouveau_context_destroy(dri_context); + nouveau_screen_destroy(dri_screen); + driDestroyContext(dri_context); + driDestroyScreen(dri_screen); + + return 0; +} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h new file mode 100644 index 0000000000..395a3ab790 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h @@ -0,0 +1,105 @@ +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +/*#include "xmlconfig.h"*/ + +#include +#include "nouveau/nouveau_winsys.h" +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +struct nouveau_channel_context { + struct pipe_screen *pscreen; + int refcount; + + unsigned cur_pctx; + unsigned nr_pctx; + struct pipe_context **pctx; + + struct nouveau_channel *channel; + + struct nouveau_notifier *sync_notifier; + + /* Common */ + struct nouveau_grobj *NvM2MF; + /* NV04-NV40 */ + struct nouveau_grobj *NvCtxSurf2D; + struct nouveau_grobj *NvSwzSurf; + struct nouveau_grobj *NvImageBlit; + struct nouveau_grobj *NvGdiRect; + struct nouveau_grobj *NvSIFM; + /* G80 */ + struct nouveau_grobj *Nv2D; + + uint32_t next_handle; + uint32_t next_subchannel; + uint32_t next_sequence; +}; + +struct nouveau_context { + /* DRI stuff */ + dri_context_t *dri_context; + dri_drawable_t *dri_drawable; + unsigned int last_stamp; + /*driOptionCache dri_option_cache;*/ + drm_context_t drm_context; + drmLock drm_lock; + int locked; + struct nouveau_screen *nv_screen; + struct pipe_surface *frontbuffer; + + struct { + int hw_vertex_buffer; + int hw_index_buffer; + } cap; + + /* Hardware context */ + struct nouveau_channel_context *nvc; + int pctx_id; + + /* pipe_surface accel */ + struct pipe_surface *surf_src, *surf_dst; + unsigned surf_src_offset, surf_dst_offset; + + int (*surface_copy_prep)(struct nouveau_context *, + struct pipe_surface *dst, + struct pipe_surface *src); + void (*surface_copy)(struct nouveau_context *, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h); + void (*surface_copy_done)(struct nouveau_context *); + int (*surface_fill)(struct nouveau_context *, struct pipe_surface *, + unsigned, unsigned, unsigned, unsigned, unsigned); +}; + +extern int nouveau_context_create(dri_context_t *); +extern void nouveau_context_destroy(dri_context_t *); +extern int nouveau_context_bind(struct nouveau_context *, dri_drawable_t *); +extern int nouveau_context_unbind(struct nouveau_context *); + +#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 + +extern void LOCK_HARDWARE(struct nouveau_context *); +extern void UNLOCK_HARDWARE(struct nouveau_context *); + +extern int +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *); +extern int +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *); +extern int nouveau_surface_init_nv04(struct nouveau_context *); +extern int nouveau_surface_init_nv50(struct nouveau_context *); + +extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int); +extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *); + +#endif diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c new file mode 120000 index 0000000000..47d52dafa8 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_device.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c new file mode 120000 index 0000000000..45078c964f --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_dma.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h new file mode 120000 index 0000000000..6b9ec77741 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_dma.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h new file mode 120000 index 0000000000..0e6c9fce35 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_dri.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h new file mode 120000 index 0000000000..473b7d4812 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_drmif.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c new file mode 120000 index 0000000000..ef1f0c6afe --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_fence.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c new file mode 120000 index 0000000000..428186544c --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_grobj.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h new file mode 120000 index 0000000000..6b878aad22 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_local.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c new file mode 100644 index 0000000000..375634bd05 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c @@ -0,0 +1,92 @@ +/************************************************************************** + * + * 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 +#include +#include "nouveau_context.h" +#include "nouveau_screen.h" + +static pthread_mutex_t lockMutex = PTHREAD_MUTEX_INITIALIZER; + +static void +nouveau_contended_lock(struct nouveau_context *nv, unsigned int flags) +{ + dri_drawable_t *dri_drawable = nv->dri_drawable; + dri_screen_t *dri_screen = nv->dri_context->dri_screen; + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + drmGetLock(nvdev->fd, nvdev->ctx, flags); + + /* 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 (dri_drawable) + DRI_VALIDATE_DRAWABLE_INFO(dri_screen, dri_drawable); +} + +/* Lock the hardware and validate our state. + */ +void +LOCK_HARDWARE(struct nouveau_context *nv) +{ + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + char __ret=0; + + pthread_mutex_lock(&lockMutex); + assert(!nv->locked); + + DRM_CAS(nvdev->lock, nvdev->ctx, + (DRM_LOCK_HELD | nvdev->ctx), __ret); + + if (__ret) + nouveau_contended_lock(nv, 0); + nv->locked = 1; +} + + +/* Unlock the hardware using the global current context + */ +void +UNLOCK_HARDWARE(struct nouveau_context *nv) +{ + struct nouveau_screen *nv_screen = nv->nv_screen; + 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); + + pthread_mutex_unlock(&lockMutex); +} diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c new file mode 120000 index 0000000000..3024a612a7 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_notifier.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c new file mode 120000 index 0000000000..dae31d9799 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_pushbuf.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c new file mode 120000 index 0000000000..e0d71e9d2b --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_resource.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c new file mode 100644 index 0000000000..0087ce0056 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c @@ -0,0 +1,88 @@ +#include "pipe/p_context.h" +#include "pipe/p_util.h" +#include "nouveau_context.h" +#include "nouveau_drm.h" +#include "nouveau_dri.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" + +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 +#error nouveau_drm.h version does not match expected version +#endif + +/* +PUBLIC const char __driConfigOptions[] = +DRI_CONF_BEGIN +DRI_CONF_END; +static const GLuint __driNConfigOptions = 0; +*/ + +int +nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf) +{ + /* XXX: Someone forgot to bump this? */ + static const dri_version_t ddx_expected = {0, 0, 10 /*NOUVEAU_DRM_HEADER_PATCHLEVEL*/}; + static const dri_version_t dri_expected = {4, 1, 0}; + static const dri_version_t drm_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; + + struct nouveau_dri *nv_dri = dri_framebuf->private; + struct nouveau_screen *nv_screen; + int ret; + + if (!driCompareVersions(&ddx_expected, &dri_screen->ddx)) + { + NOUVEAU_ERR("Unexpected DDX version.\n"); + return 1; + } + + if (!driCompareVersions(&drm_expected, &dri_screen->drm)) + { + NOUVEAU_ERR("Unexpected DRM version.\n"); + return 1; + } + + if (!driCompareVersions(&dri_expected, &dri_screen->dri)) + { + NOUVEAU_ERR("Unexpected DRI version.\n"); + return 1; + } + + if (dri_framebuf->private_size != sizeof(struct nouveau_dri)) { + NOUVEAU_ERR("DRI struct mismatch between DDX/DRI.\n"); + return 1; + } + + nv_screen = CALLOC_STRUCT(nouveau_screen); + if (!nv_screen) + return 1; + nv_screen->dri_screen = dri_screen; + dri_screen->private = (void*)nv_screen; + + /* + driParseOptionInfo(&nv_screen->option_cache, + __driConfigOptions, __driNConfigOptions); + */ + + if ((ret = nouveau_device_open_existing(&nv_screen->device, 0, + dri_screen->fd, 0))) { + NOUVEAU_ERR("Failed opening nouveau device: %d.\n", ret); + return 1; + } + + nv_screen->front_offset = nv_dri->front_offset; + nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8); + nv_screen->front_cpp = nv_dri->bpp / 8; + nv_screen->front_height = nv_dri->height; + + return 0; +} + +void +nouveau_screen_destroy(dri_screen_t *dri_screen) +{ + struct nouveau_screen *nv_screen = dri_screen->private; + + FREE(nv_screen); +} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h new file mode 100644 index 0000000000..8a58bb7556 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h @@ -0,0 +1,24 @@ +#ifndef __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_SCREEN_H__ + +/* TODO: Investigate using DRI options for interesting things */ +/*#include "xmlconfig.h"*/ + +struct nouveau_screen { + dri_screen_t *dri_screen; + struct nouveau_device *device; + struct nouveau_channel_context *nvc; + + uint32_t front_offset; + uint32_t front_pitch; + uint32_t front_cpp; + uint32_t front_height; + + /*driOptionCache option_cache;*/ +}; + +int nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf); +void nouveau_screen_destroy(dri_screen_t *dri_screen); + +#endif + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c new file mode 100644 index 0000000000..7916c80615 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c @@ -0,0 +1,64 @@ +#include "pipe/p_context.h" +#include "nouveau_context.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" + +void +nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct nouveau_context *nv = dri_drawable->private; + drm_clip_rect_t *pbox; + int nbox, i; + + LOCK_HARDWARE(nv); + if (!dri_drawable->num_cliprects) { + UNLOCK_HARDWARE(nv); + return; + } + pbox = dri_drawable->cliprects; + nbox = dri_drawable->num_cliprects; + + nv->surface_copy_prep(nv, nv->frontbuffer, surf); + for (i = 0; i < nbox; i++, pbox++) { + int sx, sy, dx, dy, w, h; + + sx = pbox->x1 - dri_drawable->x; + sy = pbox->y1 - dri_drawable->y; + dx = pbox->x1; + dy = pbox->y1; + w = pbox->x2 - pbox->x1; + h = pbox->y2 - pbox->y1; + + nv->surface_copy(nv, dx, dy, sx, sy, w, h); + } + + FIRE_RING(nv->nvc->channel); + UNLOCK_HARDWARE(nv); + + //if (nv->last_stamp != dri_drawable->last_sarea_stamp) + //nv->last_stamp = dri_drawable->last_sarea_stamp; +} + +void +nouveau_copy_sub_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, int x, int y, int w, int h) +{ + if (surf) { + drm_clip_rect_t rect; + rect.x1 = x; + rect.y1 = y; + rect.x2 = x + w; + rect.y2 = y + h; + + nouveau_copy_buffer(dri_drawable, surf, &rect); + } +} + +void +nouveau_swap_buffers(dri_drawable_t *dri_drawable, struct pipe_surface *surf) +{ + if (surf) + nouveau_copy_buffer(dri_drawable, surf, NULL); +} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.h new file mode 100644 index 0000000000..35e934adba --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.h @@ -0,0 +1,10 @@ +#ifndef __NOUVEAU_SWAPBUFFERS_H__ +#define __NOUVEAU_SWAPBUFFERS_H__ + +extern void nouveau_copy_buffer(dri_drawable_t *, struct pipe_surface *, + const drm_clip_rect_t *); +extern void nouveau_copy_sub_buffer(dri_drawable_t *, struct pipe_surface *, + int x, int y, int w, int h); +extern void nouveau_swap_buffers(dri_drawable_t *, struct pipe_surface *); + +#endif diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c new file mode 120000 index 0000000000..43de49b98b --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_winsys.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c new file mode 100644 index 0000000000..b835bd5760 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c @@ -0,0 +1,261 @@ +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "nouveau_context.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" +#include "nouveau_winsys_pipe.h" + +static void +nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, + void *context_private) +{ + struct nouveau_context *nv = context_private; + dri_drawable_t *dri_drawable = nv->dri_drawable; + + nouveau_copy_buffer(dri_drawable, surf, NULL); +} + +static const char * +nouveau_get_name(struct pipe_winsys *pws) +{ + return "Nouveau/DRI"; +} + +static struct pipe_surface * +nouveau_surface_alloc(struct pipe_winsys *ws) +{ + struct pipe_surface *surf; + + surf = CALLOC_STRUCT(pipe_surface); + if (!surf) + return NULL; + + surf->refcount = 1; + surf->winsys = ws; + return surf; +} + +/* Borrowed from Mesa's xm_winsys */ +static unsigned int +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +nouveau_surface_alloc_storage +( + struct pipe_winsys *pws, + struct pipe_surface *surface, + unsigned width, + unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage +) +{ + const unsigned int ALIGNMENT = 256; + + assert(pws); + assert(surface); + + surface->width = width; + surface->height = height; + surface->format = format; + pf_get_block(format, &surface->block); + surface->nblocksx = pf_get_nblocksx(&surface->block, width); + surface->nblocksy = pf_get_nblocksy(&surface->block, height); + surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); + surface->usage = flags; + surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * surface->nblocksy); + + return 0; +} + +static void +nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + + *s = NULL; + if (--surf->refcount <= 0) { + if (surf->buffer) + pipe_buffer_reference(ws, &surf->buffer, NULL); + free(surf); + } +} + +static struct pipe_buffer * +nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, + unsigned usage, unsigned size) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_context *nv = nvpws->nv; + struct nouveau_device *dev = nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + uint32_t flags; + + nvbuf = calloc(1, sizeof(*nvbuf)); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 1; + nvbuf->base.alignment = alignment; + nvbuf->base.usage = usage; + nvbuf->base.size = size; + + flags = NOUVEAU_BO_LOCAL; + + if (usage & PIPE_BUFFER_USAGE_PIXEL) { + if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) + flags |= NOUVEAU_BO_GART; + flags |= NOUVEAU_BO_VRAM; + } + + if (usage & PIPE_BUFFER_USAGE_VERTEX) { + if (nv->cap.hw_vertex_buffer) + flags |= NOUVEAU_BO_GART; + } + + if (usage & PIPE_BUFFER_USAGE_INDEX) { + if (nv->cap.hw_index_buffer) + flags |= NOUVEAU_BO_GART; + } + + 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 *pws, void *ptr, unsigned bytes) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_device *dev = nvpws->nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + + nvbuf = calloc(1, sizeof(*nvbuf)); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 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_winsys *ws, struct pipe_buffer *buf) +{ + struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + + nouveau_bo_del(&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_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_buffer(buf); + + nouveau_bo_unmap(nvbuf->bo); +} + +static INLINE struct nouveau_fence * +nouveau_pipe_fence(struct pipe_fence_handle *pfence) +{ + return (struct nouveau_fence *)pfence; +} + +static void +nouveau_pipe_fence_reference(struct pipe_winsys *ws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *pfence) +{ + nouveau_fence_ref((void *)pfence, (void *)ptr); +} + +static int +nouveau_pipe_fence_signalled(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, unsigned flag) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)ws; + struct nouveau_fence *fence = nouveau_pipe_fence(pfence); + + if (nouveau_fence(fence)->signalled == 0) + nouveau_fence_flush(nvpws->nv->nvc->channel); + + return !nouveau_fence(fence)->signalled; +} + +static int +nouveau_pipe_fence_finish(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, unsigned flag) +{ + struct nouveau_fence *fence = nouveau_pipe_fence(pfence); + struct nouveau_fence *ref = NULL; + + nouveau_fence_ref(fence, &ref); + return nouveau_fence_wait(&ref); +} + +struct pipe_winsys * +nouveau_create_pipe_winsys(struct nouveau_context *nv) +{ + struct nouveau_pipe_winsys *nvpws; + struct pipe_winsys *pws; + + nvpws = CALLOC_STRUCT(nouveau_pipe_winsys); + if (!nvpws) + return NULL; + nvpws->nv = nv; + pws = &nvpws->pws; + + pws->flush_frontbuffer = nouveau_flush_frontbuffer; + + pws->surface_alloc = nouveau_surface_alloc; + pws->surface_alloc_storage = nouveau_surface_alloc_storage; + pws->surface_release = nouveau_surface_release; + + pws->buffer_create = nouveau_pipe_bo_create; + pws->buffer_destroy = nouveau_pipe_bo_del; + pws->user_buffer_create = nouveau_pipe_bo_user_create; + pws->buffer_map = nouveau_pipe_bo_map; + pws->buffer_unmap = nouveau_pipe_bo_unmap; + + pws->fence_reference = nouveau_pipe_fence_reference; + pws->fence_signalled = nouveau_pipe_fence_signalled; + pws->fence_finish = nouveau_pipe_fence_finish; + + pws->get_name = nouveau_get_name; + + return &nvpws->pws; +} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h new file mode 120000 index 0000000000..264716fef0 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_winsys_pipe.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c new file mode 120000 index 0000000000..83faccde96 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_winsys_softpipe.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c b/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c new file mode 120000 index 0000000000..e05f0671d6 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c @@ -0,0 +1 @@ +../../dri/nouveau/nv04_surface.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c b/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c new file mode 120000 index 0000000000..3850748229 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c @@ -0,0 +1 @@ +../../dri/nouveau/nv50_surface.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/vl_winsys.h b/src/gallium/winsys/g3dvl/vl_winsys.h new file mode 100644 index 0000000000..c83db28dd9 --- /dev/null +++ b/src/gallium/winsys/g3dvl/vl_winsys.h @@ -0,0 +1,14 @@ +#ifndef vl_winsys_h +#define vl_winsys_h + +#include + +struct pipe_context; + +struct pipe_context* create_pipe_context(Display *display, int screen); +int destroy_pipe_context(struct pipe_context *pipe); +int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable); +int unbind_pipe_drawable(struct pipe_context *pipe); + +#endif + diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index c660c6e018..0100fe37bd 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -1,4 +1,4 @@ -#include "xsp_winsys.h" +#include "vl_winsys.h" #include #include #include @@ -11,10 +11,17 @@ struct xsp_pipe_winsys { struct pipe_winsys base; - Display *display; XImage fbimage; }; +struct xsp_context +{ + Display *display; + int screen; + Drawable drawable; + int drawable_bound; +}; + struct xsp_buffer { struct pipe_buffer base; @@ -183,13 +190,18 @@ static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *f static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private) { - struct xsp_pipe_winsys *xsp_winsys; + struct xsp_pipe_winsys *xsp_winsys; + struct xsp_context *xsp_context; assert(pws); assert(surface); assert(context_private); xsp_winsys = (struct xsp_pipe_winsys*)pws; + xsp_context = (struct xsp_context*)context_private; + + if (!xsp_context->drawable_bound) + return; xsp_winsys->fbimage.width = surface->width; xsp_winsys->fbimage.height = surface->height; @@ -198,9 +210,9 @@ static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface * XPutImage ( - xsp_winsys->display, - *(Drawable*)context_private, - XDefaultGC(xsp_winsys->display, XDefaultScreen(xsp_winsys->display)), + xsp_context->display, + xsp_context->drawable, + XDefaultGC(xsp_context->display, xsp_context->screen), &xsp_winsys->fbimage, 0, 0, @@ -209,7 +221,7 @@ static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface * surface->width, surface->height ); - XFlush(xsp_winsys->display); + XFlush(xsp_context->display); pipe_surface_unmap(surface); } @@ -221,11 +233,37 @@ static const char* xsp_get_name(struct pipe_winsys *pws) /* Show starts here */ -struct pipe_context* create_pipe_context(Display *display) +int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) +{ + struct xsp_context *xsp_context; + + assert(pipe); + + xsp_context = pipe->priv; + xsp_context->drawable = drawable; + xsp_context->drawable_bound = 1; + + return 0; +} + +int unbind_pipe_drawable(struct pipe_context *pipe) +{ + struct xsp_context *xsp_context; + + assert(pipe); + + xsp_context = pipe->priv; + xsp_context->drawable_bound = 0; + + return 0; +} + +struct pipe_context* create_pipe_context(Display *display, int screen) { struct xsp_pipe_winsys *xsp_winsys; - struct pipe_screen *screen; - struct pipe_context *pipe; + struct xsp_context *xsp_context; + struct pipe_screen *sp_screen; + struct pipe_context *sp_pipe; assert(display); @@ -243,7 +281,6 @@ struct pipe_context* create_pipe_context(Display *display) xsp_winsys->base.fence_finish = xsp_fence_finish; xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer; xsp_winsys->base.get_name = xsp_get_name; - xsp_winsys->display = display; { /* XXX: Can't use the returned XImage* directly, @@ -269,10 +306,16 @@ struct pipe_context* create_pipe_context(Display *display) XDestroyImage(template); } - screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); - pipe = softpipe_create(screen, (struct pipe_winsys*)xsp_winsys, NULL); + sp_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); + sp_pipe = softpipe_create(sp_screen, (struct pipe_winsys*)xsp_winsys, NULL); + + xsp_context = calloc(1, sizeof(struct xsp_context)); + xsp_context->display = display; + xsp_context->screen = screen; + + sp_pipe->priv = xsp_context; - return pipe; + return sp_pipe; } int destroy_pipe_context(struct pipe_context *pipe) @@ -284,6 +327,7 @@ int destroy_pipe_context(struct pipe_context *pipe) screen = pipe->screen; winsys = pipe->winsys; + free(pipe->priv); pipe->destroy(pipe); screen->destroy(screen); free(winsys); diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.h b/src/gallium/winsys/g3dvl/xsp_winsys.h deleted file mode 100644 index cb163dc24d..0000000000 --- a/src/gallium/winsys/g3dvl/xsp_winsys.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef xsp_winsys_h -#define xsp_winsys_h - -#include - -struct pipe_context; - -struct pipe_context* create_pipe_context(Display *display); -int destroy_pipe_context(struct pipe_context *pipe); - -#endif - -- cgit v1.2.3 From b4d198e47704f3b79c5a61877846172ae9d4b4c0 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Wed, 23 Jul 2008 02:28:02 -0400 Subject: g3dvl: Minor fixes. --- src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c | 42 +++++++++++++---------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c index 0087ce0056..daea3fff68 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c @@ -1,7 +1,7 @@ #include "pipe/p_context.h" #include "pipe/p_util.h" #include "nouveau_context.h" -#include "nouveau_drm.h" +#include #include "nouveau_dri.h" #include "nouveau_local.h" #include "nouveau_screen.h" @@ -18,40 +18,44 @@ DRI_CONF_END; static const GLuint __driNConfigOptions = 0; */ -int -nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf) +int nouveau_check_dri_drm_ddx(dri_version_t *dri, dri_version_t *drm, dri_version_t *ddx) { - /* XXX: Someone forgot to bump this? */ - static const dri_version_t ddx_expected = {0, 0, 10 /*NOUVEAU_DRM_HEADER_PATCHLEVEL*/}; - static const dri_version_t dri_expected = {4, 1, 0}; + static const dri_version_t ddx_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; + static const dri_version_t dri_expected = {4, 0, 0}; static const dri_version_t drm_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; - struct nouveau_dri *nv_dri = dri_framebuf->private; - struct nouveau_screen *nv_screen; - int ret; + assert(dri); + assert(drm); + assert(ddx); - if (!driCompareVersions(&ddx_expected, &dri_screen->ddx)) + if (dri->major != dri_expected.major || dri->minor < dri_expected.minor) { - NOUVEAU_ERR("Unexpected DDX version.\n"); + NOUVEAU_ERR("Unexpected DRI version.\n"); return 1; } - - if (!driCompareVersions(&drm_expected, &dri_screen->drm)) + if (drm->major != drm_expected.major || drm->minor < drm_expected.minor) { NOUVEAU_ERR("Unexpected DRM version.\n"); return 1; } - - if (!driCompareVersions(&dri_expected, &dri_screen->dri)) + if (ddx->major != ddx_expected.major || ddx->minor < ddx_expected.minor) { - NOUVEAU_ERR("Unexpected DRI version.\n"); + NOUVEAU_ERR("Unexpected DDX version.\n"); return 1; } + + return 0; +} - if (dri_framebuf->private_size != sizeof(struct nouveau_dri)) { - NOUVEAU_ERR("DRI struct mismatch between DDX/DRI.\n"); +int +nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf) +{ + struct nouveau_dri *nv_dri = dri_framebuf->private; + struct nouveau_screen *nv_screen; + int ret; + + if (nouveau_check_dri_drm_ddx(&dri_screen->dri, &dri_screen->drm, &dri_screen->ddx)) return 1; - } nv_screen = CALLOC_STRUCT(nouveau_screen); if (!nv_screen) -- cgit v1.2.3 From 818cd9dca2861dfb9d8f2d36ff141c55472df2ba Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 23 Jul 2008 14:02:33 +0200 Subject: i915: intel_flush_frontbuffer does work --- src/gallium/winsys/dri/intel/intel_screen.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index f2412217f3..b3022fd17a 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -253,12 +253,10 @@ intel_flush_frontbuffer( struct pipe_winsys *winsys, struct pipe_surface *surf, void *context_private) { - //struct intel_context *intel = (struct intel_context *) context_private; - //__DRIdrawablePrivate *dPriv = intel->driDrawable; + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; - assert((int)"Doesn't work currently" & 0); - - //intelDisplaySurface(dPriv, surf, NULL); + intelDisplaySurface(dPriv, surf, NULL); } static boolean -- cgit v1.2.3 From a17e6c046cd990f2ed4d0dfe9ed0a59bccd9aade Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 26 Jul 2008 16:51:09 -0400 Subject: g3dvl: Recursively build dependencies. Run `make` in src/libXvMC and everything should be built for Nouveau. Run `make DRIVER=softpipe` in src/libXvMC for SoftPipe. --- src/gallium/winsys/g3dvl/nouveau/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 644ac083e6..2861bd7db4 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -39,8 +39,10 @@ LIBS += -ldriclient -ldrm -lnv10 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate all: ${TARGET} ${TARGET}: ${OBJECTS} + cd ${DRIDIR}/src; ${MAKE} $(CC) ${LDFLAGS} -shared -o $@ $^ ${LIBS} clean: + cd ${DRIDIR}/src; ${MAKE} clean rm -rf ${OBJECTS} ${TARGET} -- cgit v1.2.3 From 18fb8f148679ddddc5a781014d36a51afc304727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 6 Aug 2008 21:37:00 +0100 Subject: xlib: Integrate with the trace pipe driver. --- src/gallium/winsys/xlib/SConscript | 54 ++++++++++++++++++++----------------- src/gallium/winsys/xlib/xm_winsys.c | 13 +++++++++ 2 files changed, 42 insertions(+), 25 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 14a85ae0f2..8650f595a7 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -9,31 +9,35 @@ if env['platform'] == 'linux' \ and 'i965simple' in env['drivers'] \ and not env['dri']: - env = env.Clone() + env = env.Clone() - env.Append(CPPPATH = [ - '#/src/mesa', - '#/src/mesa/main', - ]) + env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', + ]) - sources = [ - 'glxapi.c', - 'fakeglx.c', - 'xfonts.c', - 'xm_api.c', - 'xm_winsys.c', - 'xm_winsys_aub.c', - 'brw_aub.c', - ] - - drivers = [ - softpipe, - i965simple - ] + sources = [ + 'glxapi.c', + 'fakeglx.c', + 'xfonts.c', + 'xm_api.c', + 'xm_winsys.c', + 'xm_winsys_aub.c', + 'brw_aub.c', + ] + + drivers = [ + softpipe, + i965simple, + ] + + if 'trace' in env['drivers']: + env.Append(CPPDEFINES = 'GALLIUM_TRACE') + drivers += [trace] - # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions - env.SharedLibrary( - target ='GL', - source = sources, - LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], - ) + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='GL', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 9225ee510d..5a01b6167b 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -54,6 +54,11 @@ #define TILE_SIZE 32 /* avoid compilation errors */ #endif +#ifdef GALLIUM_TRACE +#include "trace/tr_screen.h" +#include "trace/tr_context.h" +#endif + #include "xm_winsys_aub.h" @@ -674,7 +679,15 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) { struct pipe_screen *screen = softpipe_create_screen(pws); +#ifdef GALLIUM_TRACE + screen = trace_screen_create(screen); +#endif + pipe = softpipe_create(screen, pws, NULL); + +#ifdef GALLIUM_TRACE + pipe = trace_context_create(pipe); +#endif } if (pipe) -- cgit v1.2.3 From c1c4ff28f0af0b14ae64eb01ef1d087b987af2c1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 Aug 2008 15:11:54 -0600 Subject: gallium: use PIPE_FORMAT_X8Z24_UNORM for 24-bit Z but no stencil --- src/gallium/winsys/xlib/xm_api.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 8a32c54349..4e5441a13d 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -363,7 +363,12 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, stencilFormat = PIPE_FORMAT_S8_UNORM; } else { + /* no stencil */ stencilFormat = PIPE_FORMAT_NONE; + if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) { + /* use 24-bit Z, undefined stencil channel */ + depthFormat = PIPE_FORMAT_X8Z24_UNORM; + } } -- cgit v1.2.3 From 6c7aff209ca3b310008dd345836ebc020d2db004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 8 Aug 2008 23:11:56 +0100 Subject: trace: Trace pipe_winsys calls. --- src/gallium/winsys/xlib/xm_winsys.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 5a01b6167b..6071a5ad5e 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -55,6 +55,7 @@ #endif #ifdef GALLIUM_TRACE +#include "trace/tr_winsys.h" #include "trace/tr_screen.h" #include "trace/tr_context.h" #endif @@ -650,7 +651,11 @@ xmesa_get_pipe_winsys(struct xmesa_visual *xm_vis) ws->base.get_name = xm_get_name; } - return &ws->base; +#ifdef GALLIUM_TRACE + return trace_winsys_create(&ws->base); +#else + return &ws->base; +#endif } -- cgit v1.2.3 From cf16285d1bcb9f172a930f9d4f3402e379b53c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 7 Aug 2008 09:03:52 +0100 Subject: gdi: Remove CVS keyword. --- src/gallium/winsys/gdi/wgl.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/wgl.c b/src/gallium/winsys/gdi/wgl.c index 50126014a8..3ce470480d 100644 --- a/src/gallium/winsys/gdi/wgl.c +++ b/src/gallium/winsys/gdi/wgl.c @@ -1,5 +1,3 @@ -/* $Id: wgl.c,v 1.12 2006/03/30 07:58:24 kschultz Exp $ */ - /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public -- cgit v1.2.3 From 969ff9e9bf3dfae08d087bbc47ce43f17d107bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 10:47:39 +0100 Subject: xlib: Use trace usage. --- src/gallium/winsys/xlib/xm_api.c | 5 ++++- src/gallium/winsys/xlib/xm_winsys.c | 15 ++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 4e5441a13d..d2f92a0875 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -67,6 +67,7 @@ #include "state_tracker/st_public.h" #include "state_tracker/st_context.h" #include "pipe/p_defines.h" +#include "pipe/p_screen.h" #include "pipe/p_context.h" #include "xm_winsys_aub.h" @@ -833,7 +834,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) fail: if (c->st) st_destroy_context(c->st); - if (pipe) + else if (pipe) pipe->destroy(pipe); FREE(c); return NULL; @@ -844,7 +845,9 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) PUBLIC void XMesaDestroyContext( XMesaContext c ) { + struct pipe_screen *screen = c->st->pipe->screen; st_destroy_context(c->st); + screen->destroy(screen); _mesa_free(c); } diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 6071a5ad5e..3ab4c67cae 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -55,7 +55,6 @@ #endif #ifdef GALLIUM_TRACE -#include "trace/tr_winsys.h" #include "trace/tr_screen.h" #include "trace/tr_context.h" #endif @@ -651,11 +650,7 @@ xmesa_get_pipe_winsys(struct xmesa_visual *xm_vis) ws->base.get_name = xm_get_name; } -#ifdef GALLIUM_TRACE - return trace_winsys_create(&ws->base); -#else - return &ws->base; -#endif + return &ws->base; } @@ -684,14 +679,12 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) { struct pipe_screen *screen = softpipe_create_screen(pws); -#ifdef GALLIUM_TRACE - screen = trace_screen_create(screen); -#endif - pipe = softpipe_create(screen, pws, NULL); #ifdef GALLIUM_TRACE - pipe = trace_context_create(pipe); + screen = trace_screen_create(screen); + + pipe = trace_context_create(screen, pipe); #endif } -- cgit v1.2.3 From 4b1b5ca9bd4d861ac8654c510f12b52a1a646ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Aug 2008 11:24:06 +0100 Subject: xlib: Kill xmesa_surface. A winsys cannot expect that the surfaces passed display_surface are the surfaces it created, as surface are now in generate texture views created by pipe_screen. Indeed, the fact it was working so far was mere luck. This fixes a weird tiled output when using the trace pipe driver. Winsys' surfaces should die. --- src/gallium/winsys/xlib/xm_winsys.c | 62 ++++++++++++------------------------- 1 file changed, 19 insertions(+), 43 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 3ab4c67cae..4b4dc56e84 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -81,18 +81,6 @@ struct xm_buffer }; -/** - * Subclass of pipe_surface for Xlib winsys - */ -struct xmesa_surface -{ - struct pipe_surface surface; - - int tileSize; - boolean no_swap; -}; - - /** * Subclass of pipe_winsys for Xlib winsys */ @@ -105,14 +93,6 @@ struct xmesa_pipe_winsys -/** Cast wrapper */ -static INLINE struct xmesa_surface * -xmesa_surface(struct pipe_surface *ps) -{ - return (struct xmesa_surface *) ps; -} - - /** Cast wrapper */ static INLINE struct xm_buffer * xm_buffer( struct pipe_buffer *buf ) @@ -358,13 +338,24 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) { XImage *ximage; struct xm_buffer *xm_buf = xm_buffer(surf->buffer); - const struct xmesa_surface *xm_surf - = xmesa_surface((struct pipe_surface *) surf); + static boolean no_swap = 0; + static boolean firsttime = 1; + static int tileSize = 0; - if (xm_surf->no_swap) + if (firsttime) { + no_swap = getenv("SP_NO_RAST") != NULL; +#ifdef GALLIUM_CELL + if (!getenv("GALLIUM_NOCELL")) { + tileSize = 32; /** probably temporary */ + } +#endif + firsttime = 0; + } + + if (no_swap) return; - if (xm_surf->tileSize) { + if (tileSize) { xmesa_display_surface_tiled(b, surf); return; } @@ -531,29 +522,14 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, static struct pipe_surface * xm_surface_alloc(struct pipe_winsys *ws) { - struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface); - static boolean no_swap = 0; - static boolean firsttime = 1; - - if (firsttime) { - no_swap = getenv("SP_NO_RAST") != NULL; - firsttime = 0; - } + struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); assert(ws); - xms->surface.refcount = 1; - xms->surface.winsys = ws; + surface->refcount = 1; + surface->winsys = ws; -#ifdef GALLIUM_CELL - if (!getenv("GALLIUM_NOCELL")) { - xms->tileSize = 32; /** probably temporary */ - } -#endif - - xms->no_swap = no_swap; - - return &xms->surface; + return surface; } -- cgit v1.2.3 From 2037b1381c129c74ba87a092484258608583d34e Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Sun, 17 Aug 2008 19:14:00 +0100 Subject: rather than use CRTC 1 (aka LVDS), try and setup all connectors/encoders and get the same output on all. --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 111 ++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 19 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 55f4d92afb..1851babaf6 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -66,7 +66,67 @@ egl_drm_create_device(int drmFD) return device; } -__GLcontextModes* _gl_context_modes_create( unsigned count, size_t minimum_size ); +static void +_egl_context_modes_destroy(__GLcontextModes *modes) +{ + _eglLog(_EGL_DEBUG, "%s", __FUNCTION__); + + while (modes) { + __GLcontextModes * const next = modes->next; + free(modes); + modes = next; + } +} +/** + * Create a linked list of 'count' GLcontextModes. + * These are used during the client/server visual negotiation phase, + * then discarded. + */ +static __GLcontextModes * +_egl_context_modes_create(unsigned count, size_t minimum_size) +{ + /* This code copied from libGLX, and modified */ + const size_t size = (minimum_size > sizeof(__GLcontextModes)) + ? minimum_size : sizeof(__GLcontextModes); + __GLcontextModes * head = NULL; + __GLcontextModes ** next; + unsigned i; + + _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size); + + next = & head; + for (i = 0 ; i < count ; i++) { + *next = (__GLcontextModes *) calloc(1, size); + if (*next == NULL) { + _egl_context_modes_destroy(head); + head = NULL; + break; + } + + (*next)->doubleBufferMode = 1; + (*next)->visualID = GLX_DONT_CARE; + (*next)->visualType = GLX_DONT_CARE; + (*next)->visualRating = GLX_NONE; + (*next)->transparentPixel = GLX_NONE; + (*next)->transparentRed = GLX_DONT_CARE; + (*next)->transparentGreen = GLX_DONT_CARE; + (*next)->transparentBlue = GLX_DONT_CARE; + (*next)->transparentAlpha = GLX_DONT_CARE; + (*next)->transparentIndex = GLX_DONT_CARE; + (*next)->xRenderable = GLX_DONT_CARE; + (*next)->fbconfigID = GLX_DONT_CARE; + (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; + (*next)->bindToTextureRgb = GLX_DONT_CARE; + (*next)->bindToTextureRgba = GLX_DONT_CARE; + (*next)->bindToMipmapTexture = GLX_DONT_CARE; + (*next)->bindToTextureTargets = 0; + (*next)->yInverted = GLX_DONT_CARE; + + next = & ((*next)->next); + } + + return head; +} struct drm_screen; @@ -102,7 +162,6 @@ struct drm_screen /* currently only support one connector */ drmModeConnectorPtr connector; - uint32_t connectorID; /* Has this screen been shown */ int shown; @@ -190,7 +249,6 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) screen = malloc(sizeof(struct drm_screen)); memset(screen, 0, sizeof(*screen)); - screen->connectorID = res->connectors[i]; screen->connector = connector; _eglInitScreen(&screen->base); _eglAddScreen(disp, &screen->base); @@ -225,17 +283,20 @@ static void drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) { struct drm_driver *drm_drv = (struct drm_driver *)drv; + unsigned int i; intel_bind_frontbuffer(screen->surf->drawable, NULL); screen->surf = NULL; - drmModeSetCrtc( - drm_drv->device->drmFD, - drm_drv->res->crtcs[1], - 0, // FD - 0, 0, - NULL, 0, // List of output ids - NULL); + for (i = 0; i < drm_drv->res->count_crtcs; i++) { + drmModeSetCrtc( + drm_drv->device->drmFD, + drm_drv->res->crtcs[i], + 0, // FD + 0, 0, + NULL, 0, // List of output ids + NULL); + } drmModeRmFB(drm_drv->device->drmFD, screen->fbID); drmModeFreeFB(screen->fb); @@ -560,9 +621,10 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, struct drm_surface *surf = lookup_drm_surface(surface); struct drm_screen *scrn = lookup_drm_screen(dpy, screen); _EGLMode *mode = _eglLookupMode(dpy, m); - size_t pitch = 2048 * 4; + size_t pitch = mode->Width * 4; size_t size = mode->Height * pitch; int ret; + unsigned int i,j,k; if (scrn->shown) drm_takedown_shown_screen(drv, scrn); @@ -596,14 +658,25 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, if (!scrn->mode) goto err_fb; - ret = drmModeSetCrtc( - drm_drv->device->drmFD, - drm_drv->res->crtcs[1], - scrn->fbID, - 0, 0, - &scrn->connectorID, 1, - scrn->mode); - + for (j = 0; j < drm_drv->res->count_connectors; j++) { + drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]); + for (k = 0; k < con->count_encoders; k++) { + drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]); + for (i = 0; i < drm_drv->res->count_crtcs; i++) { + if (enc->possible_crtcs & (1<device->drmFD, + drm_drv->res->crtcs[i], + scrn->fbID, + 0, 0, + &drm_drv->res->connectors[j], 1, + scrn->mode); + /* skip the other crtcs now */ + i = drm_drv->res->count_crtcs; + } + } + } + } scrn->front.handle = scrn->buffer.handle; scrn->front.pitch = pitch; -- cgit v1.2.3 From ccf1910dd4b2a8ccd04ddbdf725b6dd3f8026eee Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Sun, 17 Aug 2008 20:17:18 +0100 Subject: consolidate intel directories. we now have src/gallium/winsys/drm/intel/{common,dri,egl} --- src/gallium/winsys/SConscript | 4 +- src/gallium/winsys/common/Makefile | 20 - src/gallium/winsys/common/Makefile.template | 64 -- src/gallium/winsys/common/intel_drm/Makefile | 23 - src/gallium/winsys/common/intel_drm/glthread.h | 359 -------- .../winsys/common/intel_drm/intel_be_batchbuffer.c | 429 --------- .../winsys/common/intel_drm/intel_be_batchbuffer.h | 69 -- .../winsys/common/intel_drm/intel_be_context.c | 107 --- .../winsys/common/intel_drm/intel_be_context.h | 40 - .../winsys/common/intel_drm/intel_be_device.c | 308 ------- .../winsys/common/intel_drm/intel_be_device.h | 72 -- .../winsys/common/intel_drm/ws_dri_bufmgr.c | 949 -------------------- .../winsys/common/intel_drm/ws_dri_bufmgr.h | 138 --- .../winsys/common/intel_drm/ws_dri_bufpool.h | 102 --- .../winsys/common/intel_drm/ws_dri_drmpool.c | 268 ------ .../winsys/common/intel_drm/ws_dri_fencemgr.c | 377 -------- .../winsys/common/intel_drm/ws_dri_fencemgr.h | 115 --- .../winsys/common/intel_drm/ws_dri_mallocpool.c | 161 ---- .../winsys/common/intel_drm/ws_dri_slabpool.c | 968 --------------------- src/gallium/winsys/dri/Makefile | 38 - src/gallium/winsys/dri/Makefile.template | 125 --- src/gallium/winsys/dri/SConscript | 54 -- src/gallium/winsys/dri/intel/Makefile | 34 - src/gallium/winsys/dri/intel/SConscript | 41 - src/gallium/winsys/dri/intel/intel_batchbuffer.h | 24 - src/gallium/winsys/dri/intel/intel_context.c | 337 ------- src/gallium/winsys/dri/intel/intel_context.h | 164 ---- src/gallium/winsys/dri/intel/intel_lock.c | 102 --- src/gallium/winsys/dri/intel/intel_reg.h | 53 -- src/gallium/winsys/dri/intel/intel_screen.c | 607 ------------- src/gallium/winsys/dri/intel/intel_screen.h | 122 --- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 261 ------ src/gallium/winsys/dri/intel/intel_swapbuffers.h | 47 - .../winsys/dri/intel/intel_winsys_softpipe.c | 82 -- .../winsys/dri/intel/intel_winsys_softpipe.h | 39 - src/gallium/winsys/dri/intel/server/i830_common.h | 255 ------ src/gallium/winsys/dri/intel/server/i830_dri.h | 62 -- src/gallium/winsys/drm/Makefile | 38 + src/gallium/winsys/drm/Makefile.template | 125 +++ src/gallium/winsys/drm/SConscript | 54 ++ src/gallium/winsys/drm/intel/Makefile | 25 + src/gallium/winsys/drm/intel/common/Makefile | 23 + .../winsys/drm/intel/common/Makefile.template | 64 ++ src/gallium/winsys/drm/intel/common/glthread.h | 359 ++++++++ .../winsys/drm/intel/common/intel_be_batchbuffer.c | 429 +++++++++ .../winsys/drm/intel/common/intel_be_batchbuffer.h | 69 ++ .../winsys/drm/intel/common/intel_be_context.c | 107 +++ .../winsys/drm/intel/common/intel_be_context.h | 40 + .../winsys/drm/intel/common/intel_be_device.c | 308 +++++++ .../winsys/drm/intel/common/intel_be_device.h | 72 ++ .../winsys/drm/intel/common/ws_dri_bufmgr.c | 949 ++++++++++++++++++++ .../winsys/drm/intel/common/ws_dri_bufmgr.h | 138 +++ .../winsys/drm/intel/common/ws_dri_bufpool.h | 102 +++ .../winsys/drm/intel/common/ws_dri_drmpool.c | 268 ++++++ .../winsys/drm/intel/common/ws_dri_fencemgr.c | 377 ++++++++ .../winsys/drm/intel/common/ws_dri_fencemgr.h | 115 +++ .../winsys/drm/intel/common/ws_dri_mallocpool.c | 161 ++++ .../winsys/drm/intel/common/ws_dri_slabpool.c | 968 +++++++++++++++++++++ src/gallium/winsys/drm/intel/dri/Makefile | 33 + src/gallium/winsys/drm/intel/dri/SConscript | 41 + .../winsys/drm/intel/dri/intel_batchbuffer.h | 24 + src/gallium/winsys/drm/intel/dri/intel_context.c | 337 +++++++ src/gallium/winsys/drm/intel/dri/intel_context.h | 164 ++++ src/gallium/winsys/drm/intel/dri/intel_lock.c | 102 +++ src/gallium/winsys/drm/intel/dri/intel_reg.h | 53 ++ src/gallium/winsys/drm/intel/dri/intel_screen.c | 607 +++++++++++++ src/gallium/winsys/drm/intel/dri/intel_screen.h | 122 +++ .../winsys/drm/intel/dri/intel_swapbuffers.c | 261 ++++++ .../winsys/drm/intel/dri/intel_swapbuffers.h | 47 + .../winsys/drm/intel/dri/intel_winsys_softpipe.c | 82 ++ .../winsys/drm/intel/dri/intel_winsys_softpipe.h | 39 + .../winsys/drm/intel/dri/server/i830_common.h | 255 ++++++ src/gallium/winsys/drm/intel/dri/server/i830_dri.h | 62 ++ src/gallium/winsys/drm/intel/egl/Makefile | 28 + src/gallium/winsys/drm/intel/egl/SConscript | 39 + .../winsys/drm/intel/egl/intel_batchbuffer.h | 24 + src/gallium/winsys/drm/intel/egl/intel_context.c | 242 ++++++ src/gallium/winsys/drm/intel/egl/intel_context.h | 118 +++ src/gallium/winsys/drm/intel/egl/intel_device.c | 137 +++ src/gallium/winsys/drm/intel/egl/intel_device.h | 50 ++ src/gallium/winsys/drm/intel/egl/intel_egl.c | 796 +++++++++++++++++ src/gallium/winsys/drm/intel/egl/intel_egl.h | 53 ++ src/gallium/winsys/drm/intel/egl/intel_reg.h | 53 ++ .../winsys/drm/intel/egl/intel_swapbuffers.c | 111 +++ src/gallium/winsys/egl_drm/Makefile | 38 - src/gallium/winsys/egl_drm/Makefile.template | 117 --- src/gallium/winsys/egl_drm/intel/Makefile | 29 - src/gallium/winsys/egl_drm/intel/SConscript | 39 - .../winsys/egl_drm/intel/intel_batchbuffer.h | 24 - src/gallium/winsys/egl_drm/intel/intel_context.c | 242 ------ src/gallium/winsys/egl_drm/intel/intel_context.h | 118 --- src/gallium/winsys/egl_drm/intel/intel_device.c | 137 --- src/gallium/winsys/egl_drm/intel/intel_device.h | 50 -- src/gallium/winsys/egl_drm/intel/intel_egl.c | 796 ----------------- src/gallium/winsys/egl_drm/intel/intel_egl.h | 53 -- src/gallium/winsys/egl_drm/intel/intel_reg.h | 53 -- .../winsys/egl_drm/intel/intel_swapbuffers.c | 111 --- src/gallium/winsys/gdi/wmesa.c | 70 -- 98 files changed, 8673 insertions(+), 8895 deletions(-) delete mode 100644 src/gallium/winsys/common/Makefile delete mode 100644 src/gallium/winsys/common/Makefile.template delete mode 100644 src/gallium/winsys/common/intel_drm/Makefile delete mode 100644 src/gallium/winsys/common/intel_drm/glthread.h delete mode 100644 src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c delete mode 100644 src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h delete mode 100644 src/gallium/winsys/common/intel_drm/intel_be_context.c delete mode 100644 src/gallium/winsys/common/intel_drm/intel_be_context.h delete mode 100644 src/gallium/winsys/common/intel_drm/intel_be_device.c delete mode 100644 src/gallium/winsys/common/intel_drm/intel_be_device.h delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c delete mode 100644 src/gallium/winsys/dri/Makefile delete mode 100644 src/gallium/winsys/dri/Makefile.template delete mode 100644 src/gallium/winsys/dri/SConscript delete mode 100644 src/gallium/winsys/dri/intel/Makefile delete mode 100644 src/gallium/winsys/dri/intel/SConscript delete mode 100644 src/gallium/winsys/dri/intel/intel_batchbuffer.h delete mode 100644 src/gallium/winsys/dri/intel/intel_context.c delete mode 100644 src/gallium/winsys/dri/intel/intel_context.h delete mode 100644 src/gallium/winsys/dri/intel/intel_lock.c delete mode 100644 src/gallium/winsys/dri/intel/intel_reg.h delete mode 100644 src/gallium/winsys/dri/intel/intel_screen.c delete mode 100644 src/gallium/winsys/dri/intel/intel_screen.h delete mode 100644 src/gallium/winsys/dri/intel/intel_swapbuffers.c delete mode 100644 src/gallium/winsys/dri/intel/intel_swapbuffers.h delete mode 100644 src/gallium/winsys/dri/intel/intel_winsys_softpipe.c delete mode 100644 src/gallium/winsys/dri/intel/intel_winsys_softpipe.h delete mode 100644 src/gallium/winsys/dri/intel/server/i830_common.h delete mode 100644 src/gallium/winsys/dri/intel/server/i830_dri.h create mode 100644 src/gallium/winsys/drm/Makefile create mode 100644 src/gallium/winsys/drm/Makefile.template create mode 100644 src/gallium/winsys/drm/SConscript create mode 100644 src/gallium/winsys/drm/intel/Makefile create mode 100644 src/gallium/winsys/drm/intel/common/Makefile create mode 100644 src/gallium/winsys/drm/intel/common/Makefile.template create mode 100644 src/gallium/winsys/drm/intel/common/glthread.h create mode 100644 src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.c create mode 100644 src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.h create mode 100644 src/gallium/winsys/drm/intel/common/intel_be_context.c create mode 100644 src/gallium/winsys/drm/intel/common/intel_be_context.h create mode 100644 src/gallium/winsys/drm/intel/common/intel_be_device.c create mode 100644 src/gallium/winsys/drm/intel/common/intel_be_device.h create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.h create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_bufpool.h create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_drmpool.c create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.c create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.h create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_mallocpool.c create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_slabpool.c create mode 100644 src/gallium/winsys/drm/intel/dri/Makefile create mode 100644 src/gallium/winsys/drm/intel/dri/SConscript create mode 100644 src/gallium/winsys/drm/intel/dri/intel_batchbuffer.h create mode 100644 src/gallium/winsys/drm/intel/dri/intel_context.c create mode 100644 src/gallium/winsys/drm/intel/dri/intel_context.h create mode 100644 src/gallium/winsys/drm/intel/dri/intel_lock.c create mode 100644 src/gallium/winsys/drm/intel/dri/intel_reg.h create mode 100644 src/gallium/winsys/drm/intel/dri/intel_screen.c create mode 100644 src/gallium/winsys/drm/intel/dri/intel_screen.h create mode 100644 src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c create mode 100644 src/gallium/winsys/drm/intel/dri/intel_swapbuffers.h create mode 100644 src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c create mode 100644 src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.h create mode 100644 src/gallium/winsys/drm/intel/dri/server/i830_common.h create mode 100644 src/gallium/winsys/drm/intel/dri/server/i830_dri.h create mode 100644 src/gallium/winsys/drm/intel/egl/Makefile create mode 100644 src/gallium/winsys/drm/intel/egl/SConscript create mode 100644 src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h create mode 100644 src/gallium/winsys/drm/intel/egl/intel_context.c create mode 100644 src/gallium/winsys/drm/intel/egl/intel_context.h create mode 100644 src/gallium/winsys/drm/intel/egl/intel_device.c create mode 100644 src/gallium/winsys/drm/intel/egl/intel_device.h create mode 100644 src/gallium/winsys/drm/intel/egl/intel_egl.c create mode 100644 src/gallium/winsys/drm/intel/egl/intel_egl.h create mode 100644 src/gallium/winsys/drm/intel/egl/intel_reg.h create mode 100644 src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c delete mode 100644 src/gallium/winsys/egl_drm/Makefile delete mode 100644 src/gallium/winsys/egl_drm/Makefile.template delete mode 100644 src/gallium/winsys/egl_drm/intel/Makefile delete mode 100644 src/gallium/winsys/egl_drm/intel/SConscript delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_context.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_context.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_device.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_device.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_egl.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_egl.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_reg.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index bf1718e7a5..ddab9efc86 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -1,8 +1,8 @@ Import('*') -if env['dri']: +if env['drm']: SConscript([ - 'dri/SConscript', + 'drm/SConscript', ]) if 'xlib' in env['winsys']: diff --git a/src/gallium/winsys/common/Makefile b/src/gallium/winsys/common/Makefile deleted file mode 100644 index 4c0f3545a5..0000000000 --- a/src/gallium/winsys/common/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -TOP = ../../../.. -include $(TOP)/configs/current - - -SUBDIRS = $(GALLIUM_WINSYS_COMMON_DIRS) - - -default: subdirs - - -subdirs: - @for dir in $(SUBDIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE)) || exit 1 ; \ - fi \ - done - - -clean: - rm -f `find . -name \*.[oa]` diff --git a/src/gallium/winsys/common/Makefile.template b/src/gallium/winsys/common/Makefile.template deleted file mode 100644 index 67af778157..0000000000 --- a/src/gallium/winsys/common/Makefile.template +++ /dev/null @@ -1,64 +0,0 @@ -# -*-makefile-*- - - -# We still have a dependency on the "dri" buffer manager. Most likely -# the interface can be reused in non-dri environments, and also as a -# frontend to simpler memory managers. -# -COMMON_SOURCES = - -OBJECTS = $(C_SOURCES:.c=.o) \ - $(CPP_SOURCES:.cpp=.o) \ - $(ASM_SOURCES:.S=.o) - - -### Include directories -INCLUDES = \ - -I. \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/include \ - $(DRIVER_INCLUDES) - - -##### RULES ##### - -.c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.cpp.o: - $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - - -##### TARGETS ##### - -default: depend symlinks $(LIBNAME) - - -$(LIBNAME): $(OBJECTS) Makefile $(TOP)/src/gallium/winsys/common/Makefile.template - $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) - - -depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ - $(ASM_SOURCES) 2> /dev/null - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` `find ../include` - - -# Remove .o and backup files -clean:: - -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) - -rm -f depend depend.bak - - -include depend diff --git a/src/gallium/winsys/common/intel_drm/Makefile b/src/gallium/winsys/common/intel_drm/Makefile deleted file mode 100644 index 913dbeff20..0000000000 --- a/src/gallium/winsys/common/intel_drm/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -TOP = ../../../../.. -include $(TOP)/configs/current - -LIBNAME = inteldrm - -C_SOURCES = \ - intel_be_batchbuffer.c \ - intel_be_context.c \ - intel_be_device.c \ - ws_dri_bufmgr.c \ - ws_dri_drmpool.c \ - ws_dri_fencemgr.c \ - ws_dri_mallocpool.c \ - ws_dri_slabpool.c - - -include ../Makefile.template - -DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \ - && pkg-config libdrm --atleast-version=2.3.1 \ - && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") -symlinks: - diff --git a/src/gallium/winsys/common/intel_drm/glthread.h b/src/gallium/winsys/common/intel_drm/glthread.h deleted file mode 100644 index b8e9d5f59b..0000000000 --- a/src/gallium/winsys/common/intel_drm/glthread.h +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 1999-2006 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - - -/* - * Thread support for gl dispatch. - * - * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) - * and Christoph Poliwoda (poliwoda@volumegraphics.com) - * Revised by Keith Whitwell - * Adapted for new gl dispatcher by Brian Paul - * - * - * - * DOCUMENTATION - * - * This thread module exports the following types: - * _glthread_TSD Thread-specific data area - * _glthread_Thread Thread datatype - * _glthread_Mutex Mutual exclusion lock - * - * Macros: - * _glthread_DECLARE_STATIC_MUTEX(name) Declare a non-local mutex - * _glthread_INIT_MUTEX(name) Initialize a mutex - * _glthread_LOCK_MUTEX(name) Lock a mutex - * _glthread_UNLOCK_MUTEX(name) Unlock a mutex - * - * Functions: - * _glthread_GetID(v) Get integer thread ID - * _glthread_InitTSD() Initialize thread-specific data - * _glthread_GetTSD() Get thread-specific data - * _glthread_SetTSD() Set thread-specific data - * - */ - -/* - * If this file is accidentally included by a non-threaded build, - * it should not cause the build to fail, or otherwise cause problems. - * In general, it should only be included when needed however. - */ - -#ifndef GLTHREAD_H -#define GLTHREAD_H - - -#if defined(USE_MGL_NAMESPACE) -#define _glapi_Dispatch _mglapi_Dispatch -#endif - - - -#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\ - defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \ - && !defined(THREADS) -# define THREADS -#endif - -#ifdef VMS -#include -#endif - -/* - * POSIX threads. This should be your choice in the Unix world - * whenever possible. When building with POSIX threads, be sure - * to enable any compiler flags which will cause the MT-safe - * libc (if one exists) to be used when linking, as well as any - * header macros for MT-safe errno, etc. For Solaris, this is the -mt - * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable - * proper compiling for MT-safe libc etc. - */ -#if defined(PTHREADS) -#include /* POSIX threads headers */ - -typedef struct { - pthread_key_t key; - int initMagic; -} _glthread_TSD; - -typedef pthread_t _glthread_Thread; - -typedef pthread_mutex_t _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) \ - static _glthread_Mutex name = PTHREAD_MUTEX_INITIALIZER - -#define _glthread_INIT_MUTEX(name) \ - pthread_mutex_init(&(name), NULL) - -#define _glthread_DESTROY_MUTEX(name) \ - pthread_mutex_destroy(&(name)) - -#define _glthread_LOCK_MUTEX(name) \ - (void) pthread_mutex_lock(&(name)) - -#define _glthread_UNLOCK_MUTEX(name) \ - (void) pthread_mutex_unlock(&(name)) - -typedef pthread_cond_t _glthread_Cond; - -#define _glthread_DECLARE_STATIC_COND(name) \ - static _glthread_Cond name = PTHREAD_COND_INITIALIZER - -#define _glthread_INIT_COND(cond) \ - pthread_cond_init(&(cond), NULL) - -#define _glthread_DESTROY_COND(name) \ - pthread_cond_destroy(&(name)) - -#define _glthread_COND_WAIT(cond, mutex) \ - pthread_cond_wait(&(cond), &(mutex)) - -#define _glthread_COND_SIGNAL(cond) \ - pthread_cond_signal(&(cond)) - -#define _glthread_COND_BROADCAST(cond) \ - pthread_cond_broadcast(&(cond)) - - -#else /* PTHREADS */ - -typedef unsigned int _glthread_Cond; -#define _glthread_DECLARE_STATIC_COND(name) \ -// #warning Condition variables not implemented. - -#define _glthread_INIT_COND(cond) \ - abort(); - -#define _glthread_DESTROY_COND(name) \ - abort(); - -#define _glthread_COND_WAIT(cond, mutex) \ - abort(); - -#define _glthread_COND_SIGNAL(cond) \ - abort(); - -#define _glthread_COND_BROADCAST(cond) \ - abort(); - -#endif - - -/* - * Solaris threads. Use only up to Solaris 2.4. - * Solaris 2.5 and higher provide POSIX threads. - * Be sure to compile with -mt on the Solaris compilers, or - * use -D_REENTRANT if using gcc. - */ -#ifdef SOLARIS_THREADS -#include - -typedef struct { - thread_key_t key; - mutex_t keylock; - int initMagic; -} _glthread_TSD; - -typedef thread_t _glthread_Thread; - -typedef mutex_t _glthread_Mutex; - -/* XXX need to really implement mutex-related macros */ -#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 -#define _glthread_INIT_MUTEX(name) (void) name -#define _glthread_DESTROY_MUTEX(name) (void) name -#define _glthread_LOCK_MUTEX(name) (void) name -#define _glthread_UNLOCK_MUTEX(name) (void) name - -#endif /* SOLARIS_THREADS */ - - - - -/* - * Windows threads. Should work with Windows NT and 95. - * IMPORTANT: Link with multithreaded runtime library when THREADS are - * used! - */ -#ifdef WIN32_THREADS -#include - -typedef struct { - DWORD key; - int initMagic; -} _glthread_TSD; - -typedef HANDLE _glthread_Thread; - -typedef CRITICAL_SECTION _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) /*static*/ _glthread_Mutex name = {0,0,0,0,0,0} -#define _glthread_INIT_MUTEX(name) InitializeCriticalSection(&name) -#define _glthread_DESTROY_MUTEX(name) DeleteCriticalSection(&name) -#define _glthread_LOCK_MUTEX(name) EnterCriticalSection(&name) -#define _glthread_UNLOCK_MUTEX(name) LeaveCriticalSection(&name) - -#endif /* WIN32_THREADS */ - - - - -/* - * XFree86 has its own thread wrapper, Xthreads.h - * We wrap it again for GL. - */ -#ifdef USE_XTHREADS -#include - -typedef struct { - xthread_key_t key; - int initMagic; -} _glthread_TSD; - -typedef xthread_t _glthread_Thread; - -typedef xmutex_rec _glthread_Mutex; - -#ifdef XMUTEX_INITIALIZER -#define _glthread_DECLARE_STATIC_MUTEX(name) \ - static _glthread_Mutex name = XMUTEX_INITIALIZER -#else -#define _glthread_DECLARE_STATIC_MUTEX(name) \ - static _glthread_Mutex name -#endif - -#define _glthread_INIT_MUTEX(name) \ - xmutex_init(&(name)) - -#define _glthread_DESTROY_MUTEX(name) \ - xmutex_clear(&(name)) - -#define _glthread_LOCK_MUTEX(name) \ - (void) xmutex_lock(&(name)) - -#define _glthread_UNLOCK_MUTEX(name) \ - (void) xmutex_unlock(&(name)) - -#endif /* USE_XTHREADS */ - - - -/* - * BeOS threads. R5.x required. - */ -#ifdef BEOS_THREADS - -#include -#include - -typedef struct { - int32 key; - int initMagic; -} _glthread_TSD; - -typedef thread_id _glthread_Thread; - -/* Use Benaphore, aka speeder semaphore */ -typedef struct { - int32 lock; - sem_id sem; -} benaphore; -typedef benaphore _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = { 0, 0 } -#define _glthread_INIT_MUTEX(name) name.sem = create_sem(0, #name"_benaphore"), name.lock = 0 -#define _glthread_DESTROY_MUTEX(name) delete_sem(name.sem), name.lock = 0 -#define _glthread_LOCK_MUTEX(name) if (name.sem == 0) _glthread_INIT_MUTEX(name); \ - if (atomic_add(&(name.lock), 1) >= 1) acquire_sem(name.sem) -#define _glthread_UNLOCK_MUTEX(name) if (atomic_add(&(name.lock), -1) > 1) release_sem(name.sem) - -#endif /* BEOS_THREADS */ - - - -#ifndef THREADS - -/* - * THREADS not defined - */ - -typedef GLuint _glthread_TSD; - -typedef GLuint _glthread_Thread; - -typedef GLuint _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 - -#define _glthread_INIT_MUTEX(name) (void) name - -#define _glthread_DESTROY_MUTEX(name) (void) name - -#define _glthread_LOCK_MUTEX(name) (void) name - -#define _glthread_UNLOCK_MUTEX(name) (void) name - -#endif /* THREADS */ - - - -/* - * Platform independent thread specific data API. - */ - -extern unsigned long -_glthread_GetID(void); - - -extern void -_glthread_InitTSD(_glthread_TSD *); - - -extern void * -_glthread_GetTSD(_glthread_TSD *); - - -extern void -_glthread_SetTSD(_glthread_TSD *, void *); - -#if defined(GLX_USE_TLS) - -extern __thread struct _glapi_table * _glapi_tls_Dispatch - __attribute__((tls_model("initial-exec"))); - -#define GET_DISPATCH() _glapi_tls_Dispatch - -#elif !defined(GL_CALL) -# if defined(THREADS) -# define GET_DISPATCH() \ - ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ - ? _glapi_Dispatch : _glapi_get_dispatch()) -# else -# define GET_DISPATCH() _glapi_Dispatch -# endif /* defined(THREADS) */ -#endif /* ndef GL_CALL */ - - -#endif /* THREADS_H */ diff --git a/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c b/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c deleted file mode 100644 index bc13a5761e..0000000000 --- a/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c +++ /dev/null @@ -1,429 +0,0 @@ - -#include "intel_be_batchbuffer.h" -#include "intel_be_context.h" -#include "intel_be_device.h" -#include - -#include "xf86drm.h" - -static void -intel_realloc_relocs(struct intel_be_batchbuffer *batch, int num_relocs) -{ - unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; - - size *= sizeof(uint32_t); - batch->reloc = realloc(batch->reloc, size); - batch->reloc_size = num_relocs; -} - - -void -intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch) -{ - /* - * Get a new, free batchbuffer. - */ - drmBO *bo; - struct drm_bo_info_req *req; - - driBOUnrefUserList(batch->list); - driBOResetList(batch->list); - - /* base.size is the size available to the i915simple driver */ - batch->base.size = batch->device->max_batch_size - BATCH_RESERVED; - batch->base.actual_size = batch->device->max_batch_size; - driBOData(batch->buffer, batch->base.actual_size, NULL, NULL, 0); - - /* - * Add the batchbuffer to the validate list. - */ - - driBOAddListItem(batch->list, batch->buffer, - DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, - &batch->dest_location, &batch->node); - - req = &batch->node->bo_arg.d.req.bo_req; - - /* - * Set up information needed for us to make relocations - * relative to the underlying drm buffer objects. - */ - - driReadLockKernelBO(); - bo = driBOKernel(batch->buffer); - req->presumed_offset = (uint64_t) bo->offset; - req->hint = DRM_BO_HINT_PRESUMED_OFFSET; - batch->drmBOVirtual = (uint8_t *) bo->virtual; - driReadUnlockKernelBO(); - - /* - * Adjust the relocation buffer size. - */ - - if (batch->reloc_size > INTEL_MAX_RELOCS || - batch->reloc == NULL) - intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); - - assert(batch->reloc != NULL); - batch->reloc[0] = 0; /* No relocs yet. */ - batch->reloc[1] = 1; /* Reloc type 1 */ - batch->reloc[2] = 0; /* Only a single relocation list. */ - batch->reloc[3] = 0; /* Only a single relocation list. */ - - batch->base.map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); - batch->poolOffset = driBOPoolOffset(batch->buffer); - batch->base.ptr = batch->base.map; - batch->dirty_state = ~0; - batch->nr_relocs = 0; - batch->flags = 0; - batch->id = 0;//batch->intel->intelScreen->batch_id++; -} - -/*====================================================================== - * Public functions - */ -struct intel_be_batchbuffer * -intel_be_batchbuffer_alloc(struct intel_be_context *intel) -{ - struct intel_be_batchbuffer *batch = calloc(sizeof(*batch), 1); - - batch->intel = intel; - batch->device = intel->device; - - driGenBuffers(intel->device->batchPool, "batchbuffer", 1, - &batch->buffer, 4096, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); - batch->last_fence = NULL; - batch->list = driBOCreateList(20); - batch->reloc = NULL; - intel_be_batchbuffer_reset(batch); - return batch; -} - -void -intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch) -{ - if (batch->last_fence) { - driFenceFinish(batch->last_fence, - DRM_FENCE_TYPE_EXE, FALSE); - driFenceUnReference(&batch->last_fence); - } - if (batch->base.map) { - driBOUnmap(batch->buffer); - batch->base.map = NULL; - } - driBOUnReference(batch->buffer); - driBOFreeList(batch->list); - if (batch->reloc) - free(batch->reloc); - batch->buffer = NULL; - free(batch); -} - -void -intel_be_offset_relocation(struct intel_be_batchbuffer *batch, - unsigned pre_add, - struct _DriBufferObject *driBO, - uint64_t val_flags, - uint64_t val_mask) -{ - int itemLoc; - struct _drmBONode *node; - uint32_t *reloc; - struct drm_bo_info_req *req; - - driBOAddListItem(batch->list, driBO, val_flags, val_mask, - &itemLoc, &node); - req = &node->bo_arg.d.req.bo_req; - - if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { - - /* - * Stop other threads from tampering with the underlying - * drmBO while we're reading its offset. - */ - - driReadLockKernelBO(); - req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; - driReadUnlockKernelBO(); - req->hint = DRM_BO_HINT_PRESUMED_OFFSET; - } - - pre_add += driBOPoolOffset(driBO); - - if (batch->nr_relocs == batch->reloc_size) - intel_realloc_relocs(batch, batch->reloc_size * 2); - - reloc = batch->reloc + - (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); - - reloc[0] = ((uint8_t *)batch->base.ptr - batch->drmBOVirtual); - i915_batchbuffer_dword(&batch->base, req->presumed_offset + pre_add); - reloc[1] = pre_add; - reloc[2] = itemLoc; - reloc[3] = batch->dest_location; - batch->nr_relocs++; -} - -static void -i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) -{ - buf->handle = rep->handle; - buf->flags = rep->flags; - buf->size = rep->size; - buf->offset = rep->offset; - buf->mapHandle = rep->arg_handle; - buf->proposedFlags = rep->proposed_flags; - buf->start = rep->buffer_start; - buf->fenceFlags = rep->fence_flags; - buf->replyFlags = rep->rep_flags; - buf->pageAlignment = rep->page_alignment; -} - -static int -i915_execbuf(struct intel_be_batchbuffer *batch, - unsigned int used, - boolean ignore_cliprects, - drmBOList *list, - struct drm_i915_execbuffer *ea) -{ -// struct intel_be_context *intel = batch->intel; - drmBONode *node; - drmMMListHead *l; - struct drm_i915_op_arg *arg, *first; - struct drm_bo_op_req *req; - struct drm_bo_info_rep *rep; - uint64_t *prevNext = NULL; - drmBO *buf; - int ret = 0; - uint32_t count = 0; - - first = NULL; - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - - arg = &node->bo_arg; - req = &arg->d.req; - - if (!first) - first = arg; - - if (prevNext) - *prevNext = (unsigned long)arg; - - prevNext = &arg->next; - req->bo_req.handle = node->buf->handle; - req->op = drm_bo_validate; - req->bo_req.flags = node->arg0; - req->bo_req.mask = node->arg1; - req->bo_req.hint |= 0; - count++; - } - - memset(ea, 0, sizeof(*ea)); - ea->num_buffers = count; - ea->batch.start = batch->poolOffset; - ea->batch.used = used; -#if 0 /* ZZZ JB: no cliprects used */ - ea->batch.cliprects = intel->pClipRects; - ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; - ea->batch.DR1 = 0; - ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | - (((GLuint) intel->drawY) << 16)); -#else - ea->batch.cliprects = NULL; - ea->batch.num_cliprects = 0; - ea->batch.DR1 = 0; - ea->batch.DR4 = 0; -#endif - ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; - ea->ops_list = (unsigned long) first; - first->reloc_ptr = (unsigned long) batch->reloc; - batch->reloc[0] = batch->nr_relocs; - - //return -EFAULT; - do { - ret = drmCommandWriteRead(batch->device->fd, DRM_I915_EXECBUFFER, ea, - sizeof(*ea)); - } while (ret == -EAGAIN); - - if (ret != 0) - return ret; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - arg = &node->bo_arg; - rep = &arg->d.rep.bo_info; - - if (!arg->handled) { - return -EFAULT; - } - if (arg->d.rep.ret) - return arg->d.rep.ret; - - buf = node->buf; - i915_drm_copy_reply(rep, buf); - } - return 0; -} - -/* TODO: Push this whole function into bufmgr. - */ -static struct _DriFenceObject * -do_flush_locked(struct intel_be_batchbuffer *batch, - unsigned int used, - boolean ignore_cliprects, boolean allow_unlock) -{ - struct intel_be_context *intel = batch->intel; - struct _DriFenceObject *fo; - drmFence fence; - drmBOList *boList; - struct drm_i915_execbuffer ea; - int ret = 0; - - driBOValidateUserList(batch->list); - boList = driGetdrmBOList(batch->list); - -#if 0 /* ZZZ JB Allways run */ - if (!(intel->numClipRects == 0 && !ignore_cliprects)) { -#else - if (1) { -#endif - ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); - } else { - driPutdrmBOList(batch->list); - fo = NULL; - goto out; - } - driPutdrmBOList(batch->list); - if (ret) - abort(); - - if (ea.fence_arg.error != 0) { - - /* - * The hardware has been idled by the kernel. - * Don't fence the driBOs. - */ - - if (batch->last_fence) - driFenceUnReference(&batch->last_fence); -#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ - _mesa_printf("fence error\n"); -#endif - batch->last_fence = NULL; - fo = NULL; - goto out; - } - - fence.handle = ea.fence_arg.handle; - fence.fence_class = ea.fence_arg.fence_class; - fence.type = ea.fence_arg.type; - fence.flags = ea.fence_arg.flags; - fence.signaled = ea.fence_arg.signaled; - - fo = driBOFenceUserList(batch->device->fenceMgr, batch->list, - "SuperFence", &fence); - - if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { - if (batch->last_fence) - driFenceUnReference(&batch->last_fence); - /* - * FIXME: Context last fence?? - */ - batch->last_fence = fo; - driFenceReference(fo); - } - out: -#if 0 /* ZZZ JB: fix this */ - intel->vtbl.lost_hardware(intel); -#else - (void)intel; -#endif - return fo; -} - - -struct _DriFenceObject * -intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch) -{ - struct intel_be_context *intel = batch->intel; - unsigned int used = batch->base.ptr - batch->base.map; - boolean was_locked = batch->intel->hardware_locked(intel); - struct _DriFenceObject *fence; - - if (used == 0) { - driFenceReference(batch->last_fence); - return batch->last_fence; - } - - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a - * performance drain that we would like to avoid. - */ -#if 0 /* ZZZ JB: what should we do here? */ - if (used & 4) { - ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->base.ptr)[1] = 0; - ((int *) batch->base.ptr)[2] = MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->base.ptr)[1] = MI_BATCH_BUFFER_END; - used += 8; - } -#else - if (used & 4) { - ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->base.ptr)[1] = 0; - ((int *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; - used += 8; - } -#endif - driBOUnmap(batch->buffer); - batch->base.ptr = NULL; - batch->base.map = NULL; - - /* TODO: Just pass the relocation list and dma buffer up to the - * kernel. - */ - if (!was_locked) - intel->hardware_lock(intel); - - fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), - FALSE); - - if (!was_locked) - intel->hardware_unlock(intel); - - /* Reset the buffer: - */ - intel_be_batchbuffer_reset(batch); - return fence; -} - -void -intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch) -{ - struct _DriFenceObject *fence = intel_be_batchbuffer_flush(batch); - driFenceFinish(fence, driFenceType(fence), FALSE); - driFenceUnReference(&fence); -} - -#if 0 -void -intel_be_batchbuffer_data(struct intel_be_batchbuffer *batch, - const void *data, unsigned int bytes, unsigned int flags) -{ - assert((bytes & 3) == 0); - intel_batchbuffer_require_space(batch, bytes, flags); - memcpy(batch->base.ptr, data, bytes); - batch->base.ptr += bytes; -} -#endif diff --git a/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h b/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h deleted file mode 100644 index f150e3a674..0000000000 --- a/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h +++ /dev/null @@ -1,69 +0,0 @@ - -#ifndef INTEL_BE_BATCHBUFFER_H -#define INTEL_BE_BATCHBUFFER_H - -#include "i915simple/i915_batch.h" - -#include "ws_dri_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_batchbuffer -{ - struct i915_batchbuffer base; - - struct intel_be_context *intel; - struct intel_be_device *device; - - struct _DriBufferObject *buffer; - struct _DriFenceObject *last_fence; - uint32_t flags; - - struct _DriBufferList *list; - size_t list_count; - - uint32_t *reloc; - size_t reloc_size; - size_t nr_relocs; - - uint32_t dirty_state; - uint32_t id; - - uint32_t poolOffset; - uint8_t *drmBOVirtual; - struct _drmBONode *node; /* Validation list node for this buffer */ - int dest_location; /* Validation list sequence for this buffer */ -}; - -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); - -struct _DriFenceObject * -intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch); - -void -intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch); - -void -intel_be_offset_relocation(struct intel_be_batchbuffer *batch, - unsigned pre_add, - struct _DriBufferObject *driBO, - uint64_t val_flags, - uint64_t val_mask); - -#endif diff --git a/src/gallium/winsys/common/intel_drm/intel_be_context.c b/src/gallium/winsys/common/intel_drm/intel_be_context.c deleted file mode 100644 index 1af39674f4..0000000000 --- a/src/gallium/winsys/common/intel_drm/intel_be_context.c +++ /dev/null @@ -1,107 +0,0 @@ - -/* - * Authors: Jakob Bornecrantz - */ - -#include "ws_dri_fencemgr.h" -#include "intel_be_device.h" -#include "intel_be_context.h" -#include "intel_be_batchbuffer.h" - -static INLINE struct intel_be_context * -intel_be_context(struct i915_winsys *sws) -{ - return (struct intel_be_context *)sws; -} - -/* Simple batchbuffer interface: - */ - -static struct i915_batchbuffer* -intel_i915_batch_get(struct i915_winsys *sws) -{ - struct intel_be_context *intel = intel_be_context(sws); - return &intel->batch->base; -} - -static void intel_i915_batch_reloc(struct i915_winsys *sws, - struct pipe_buffer *buf, - unsigned access_flags, - unsigned delta) -{ - struct intel_be_context *intel = intel_be_context(sws); - - unsigned flags = DRM_BO_FLAG_MEM_TT; - unsigned mask = DRM_BO_MASK_MEM; - - if (access_flags & I915_BUFFER_ACCESS_WRITE) { - flags |= DRM_BO_FLAG_WRITE; - mask |= DRM_BO_FLAG_WRITE; - } - - if (access_flags & I915_BUFFER_ACCESS_READ) { - flags |= DRM_BO_FLAG_READ; - mask |= DRM_BO_FLAG_READ; - } - - intel_be_offset_relocation(intel->batch, - delta, - dri_bo(buf), - flags, - mask); -} - -static void intel_i915_batch_flush(struct i915_winsys *sws, - struct pipe_fence_handle **fence) -{ - struct intel_be_context *intel = intel_be_context(sws); - - union { - struct _DriFenceObject *dri; - struct pipe_fence_handle *pipe; - } fu; - - if (fence) - assert(!*fence); - - fu.dri = intel_be_batchbuffer_flush(intel->batch); - - if (!fu.dri) { - assert(0); - *fence = NULL; - return; - } - - if (fu.dri) { - if (fence) - *fence = fu.pipe; - else - driFenceUnReference(&fu.dri); - } - -} - -boolean -intel_be_init_context(struct intel_be_context *intel, struct intel_be_device *device) -{ - assert(intel); - assert(device); - - intel->device = device; - - /* TODO move framebuffer createion to the driver */ - - intel->base.batch_get = intel_i915_batch_get; - intel->base.batch_reloc = intel_i915_batch_reloc; - intel->base.batch_flush = intel_i915_batch_flush; - - intel->batch = intel_be_batchbuffer_alloc(intel); - - return true; -} - -void -intel_be_destroy_context(struct intel_be_context *intel) -{ - intel_be_batchbuffer_free(intel->batch); -} diff --git a/src/gallium/winsys/common/intel_drm/intel_be_context.h b/src/gallium/winsys/common/intel_drm/intel_be_context.h deleted file mode 100644 index d5cbc93594..0000000000 --- a/src/gallium/winsys/common/intel_drm/intel_be_context.h +++ /dev/null @@ -1,40 +0,0 @@ -/* These need to be diffrent from the intel winsys */ -#ifndef INTEL_BE_CONTEXT_H -#define INTEL_BE_CONTEXT_H - -#include "i915simple/i915_winsys.h" - -struct intel_be_context -{ - /** Interface to i915simple driver */ - struct i915_winsys base; - - struct intel_be_device *device; - struct intel_be_batchbuffer *batch; - - /* - * Hardware lock functions. - * - * Needs to be filled in by the winsys. - */ - void (*hardware_lock)(struct intel_be_context *context); - void (*hardware_unlock)(struct intel_be_context *context); - boolean (*hardware_locked)(struct intel_be_context *context); -}; - -/** - * Intialize a allocated intel_be_context struct. - * - * Remember to set the hardware_* functions. - */ -boolean -intel_be_init_context(struct intel_be_context *intel, - struct intel_be_device *device); - -/** - * Destroy a intel_be_context. - * Does not free the struct that is up to the winsys. - */ -void -intel_be_destroy_context(struct intel_be_context *intel); -#endif diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c deleted file mode 100644 index 8db0329615..0000000000 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.c +++ /dev/null @@ -1,308 +0,0 @@ - - -/* - * Authors: Keith Whitwell - * Jakob Bornecrantz - */ - -#include "intel_be_device.h" -#include "ws_dri_bufmgr.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" - -#include "pipe/p_winsys.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" - -#include "i915simple/i915_screen.h" - -/* Turn a pipe winsys into an intel/pipe winsys: - */ -static INLINE struct intel_be_device * -intel_be_device( struct pipe_winsys *winsys ) -{ - return (struct intel_be_device *)winsys; -} - - -/* - * Buffer functions. - * - * Most callbacks map direcly onto dri_bufmgr operations: - */ - -static void *intel_be_buffer_map(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned flags ) -{ - unsigned drm_flags = 0; - - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) - drm_flags |= DRM_BO_FLAG_WRITE; - - if (flags & PIPE_BUFFER_USAGE_CPU_READ) - drm_flags |= DRM_BO_FLAG_READ; - - return driBOMap( dri_bo(buf), drm_flags, 0 ); -} - -static void intel_be_buffer_unmap(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - driBOUnmap( dri_bo(buf) ); -} - -static void -intel_be_buffer_destroy(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - driBOUnReference( dri_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 *iws = intel_be_device(winsys); - unsigned flags = 0; - struct _DriBufferPool *pool; - - buffer->base.refcount = 1; - buffer->base.alignment = alignment; - buffer->base.usage = usage; - buffer->base.size = size; - - if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { - flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; - pool = iws->mallocPool; - } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { - /* For vertex buffers */ - flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; - pool = iws->vertexPool; - } else { - flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; - pool = iws->regionPool; - } - - if (usage & PIPE_BUFFER_USAGE_GPU_READ) - flags |= DRM_BO_FLAG_READ; - - if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) - flags |= DRM_BO_FLAG_WRITE; - - /* drm complains if we don't set any read/write flags. - */ - if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) - flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - - buffer->pool = pool; - driGenBuffers( buffer->pool, - "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); - - driBOData( buffer->driBO, size, NULL, buffer->pool, 0 ); - - return &buffer->base; -} - - -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 *iws = intel_be_device(winsys); - - driGenUserBuffer( iws->regionPool, - "pipe user buffer", &buffer->driBO, ptr, bytes ); - - buffer->base.refcount = 1; - - return &buffer->base; -} - -struct pipe_buffer * -intel_be_buffer_from_handle(struct intel_be_device *device, - const char* name, unsigned handle) -{ - struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); - struct pipe_buffer *buffer; - - if (!be_buf) - goto err; - - memset(be_buf, 0, sizeof(*be_buf)); - - driGenBuffers(device->staticPool, name, 1, &be_buf->driBO, 0, 0, 0); - driBOSetReferenced(be_buf->driBO, handle); - - if (0) /** XXX TODO check error */ - goto err_bo; - - buffer = &be_buf->base; - buffer->refcount = 1; - buffer->alignment = 0; - buffer->usage = 0; - buffer->size = driBOSize(be_buf->driBO); - - return buffer; -err_bo: - free(be_buf); -err: - return NULL; -} - - -/* - * Surface functions. - * - * Deprecated! - */ - -static struct pipe_surface * -intel_i915_surface_alloc(struct pipe_winsys *winsys) -{ - assert((size_t)"intel_i915_surface_alloc is deprecated" & 0); - return NULL; -} - -static int -intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, - unsigned width, unsigned height, - enum pipe_format format, - unsigned flags, - unsigned tex_usage) -{ - assert((size_t)"intel_i915_surface_alloc_storage is deprecated" & 0); - return -1; -} - -static void -intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - assert((size_t)"intel_i915_surface_release is deprecated" & 0); -} - - -/* - * Fence functions - */ - -static void -intel_be_fence_reference( struct pipe_winsys *sws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence ) -{ - if (*ptr) - driFenceUnReference((struct _DriFenceObject **)ptr); - - if (fence) - *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); -} - -static int -intel_be_fence_signalled( struct pipe_winsys *sws, - struct pipe_fence_handle *fence, - unsigned flag ) -{ - return driFenceSignaled((struct _DriFenceObject *)fence, flag); -} - -static int -intel_be_fence_finish( struct pipe_winsys *sws, - struct pipe_fence_handle *fence, - unsigned flag ) -{ - return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); -} - - -/* - * Misc functions - */ - -boolean -intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id) -{ - dev->fd = fd; - dev->max_batch_size = 16 * 4096; - dev->max_vertex_size = 128 * 4096; - - dev->base.buffer_create = intel_be_buffer_create; - dev->base.user_buffer_create = intel_be_user_buffer_create; - dev->base.buffer_map = intel_be_buffer_map; - dev->base.buffer_unmap = intel_be_buffer_unmap; - dev->base.buffer_destroy = intel_be_buffer_destroy; - dev->base.surface_alloc = intel_i915_surface_alloc; - dev->base.surface_alloc_storage = intel_i915_surface_alloc_storage; - dev->base.surface_release = intel_i915_surface_release; - dev->base.fence_reference = intel_be_fence_reference; - dev->base.fence_signalled = intel_be_fence_signalled; - dev->base.fence_finish = intel_be_fence_finish; - -#if 0 /* Set by the winsys */ - dev->base.flush_frontbuffer = intel_flush_frontbuffer; - dev->base.get_name = intel_get_name; -#endif - - dev->fMan = driInitFreeSlabManager(10, 10); - dev->fenceMgr = driFenceMgrTTMInit(dev->fd); - - dev->mallocPool = driMallocPoolInit(); - dev->staticPool = driDRMPoolInit(dev->fd); - /* Sizes: 64 128 256 512 1024 2048 4096 8192 16384 32768 */ - dev->regionPool = driSlabPoolInit(dev->fd, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - 64, - 10, 120, 4096 * 64, 0, - dev->fMan); - - dev->vertexPool = driSlabPoolInit(dev->fd, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - dev->max_vertex_size, - 1, 120, dev->max_vertex_size * 4, 0, - dev->fMan); - - dev->batchPool = driSlabPoolInit(dev->fd, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - dev->max_batch_size, - 1, 40, dev->max_batch_size * 16, 0, - dev->fMan); - - /* Fill in this struct with callbacks that i915simple will need to - * communicate with the window system, buffer manager, etc. - */ - dev->screen = i915_create_screen(&dev->base, id); - - return true; -} - -void -intel_be_destroy_device(struct intel_be_device *dev) -{ - driPoolTakeDown(dev->mallocPool); - driPoolTakeDown(dev->staticPool); - driPoolTakeDown(dev->regionPool); - driPoolTakeDown(dev->vertexPool); - driPoolTakeDown(dev->batchPool); - - /** TODO takedown fenceMgr and fMan */ -} diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.h b/src/gallium/winsys/common/intel_drm/intel_be_device.h deleted file mode 100644 index 3f8b3f585c..0000000000 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef INTEL_DRM_DEVICE_H -#define INTEL_DRM_DEVICE_H - -#include "pipe/p_winsys.h" -#include "pipe/p_context.h" - -/* - * Device - */ - -struct intel_be_device -{ - struct pipe_winsys base; - - /** - * Hw level screen - */ - struct pipe_screen *screen; - - int fd; /**< Drm file discriptor */ - - size_t max_batch_size; - size_t max_vertex_size; - - struct _DriFenceMgr *fenceMgr; - - struct _DriBufferPool *batchPool; - struct _DriBufferPool *regionPool; - struct _DriBufferPool *mallocPool; - struct _DriBufferPool *vertexPool; - struct _DriBufferPool *staticPool; - struct _DriFreeSlabManager *fMan; -}; - -boolean -intel_be_init_device(struct intel_be_device *device, int fd, unsigned id); - -void -intel_be_destroy_device(struct intel_be_device *dev); - -/* - * Buffer - */ - -struct intel_be_buffer { - struct pipe_buffer base; - struct _DriBufferPool *pool; - struct _DriBufferObject *driBO; -}; - -/** - * Create a be buffer from a drm bo handle - * - * Takes a reference - */ -struct pipe_buffer * -intel_be_buffer_from_handle(struct intel_be_device *device, - const char* name, unsigned handle); - -static INLINE struct intel_be_buffer * -intel_be_buffer(struct pipe_buffer *buf) -{ - return (struct intel_be_buffer *)buf; -} - -static INLINE struct _DriBufferObject * -dri_bo(struct pipe_buffer *buf) -{ - return intel_be_buffer(buf)->driBO; -} - -#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c b/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c deleted file mode 100644 index b6d901f85e..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c +++ /dev/null @@ -1,949 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - * Keith Whitwell - */ - -#include -#include -#include -#include "glthread.h" -#include "errno.h" -#include "ws_dri_bufmgr.h" -#include "string.h" -#include "pipe/p_debug.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" - - -/* - * This lock is here to protect drmBO structs changing underneath us during a - * validate list call, since validatelist cannot take individiual locks for - * each drmBO. Validatelist takes this lock in write mode. Any access to an - * individual drmBO should take this lock in read mode, since in that case, the - * driBufferObject mutex will protect the access. Locking order is - * driBufferObject mutex - > this rw lock. - */ - -_glthread_DECLARE_STATIC_MUTEX(bmMutex); -_glthread_DECLARE_STATIC_COND(bmCond); - -static int kernelReaders = 0; -static int num_buffers = 0; -static int num_user_buffers = 0; - -static drmBO *drmBOListBuf(void *iterator) -{ - drmBONode *node; - drmMMListHead *l = (drmMMListHead *) iterator; - node = DRMLISTENTRY(drmBONode, l, head); - return node->buf; -} - -static void *drmBOListIterator(drmBOList *list) -{ - void *ret = list->list.next; - - if (ret == &list->list) - return NULL; - return ret; -} - -static void *drmBOListNext(drmBOList *list, void *iterator) -{ - void *ret; - - drmMMListHead *l = (drmMMListHead *) iterator; - ret = l->next; - if (ret == &list->list) - return NULL; - return ret; -} - -static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, - uint64_t arg0, - uint64_t arg1) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->free.next; - if (l == &list->free) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - return NULL; - } - list->numCurrent++; - } - else { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - } - node->buf = item; - node->arg0 = arg0; - node->arg1 = arg1; - DRMLISTADD(&node->head, &list->list); - list->numOnList++; - return node; -} - -static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, - uint64_t mask, int *newItem) -{ - drmBONode *node, *cur; - drmMMListHead *l; - - *newItem = 0; - cur = NULL; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - if (node->buf == buf) { - cur = node; - break; - } - } - if (!cur) { - cur = drmAddListItem(list, buf, flags, mask); - if (!cur) { - return -ENOMEM; - } - *newItem = 1; - cur->arg0 = flags; - cur->arg1 = mask; - } - else { - uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; - uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; - - if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { - return -EINVAL; - } - - cur->arg1 |= mask; - cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); - - if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && - (cur->arg0 & DRM_BO_MASK_MEM) == 0) { - return -EINVAL; - } - } - return 0; -} - -static void drmBOFreeList(drmBOList *list) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->list.next; - while(l != &list->list) { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - l = list->list.next; - list->numCurrent--; - list->numOnList--; - } - - l = list->free.next; - while(l != &list->free) { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - l = list->free.next; - list->numCurrent--; - } -} - -static int drmAdjustListNodes(drmBOList *list) -{ - drmBONode *node; - drmMMListHead *l; - int ret = 0; - - while(list->numCurrent < list->numTarget) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - ret = -ENOMEM; - break; - } - list->numCurrent++; - DRMLISTADD(&node->head, &list->free); - } - - while(list->numCurrent > list->numTarget) { - l = list->free.next; - if (l == &list->free) - break; - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - list->numCurrent--; - } - return ret; -} - -static int drmBOCreateList(int numTarget, drmBOList *list) -{ - DRMINITLISTHEAD(&list->list); - DRMINITLISTHEAD(&list->free); - list->numTarget = numTarget; - list->numCurrent = 0; - list->numOnList = 0; - return drmAdjustListNodes(list); -} - -static int drmBOResetList(drmBOList *list) -{ - drmMMListHead *l; - int ret; - - ret = drmAdjustListNodes(list); - if (ret) - return ret; - - l = list->list.next; - while (l != &list->list) { - DRMLISTDEL(l); - DRMLISTADD(l, &list->free); - list->numOnList--; - l = list->list.next; - } - return drmAdjustListNodes(list); -} - -void driWriteLockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - while(kernelReaders != 0) - _glthread_COND_WAIT(bmCond, bmMutex); -} - -void driWriteUnlockKernelBO(void) -{ - _glthread_UNLOCK_MUTEX(bmMutex); -} - -void driReadLockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - kernelReaders++; - _glthread_UNLOCK_MUTEX(bmMutex); -} - -void driReadUnlockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - if (--kernelReaders == 0) - _glthread_COND_BROADCAST(bmCond); - _glthread_UNLOCK_MUTEX(bmMutex); -} - - - - -/* - * TODO: Introduce fence pools in the same way as - * buffer object pools. - */ - -typedef struct _DriBufferObject -{ - DriBufferPool *pool; - _glthread_Mutex mutex; - int refCount; - const char *name; - uint64_t flags; - unsigned hint; - unsigned alignment; - unsigned createdByReference; - void *private; - /* user-space buffer: */ - unsigned userBuffer; - void *userData; - unsigned userSize; -} DriBufferObject; - -typedef struct _DriBufferList { - drmBOList drmBuffers; /* List of kernel buffers needing validation */ - drmBOList driBuffers; /* List of user-space buffers needing validation */ -} DriBufferList; - - -void -bmError(int val, const char *file, const char *function, int line) -{ - printf("Fatal video memory manager error \"%s\".\n" - "Check kernel logs or set the LIBGL_DEBUG\n" - "environment variable to \"verbose\" for more info.\n" - "Detected in file %s, line %d, function %s.\n", - strerror(-val), file, line, function); -#ifndef NDEBUG - abort(); -#else - abort(); -#endif -} - -extern drmBO * -driBOKernel(struct _DriBufferObject *buf) -{ - drmBO *ret; - - driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); - assert(buf->private != NULL); - ret = buf->pool->kernel(buf->pool, buf->private); - if (!ret) - BM_CKFATAL(-EINVAL); - _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); - - return ret; -} - -void -driBOWaitIdle(struct _DriBufferObject *buf, int lazy) -{ - - /* - * This function may block. Is it sane to keep the mutex held during - * that time?? - */ - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void * -driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) -{ - void *virtual; - int retval; - - if (buf->userBuffer) { - return buf->userData; - } - - _glthread_LOCK_MUTEX(buf->mutex); - assert(buf->private != NULL); - retval = buf->pool->map(buf->pool, buf->private, flags, hint, - &buf->mutex, &virtual); - _glthread_UNLOCK_MUTEX(buf->mutex); - - return retval == 0 ? virtual : NULL; -} - -void -driBOUnmap(struct _DriBufferObject *buf) -{ - if (buf->userBuffer) - return; - - assert(buf->private != NULL); - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -unsigned long -driBOOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->offset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -unsigned long -driBOPoolOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->poolOffset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -uint64_t -driBOFlags(struct _DriBufferObject *buf) -{ - uint64_t ret; - - assert(buf->private != NULL); - - driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->flags(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); - return ret; -} - -struct _DriBufferObject * -driBOReference(struct _DriBufferObject *buf) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (++buf->refCount == 1) { - _glthread_UNLOCK_MUTEX(buf->mutex); - BM_CKFATAL(-EINVAL); - } - _glthread_UNLOCK_MUTEX(buf->mutex); - return buf; -} - -void -driBOUnReference(struct _DriBufferObject *buf) -{ - int tmp; - - if (!buf) - return; - - _glthread_LOCK_MUTEX(buf->mutex); - tmp = --buf->refCount; - if (!tmp) { - _glthread_UNLOCK_MUTEX(buf->mutex); - if (buf->private) { - if (buf->createdByReference) - buf->pool->unreference(buf->pool, buf->private); - else - buf->pool->destroy(buf->pool, buf->private); - } - if (buf->userBuffer) - num_user_buffers--; - else - num_buffers--; - free(buf); - } else - _glthread_UNLOCK_MUTEX(buf->mutex); - -} - - -int -driBOData(struct _DriBufferObject *buf, - unsigned size, const void *data, - DriBufferPool *newPool, - uint64_t flags) -{ - void *virtual = NULL; - int newBuffer; - int retval = 0; - struct _DriBufferPool *pool; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - pool = buf->pool; - - if (pool == NULL && newPool != NULL) { - buf->pool = newPool; - pool = newPool; - } - if (newPool == NULL) - newPool = pool; - - if (!pool->create) { - assert((size_t)"driBOData called on invalid buffer\n" & 0); - BM_CKFATAL(-EINVAL); - } - - newBuffer = (!buf->private || pool != newPool || - pool->size(pool, buf->private) < size); - - if (!flags) - flags = buf->flags; - - if (newBuffer) { - - if (buf->createdByReference) { - assert((size_t)"driBOData requiring resizing called on shared buffer.\n" & 0); - BM_CKFATAL(-EINVAL); - } - - if (buf->private) - buf->pool->destroy(buf->pool, buf->private); - - pool = newPool; - buf->pool = newPool; - buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, - buf->alignment); - if (!buf->private) - retval = -ENOMEM; - - if (retval == 0) - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); - } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { - /* - * Buffer is busy. need to create a new one. - */ - - void *newBuf; - - newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, - buf->alignment); - if (newBuf) { - buf->pool->destroy(buf->pool, buf->private); - buf->private = newBuf; - } - - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } else { - uint64_t flag_diff = flags ^ buf->flags; - - /* - * We might need to change buffer flags. - */ - - if (flag_diff){ - assert(pool->setStatus != NULL); - BM_CKFATAL(pool->unmap(pool, buf->private)); - BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, - buf->flags)); - if (!data) - goto out; - - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } - } - - if (retval == 0) { - if (data) - memcpy(virtual, data, size); - - BM_CKFATAL(pool->unmap(pool, buf->private)); - } - - out: - _glthread_UNLOCK_MUTEX(buf->mutex); - - return retval; -} - -void -driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, const void *data) -{ - void *virtual; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, - &virtual)); - memcpy((unsigned char *) virtual + offset, data, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, void *data) -{ - void *virtual; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); - memcpy(data, (unsigned char *) virtual + offset, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOSetReferenced(struct _DriBufferObject *buf, - unsigned long handle) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->private != NULL) { - assert((size_t)"Invalid buffer for setReferenced\n" & 0); - BM_CKFATAL(-EINVAL); - - } - if (buf->pool->reference == NULL) { - assert((size_t)"Invalid buffer pool for setReferenced\n" & 0); - BM_CKFATAL(-EINVAL); - } - buf->private = buf->pool->reference(buf->pool, handle); - if (!buf->private) { - assert((size_t)"Invalid buffer pool for setStatic\n" & 0); - BM_CKFATAL(-ENOMEM); - } - buf->createdByReference = TRUE; - buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -int -driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, uint64_t flags, unsigned hint) -{ - struct _DriBufferObject *buf; - int i; - - flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - - ++num_buffers; - - assert(pool); - - for (i = 0; i < n; ++i) { - buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); - if (!buf) - return -ENOMEM; - - _glthread_INIT_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(buf->mutex); - buf->refCount = 1; - buf->flags = flags; - buf->hint = hint; - buf->name = name; - buf->alignment = alignment; - buf->pool = pool; - buf->createdByReference = 0; - _glthread_UNLOCK_MUTEX(buf->mutex); - buffers[i] = buf; - } - return 0; -} - -void -driGenUserBuffer(struct _DriBufferPool *pool, - const char *name, - struct _DriBufferObject **buffers, - void *ptr, unsigned bytes) -{ - const unsigned alignment = 1, flags = 0, hint = 0; - - --num_buffers; /* JB: is inced in GenBuffes */ - driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); - ++num_user_buffers; - - (*buffers)->userBuffer = 1; - (*buffers)->userData = ptr; - (*buffers)->userSize = bytes; -} - -void -driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) -{ - int i; - - for (i = 0; i < n; ++i) { - driBOUnReference(buffers[i]); - } -} - - -void -driInitBufMgr(int fd) -{ - ; -} - -/* - * Note that lists are per-context and don't need mutex protection. - */ - -struct _DriBufferList * -driBOCreateList(int target) -{ - struct _DriBufferList *list = calloc(sizeof(*list), 1); - - BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); - BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); - return list; -} - -int -driBOResetList(struct _DriBufferList * list) -{ - int ret; - ret = drmBOResetList(&list->drmBuffers); - if (ret) - return ret; - ret = drmBOResetList(&list->driBuffers); - return ret; -} - -void -driBOFreeList(struct _DriBufferList * list) -{ - drmBOFreeList(&list->drmBuffers); - drmBOFreeList(&list->driBuffers); - free(list); -} - - -/* - * Copied from libdrm, because it is needed by driAddValidateItem. - */ - -static drmBONode * -driAddListItem(drmBOList * list, drmBO * item, - uint64_t arg0, uint64_t arg1) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->free.next; - if (l == &list->free) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - return NULL; - } - list->numCurrent++; - } else { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - } - memset(&node->bo_arg, 0, sizeof(node->bo_arg)); - node->buf = item; - node->arg0 = arg0; - node->arg1 = arg1; - DRMLISTADDTAIL(&node->head, &list->list); - list->numOnList++; - return node; -} - -/* - * Slightly modified version compared to the libdrm version. - * This one returns the list index of the buffer put on the list. - */ - -static int -driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, - uint64_t mask, int *itemLoc, - struct _drmBONode **pnode) -{ - drmBONode *node, *cur; - drmMMListHead *l; - int count = 0; - - cur = NULL; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - if (node->buf == buf) { - cur = node; - break; - } - count++; - } - if (!cur) { - cur = driAddListItem(list, buf, flags, mask); - if (!cur) - return -ENOMEM; - - cur->arg0 = flags; - cur->arg1 = mask; - } else { - uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; - uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; - - if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { - return -EINVAL; - } - - cur->arg1 |= mask; - cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); - - if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && - (cur->arg0 & DRM_BO_MASK_MEM) == 0) { - return -EINVAL; - } - } - *itemLoc = count; - *pnode = cur; - return 0; -} - - -void -driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, - uint64_t flags, uint64_t mask, int *itemLoc, - struct _drmBONode **node) -{ - int newItem; - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(driAddValidateItem(&list->drmBuffers, - buf->pool->kernel(buf->pool, buf->private), - flags, mask, itemLoc, node)); - BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, - flags, mask, &newItem)); - if (newItem) - buf->refCount++; - - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -drmBOList *driGetdrmBOList(struct _DriBufferList *list) -{ - driWriteLockKernelBO(); - return &list->drmBuffers; -} - -void driPutdrmBOList(struct _DriBufferList *list) -{ - driWriteUnlockKernelBO(); -} - - -void -driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->pool->fence) - BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); - _glthread_UNLOCK_MUTEX(buf->mutex); - -} - -void -driBOUnrefUserList(struct _DriBufferList *list) -{ - struct _DriBufferObject *buf; - void *curBuf; - - curBuf = drmBOListIterator(&list->driBuffers); - while (curBuf) { - buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); - driBOUnReference(buf); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } -} - -struct _DriFenceObject * -driBOFenceUserList(struct _DriFenceMgr *mgr, - struct _DriBufferList *list, const char *name, - drmFence *kFence) -{ - struct _DriFenceObject *fence; - struct _DriBufferObject *buf; - void *curBuf; - - fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, - kFence, sizeof(*kFence)); - curBuf = drmBOListIterator(&list->driBuffers); - - /* - * User-space fencing callbacks. - */ - - while (curBuf) { - buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - driBOFence(buf, fence); - driBOUnReference(buf); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } - - driBOResetList(list); - return fence; -} - -void -driBOValidateUserList(struct _DriBufferList * list) -{ - void *curBuf; - struct _DriBufferObject *buf; - - curBuf = drmBOListIterator(&list->driBuffers); - - /* - * User-space validation callbacks. - */ - - while (curBuf) { - buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->pool->validate) - BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); - _glthread_UNLOCK_MUTEX(buf->mutex); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } -} - - -void -driPoolTakeDown(struct _DriBufferPool *pool) -{ - pool->takeDown(pool); - -} - -unsigned long -driBOSize(struct _DriBufferObject *buf) -{ - unsigned long size; - - _glthread_LOCK_MUTEX(buf->mutex); - size = buf->pool->size(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - - return size; - -} - -drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) -{ - return &list->drmBuffers; -} - -drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) -{ - return &list->driBuffers; -} - diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h b/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h deleted file mode 100644 index e6c0cff0a0..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - * Keith Whitwell - */ - -#ifndef _PSB_BUFMGR_H_ -#define _PSB_BUFMGR_H_ -#include -#include "i915_drm.h" -#include "ws_dri_fencemgr.h" - -typedef struct _drmBONode -{ - drmMMListHead head; - drmBO *buf; - struct drm_i915_op_arg bo_arg; - uint64_t arg0; - uint64_t arg1; -} drmBONode; - -typedef struct _drmBOList { - unsigned numTarget; - unsigned numCurrent; - unsigned numOnList; - drmMMListHead list; - drmMMListHead free; -} drmBOList; - - -struct _DriFenceObject; -struct _DriBufferObject; -struct _DriBufferPool; -struct _DriBufferList; - -/* - * Return a pointer to the libdrm buffer object this DriBufferObject - * uses. - */ - -extern drmBO *driBOKernel(struct _DriBufferObject *buf); -extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, - unsigned hint); -extern void driBOUnmap(struct _DriBufferObject *buf); -extern unsigned long driBOOffset(struct _DriBufferObject *buf); -extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); - -extern uint64_t driBOFlags(struct _DriBufferObject *buf); -extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); -extern void driBOUnReference(struct _DriBufferObject *buf); - -extern int driBOData(struct _DriBufferObject *r_buf, - unsigned size, const void *data, - struct _DriBufferPool *pool, uint64_t flags); - -extern void driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - const void *data); -extern void driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - void *data); -extern int driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, uint64_t flags, unsigned hint); -extern void driGenUserBuffer(struct _DriBufferPool *pool, - const char *name, - struct _DriBufferObject *buffers[], - void *ptr, unsigned bytes); -extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); -extern void driInitBufMgr(int fd); -extern struct _DriBufferList *driBOCreateList(int target); -extern int driBOResetList(struct _DriBufferList * list); -extern void driBOAddListItem(struct _DriBufferList * list, - struct _DriBufferObject *buf, - uint64_t flags, uint64_t mask, int *itemLoc, - struct _drmBONode **node); - -extern void driBOValidateList(int fd, struct _DriBufferList * list); -extern void driBOFreeList(struct _DriBufferList * list); -extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, - struct _DriBufferList *list, - const char *name, - drmFence *kFence); -extern void driBOUnrefUserList(struct _DriBufferList *list); -extern void driBOValidateUserList(struct _DriBufferList * list); -extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); -extern void driPutdrmBOList(struct _DriBufferList *list); - -extern void driBOFence(struct _DriBufferObject *buf, - struct _DriFenceObject *fence); - -extern void driPoolTakeDown(struct _DriBufferPool *pool); -extern void driBOSetReferenced(struct _DriBufferObject *buf, - unsigned long handle); -unsigned long driBOSize(struct _DriBufferObject *buf); -extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); -extern void driPoolTakeDown(struct _DriBufferPool *pool); - -extern void driReadLockKernelBO(void); -extern void driReadUnlockKernelBO(void); -extern void driWriteLockKernelBO(void); -extern void driWriteUnlockKernelBO(void); - -/* - * For debugging purposes. - */ - -extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); -extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); -#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h b/src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h deleted file mode 100644 index bf60798924..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - */ - -#ifndef _PSB_BUFPOOL_H_ -#define _PSB_BUFPOOL_H_ - -#include -#include -struct _DriFenceObject; - -typedef struct _DriBufferPool -{ - int fd; - int (*map) (struct _DriBufferPool * pool, void *private, - unsigned flags, int hint, _glthread_Mutex *mutex, - void **virtual); - int (*unmap) (struct _DriBufferPool * pool, void *private); - int (*destroy) (struct _DriBufferPool * pool, void *private); - unsigned long (*offset) (struct _DriBufferPool * pool, void *private); - unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); - uint64_t (*flags) (struct _DriBufferPool * pool, void *private); - unsigned long (*size) (struct _DriBufferPool * pool, void *private); - void *(*create) (struct _DriBufferPool * pool, unsigned long size, - uint64_t flags, unsigned hint, unsigned alignment); - void *(*reference) (struct _DriBufferPool * pool, unsigned handle); - int (*unreference) (struct _DriBufferPool * pool, void *private); - int (*fence) (struct _DriBufferPool * pool, void *private, - struct _DriFenceObject * fence); - drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); - int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); - int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, - int lazy); - int (*setStatus) (struct _DriBufferPool *pool, void *private, - uint64_t flag_diff, uint64_t old_flags); - void (*takeDown) (struct _DriBufferPool * pool); - void *data; -} DriBufferPool; - -extern void bmError(int val, const char *file, const char *function, - int line); -#define BM_CKFATAL(val) \ - do{ \ - int tstVal = (val); \ - if (tstVal) \ - bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ - } while(0); - - -/* - * Builtin pools. - */ - -/* - * Kernel buffer objects. Size in multiples of page size. Page size aligned. - */ - -extern struct _DriBufferPool *driDRMPoolInit(int fd); -extern struct _DriBufferPool *driMallocPoolInit(void); - -struct _DriFreeSlabManager; -extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, - uint64_t validMask, - uint32_t smallestSize, - uint32_t numSizes, - uint32_t desiredNumBuffers, - uint32_t maxSlabSize, - uint32_t pageAlignment, - struct _DriFreeSlabManager *fMan); -extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); -extern struct _DriFreeSlabManager * -driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); - - -#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c b/src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c deleted file mode 100644 index 40929efa2f..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c +++ /dev/null @@ -1,268 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - */ - -#include -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" -#include "assert.h" - -/* - * Buffer pool implementation using DRM buffer objects as DRI buffer objects. - */ - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, uint64_t flags, unsigned hint, - unsigned alignment) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - unsigned pageSize = getpagesize(); - - if (!buf) - return NULL; - - if ((alignment > pageSize) && (alignment % pageSize)) { - free(buf); - return NULL; - } - - ret = drmBOCreate(pool->fd, size, alignment / pageSize, - NULL, - flags, hint, buf); - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static void * -pool_reference(struct _DriBufferPool *pool, unsigned handle) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - - if (!buf) - return NULL; - - ret = drmBOReference(pool->fd, handle, buf); - - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); - ret = drmBOUnreference(pool->fd, buf); - free(buf); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_unreference(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); - ret = drmBOUnreference(pool->fd, buf); - free(buf); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOMap(pool->fd, buf, flags, hint, virtual); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOUnmap(pool->fd, buf); - driReadUnlockKernelBO(); - - return ret; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - unsigned long offset; - - driReadLockKernelBO(); - assert(buf->flags & DRM_BO_FLAG_NO_MOVE); - offset = buf->offset; - driReadUnlockKernelBO(); - - return buf->offset; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - return 0; -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - uint64_t flags; - - driReadLockKernelBO(); - flags = buf->flags; - driReadUnlockKernelBO(); - - return flags; -} - - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - unsigned long size; - - driReadLockKernelBO(); - size = buf->size; - driReadUnlockKernelBO(); - - return buf->size; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - /* - * Noop. The kernel handles all fencing. - */ - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - return (drmBO *) private; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, - int lazy) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); - driReadUnlockKernelBO(); - - return ret; -} - - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - -/*static int -pool_setStatus(struct _DriBufferPool *pool, void *private, - uint64_t flag_diff, uint64_t old_flags) -{ - drmBO *buf = (drmBO *) private; - uint64_t new_flags = old_flags ^ flag_diff; - int ret; - - driReadLockKernelBO(); - ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, - 0, 0, 0); - driReadUnlockKernelBO(); - return ret; -}*/ - -struct _DriBufferPool * -driDRMPoolInit(int fd) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - - if (!pool) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->poolOffset = &pool_poolOffset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - pool->reference = &pool_reference; - pool->unreference = &pool_unreference; - pool->data = NULL; - return pool; -} diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c b/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c deleted file mode 100644 index b56bc269da..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c +++ /dev/null @@ -1,377 +0,0 @@ -#include "ws_dri_fencemgr.h" -#include "glthread.h" -#include -#include -#include - -/* - * Note: Locking order is - * _DriFenceObject::mutex - * _DriFenceMgr::mutex - */ - -struct _DriFenceMgr { - /* - * Constant members. Need no mutex protection. - */ - struct _DriFenceMgrCreateInfo info; - void *private; - - /* - * These members are protected by this->mutex - */ - _glthread_Mutex mutex; - int refCount; - drmMMListHead *heads; - int num_fences; -}; - -struct _DriFenceObject { - - /* - * These members are constant and need no mutex protection. - */ - struct _DriFenceMgr *mgr; - uint32_t fence_class; - uint32_t fence_type; - - /* - * These members are protected by mgr->mutex. - */ - drmMMListHead head; - int refCount; - - /* - * These members are protected by this->mutex. - */ - _glthread_Mutex mutex; - uint32_t signaled_type; - void *private; -}; - -uint32_t -driFenceType(struct _DriFenceObject *fence) -{ - return fence->fence_type; -} - -struct _DriFenceMgr * -driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) -{ - struct _DriFenceMgr *tmp; - uint32_t i; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return NULL; - - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); - tmp->refCount = 1; - tmp->info = *info; - tmp->num_fences = 0; - tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); - if (!tmp->heads) - goto out_err; - - for (i=0; iinfo.num_classes; ++i) { - DRMINITLISTHEAD(&tmp->heads[i]); - } - _glthread_UNLOCK_MUTEX(tmp->mutex); - return tmp; - - out_err: - if (tmp) - free(tmp); - return NULL; -} - -static void -driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) -{ - struct _DriFenceMgr *mgr = *pMgr; - - *pMgr = NULL; - if (--mgr->refCount == 0) - free(mgr); - else - _glthread_UNLOCK_MUTEX(mgr->mutex); -} - -void -driFenceMgrUnReference(struct _DriFenceMgr **pMgr) -{ - _glthread_LOCK_MUTEX((*pMgr)->mutex); - driFenceMgrUnrefUnlock(pMgr); -} - -static void -driFenceUnReferenceLocked(struct _DriFenceObject **pFence) -{ - struct _DriFenceObject *fence = *pFence; - struct _DriFenceMgr *mgr = fence->mgr; - - *pFence = NULL; - if (--fence->refCount == 0) { - DRMLISTDELINIT(&fence->head); - if (fence->private) - mgr->info.unreference(mgr, &fence->private); - --mgr->num_fences; - fence->mgr = NULL; - --mgr->refCount; - free(fence); - - } -} - - -static void -driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, - drmMMListHead *list, - uint32_t fence_class, - uint32_t fence_type) -{ - struct _DriFenceObject *entry; - drmMMListHead *prev; - - while(list != &mgr->heads[fence_class]) { - entry = DRMLISTENTRY(struct _DriFenceObject, list, head); - - /* - * Up refcount so that entry doesn't disappear from under us - * when we unlock-relock mgr to get the correct locking order. - */ - - ++entry->refCount; - _glthread_UNLOCK_MUTEX(mgr->mutex); - _glthread_LOCK_MUTEX(entry->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); - - prev = list->prev; - - - - if (list->prev == list) { - - /* - * Somebody else removed the entry from the list. - */ - - _glthread_UNLOCK_MUTEX(entry->mutex); - driFenceUnReferenceLocked(&entry); - return; - } - - entry->signaled_type |= (fence_type & entry->fence_type); - if (entry->signaled_type == entry->fence_type) { - DRMLISTDELINIT(list); - mgr->info.unreference(mgr, &entry->private); - } - _glthread_UNLOCK_MUTEX(entry->mutex); - driFenceUnReferenceLocked(&entry); - list = prev; - } -} - - -int -driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, - int lazy_hint) -{ - struct _DriFenceMgr *mgr = fence->mgr; - int ret = 0; - - _glthread_LOCK_MUTEX(fence->mutex); - - if ((fence->signaled_type & fence_type) == fence_type) - goto out0; - - ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); - if (ret) - goto out0; - - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); - - driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, - fence_type); - _glthread_UNLOCK_MUTEX(mgr->mutex); - return 0; - - out0: - _glthread_UNLOCK_MUTEX(fence->mutex); - return ret; -} - -uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) -{ - uint32_t ret; - - _glthread_LOCK_MUTEX(fence->mutex); - ret = fence->signaled_type; - _glthread_UNLOCK_MUTEX(fence->mutex); - - return ret; -} - -int -driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, - uint32_t *signaled) -{ - int ret = 0; - struct _DriFenceMgr *mgr; - - _glthread_LOCK_MUTEX(fence->mutex); - mgr = fence->mgr; - *signaled = fence->signaled_type; - if ((fence->signaled_type & flush_type) == flush_type) - goto out0; - - ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); - if (ret) { - *signaled = fence->signaled_type; - goto out0; - } - - if ((fence->signaled_type | *signaled) == fence->signaled_type) - goto out0; - - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); - - driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, - *signaled); - - _glthread_UNLOCK_MUTEX(mgr->mutex); - return 0; - out0: - _glthread_UNLOCK_MUTEX(fence->mutex); - return ret; -} - -struct _DriFenceObject * -driFenceReference(struct _DriFenceObject *fence) -{ - _glthread_LOCK_MUTEX(fence->mgr->mutex); - ++fence->refCount; - _glthread_UNLOCK_MUTEX(fence->mgr->mutex); - return fence; -} - -void -driFenceUnReference(struct _DriFenceObject **pFence) -{ - struct _DriFenceMgr *mgr; - - if (*pFence == NULL) - return; - - mgr = (*pFence)->mgr; - _glthread_LOCK_MUTEX(mgr->mutex); - ++mgr->refCount; - driFenceUnReferenceLocked(pFence); - driFenceMgrUnrefUnlock(&mgr); -} - -struct _DriFenceObject -*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, - uint32_t fence_type, void *private, size_t private_size) -{ - struct _DriFenceObject *fence; - size_t fence_size = sizeof(*fence); - - if (private_size) - fence_size = ((fence_size + 15) & ~15); - - fence = calloc(1, fence_size + private_size); - - if (!fence) { - int ret = mgr->info.finish(mgr, private, fence_type, 0); - - if (ret) - usleep(10000000); - - return NULL; - } - - _glthread_INIT_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); - fence->refCount = 1; - DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); - fence->mgr = mgr; - ++mgr->refCount; - ++mgr->num_fences; - _glthread_UNLOCK_MUTEX(mgr->mutex); - fence->fence_class = fence_class; - fence->fence_type = fence_type; - fence->signaled_type = 0; - fence->private = private; - if (private_size) { - fence->private = (void *)(((uint8_t *) fence) + fence_size); - memcpy(fence->private, private, private_size); - } - - _glthread_UNLOCK_MUTEX(fence->mutex); - return fence; -} - - -static int -tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, - uint32_t *signaled_type) -{ - long fd = (long) mgr->private; - int dummy; - drmFence *fence = (drmFence *) private; - int ret; - - *signaled_type = 0; - ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); - if (ret) - return ret; - - *signaled_type = fence->signaled; - - return 0; -} - -static int -tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, - int lazy_hint) -{ - long fd = (long) mgr->private; - unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; - - return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); -} - -static int -tUnref(struct _DriFenceMgr *mgr, void **private) -{ - long fd = (long) mgr->private; - drmFence *fence = (drmFence *) *private; - *private = NULL; - - return drmFenceUnreference(fd, fence); -} - -struct _DriFenceMgr *driFenceMgrTTMInit(int fd) -{ - struct _DriFenceMgrCreateInfo info; - struct _DriFenceMgr *mgr; - - info.flags = DRI_FENCE_CLASS_ORDERED; - info.num_classes = 4; - info.signaled = tSignaled; - info.finish = tFinish; - info.unreference = tUnref; - - mgr = driFenceMgrCreate(&info); - if (mgr == NULL) - return NULL; - - mgr->private = (void *) (long) fd; - return mgr; -} - diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h b/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h deleted file mode 100644 index 4ea58dfe18..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef DRI_FENCEMGR_H -#define DRI_FENCEMGR_H - -#include -#include - -struct _DriFenceObject; -struct _DriFenceMgr; - -/* - * Do a quick check to see if the fence manager has registered the fence - * object as signaled. Note that this function may return a false negative - * answer. - */ -extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); - -/* - * Check if the fence object is signaled. This function can be substantially - * more expensive to call than the above function, but will not return a false - * negative answer. The argument "flush_type" sets the types that the - * underlying mechanism must make sure will eventually signal. - */ -extern int driFenceSignaledType(struct _DriFenceObject *fence, - uint32_t flush_type, uint32_t *signaled); - -/* - * Convenience functions. - */ - -static inline int driFenceSignaled(struct _DriFenceObject *fence, - uint32_t flush_type) -{ - uint32_t signaled_types; - int ret = driFenceSignaledType(fence, flush_type, &signaled_types); - if (ret) - return 0; - return ((signaled_types & flush_type) == flush_type); -} - -static inline int driFenceSignaledCached(struct _DriFenceObject *fence, - uint32_t flush_type) -{ - uint32_t signaled_types = - driFenceSignaledTypeCached(fence); - - return ((signaled_types & flush_type) == flush_type); -} - -/* - * Reference a fence object. - */ -extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); - -/* - * Unreference a fence object. The fence object pointer will be reset to NULL. - */ - -extern void driFenceUnReference(struct _DriFenceObject **pFence); - - -/* - * Wait for a fence to signal the indicated fence_type. - * If "lazy_hint" is true, it indicates that the wait may sleep to avoid - * busy-wait polling. - */ -extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, - int lazy_hint); - -/* - * Create a DriFenceObject for manager "mgr". - * - * "private" is a pointer that should be used for the callbacks in - * struct _DriFenceMgrCreateInfo. - * - * if private_size is nonzero, then the info stored at *private, with size - * private size will be copied and the fence manager will instead use a - * pointer to the copied data for the callbacks in - * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by - * "private" may be destroyed after the call to driFenceCreate. - */ -extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, - uint32_t fence_class, - uint32_t fence_type, - void *private, - size_t private_size); - -extern uint32_t driFenceType(struct _DriFenceObject *fence); - -/* - * Fence creations are ordered. If a fence signals a fence_type, - * it is safe to assume that all fences of the same class that was - * created before that fence has signaled the same type. - */ - -#define DRI_FENCE_CLASS_ORDERED (1 << 0) - -struct _DriFenceMgrCreateInfo { - uint32_t flags; - uint32_t num_classes; - int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, - uint32_t *signaled_type); - int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); - int (*unreference) (struct _DriFenceMgr *mgr, void **private); -}; - -extern struct _DriFenceMgr * -driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); - -void -driFenceMgrUnReference(struct _DriFenceMgr **pMgr); - -extern struct _DriFenceMgr * -driFenceMgrTTMInit(int fd); - -#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c b/src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c deleted file mode 100644 index a80555c9c7..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c +++ /dev/null @@ -1,161 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstr鰉 - */ - -#include -#include -#include -#include "pipe/p_debug.h" -#include "glthread.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, uint64_t flags, unsigned hint, - unsigned alignment) -{ - unsigned long *private = malloc(size + 2*sizeof(unsigned long)); - if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) - abort(); - - *private = size; - return (void *)private; -} - - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - free(private); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex, int lazy) -{ - return 0; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - *virtual = (void *)((unsigned long *)private + 2); - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - /* - * BUG - */ - abort(); - return 0UL; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - /* - * BUG - */ - abort(); -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - return *(unsigned long *) private; -} - - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - abort(); - return 0UL; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - abort(); - return NULL; -} - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - - -struct _DriBufferPool * -driMallocPoolInit(void) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - if (!pool) - return NULL; - - pool->data = NULL; - pool->fd = -1; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->poolOffset = &pool_poolOffset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - return pool; -} diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c b/src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c deleted file mode 100644 index dfcf6d6b19..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c +++ /dev/null @@ -1,968 +0,0 @@ -/************************************************************************** - * - * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#include -#include -#include -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" -#include "ws_dri_bufmgr.h" -#include "glthread.h" - -#define DRI_SLABPOOL_ALLOC_RETRIES 100 - -struct _DriSlab; - -struct _DriSlabBuffer { - int isSlabBuffer; - drmBO *bo; - struct _DriFenceObject *fence; - struct _DriSlab *parent; - drmMMListHead head; - uint32_t mapCount; - uint32_t start; - uint32_t fenceType; - int unFenced; - _glthread_Cond event; -}; - -struct _DriKernelBO { - int fd; - drmBO bo; - drmMMListHead timeoutHead; - drmMMListHead head; - struct timeval timeFreed; - uint32_t pageAlignment; - void *virtual; -}; - -struct _DriSlab{ - drmMMListHead head; - drmMMListHead freeBuffers; - uint32_t numBuffers; - uint32_t numFree; - struct _DriSlabBuffer *buffers; - struct _DriSlabSizeHeader *header; - struct _DriKernelBO *kbo; -}; - - -struct _DriSlabSizeHeader { - drmMMListHead slabs; - drmMMListHead freeSlabs; - drmMMListHead delayedBuffers; - uint32_t numDelayed; - struct _DriSlabPool *slabPool; - uint32_t bufSize; - _glthread_Mutex mutex; -}; - -struct _DriFreeSlabManager { - struct timeval slabTimeout; - struct timeval checkInterval; - struct timeval nextCheck; - drmMMListHead timeoutList; - drmMMListHead unCached; - drmMMListHead cached; - _glthread_Mutex mutex; -}; - - -struct _DriSlabPool { - - /* - * The data of this structure remains constant after - * initialization and thus needs no mutex protection. - */ - - struct _DriFreeSlabManager *fMan; - uint64_t proposedFlags; - uint64_t validMask; - uint32_t *bucketSizes; - uint32_t numBuckets; - uint32_t pageSize; - int fd; - int pageAlignment; - int maxSlabSize; - int desiredNumBuffers; - struct _DriSlabSizeHeader *headers; -}; - -/* - * FIXME: Perhaps arrange timeout slabs in size buckets for fast - * retreival?? - */ - - -static inline int -driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) -{ - return ((arg1->tv_sec > arg2->tv_sec) || - ((arg1->tv_sec == arg2->tv_sec) && - (arg1->tv_usec > arg2->tv_usec))); -} - -static inline void -driTimeAdd(struct timeval *arg, struct timeval *add) -{ - unsigned int sec; - - arg->tv_sec += add->tv_sec; - arg->tv_usec += add->tv_usec; - sec = arg->tv_usec / 1000000; - arg->tv_sec += sec; - arg->tv_usec -= sec*1000000; -} - -static void -driFreeKernelBO(struct _DriKernelBO *kbo) -{ - if (!kbo) - return; - - (void) drmBOUnreference(kbo->fd, &kbo->bo); - free(kbo); -} - - -static void -driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, - struct timeval *time) -{ - drmMMListHead *list, *next; - struct _DriKernelBO *kbo; - - if (!driTimeAfterEq(time, &fMan->nextCheck)) - return; - - for (list = fMan->timeoutList.next, next = list->next; - list != &fMan->timeoutList; - list = next, next = list->next) { - - kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); - - if (!driTimeAfterEq(time, &kbo->timeFreed)) - break; - - DRMLISTDELINIT(&kbo->timeoutHead); - DRMLISTDELINIT(&kbo->head); - driFreeKernelBO(kbo); - } - - fMan->nextCheck = *time; - driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); -} - - -/* - * Add a _DriKernelBO to the free slab manager. - * This means that it is available for reuse, but if it's not - * reused in a while, it will be freed. - */ - -static void -driSetKernelBOFree(struct _DriFreeSlabManager *fMan, - struct _DriKernelBO *kbo) -{ - struct timeval time; - - _glthread_LOCK_MUTEX(fMan->mutex); - gettimeofday(&time, NULL); - driTimeAdd(&time, &fMan->slabTimeout); - - kbo->timeFreed = time; - - if (kbo->bo.flags & DRM_BO_FLAG_CACHED) - DRMLISTADD(&kbo->head, &fMan->cached); - else - DRMLISTADD(&kbo->head, &fMan->unCached); - - DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); - driFreeTimeoutKBOsLocked(fMan, &time); - - _glthread_UNLOCK_MUTEX(fMan->mutex); -} - -/* - * Get a _DriKernelBO for us to use as storage for a slab. - * - */ - -static struct _DriKernelBO * -driAllocKernelBO(struct _DriSlabSizeHeader *header) - -{ - struct _DriSlabPool *slabPool = header->slabPool; - struct _DriFreeSlabManager *fMan = slabPool->fMan; - drmMMListHead *list, *next, *head; - uint32_t size = header->bufSize * slabPool->desiredNumBuffers; - struct _DriKernelBO *kbo; - struct _DriKernelBO *kboTmp; - int ret; - - /* - * FIXME: We should perhaps allow some variation in slabsize in order - * to efficiently reuse slabs. - */ - - size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; - size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); - _glthread_LOCK_MUTEX(fMan->mutex); - - kbo = NULL; - - retry: - head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? - &fMan->cached : &fMan->unCached; - - for (list = head->next, next = list->next; - list != head; - list = next, next = list->next) { - - kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); - - if ((kboTmp->bo.size == size) && - (slabPool->pageAlignment == 0 || - (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { - - if (!kbo) - kbo = kboTmp; - - if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) - break; - - } - } - - if (kbo) { - DRMLISTDELINIT(&kbo->head); - DRMLISTDELINIT(&kbo->timeoutHead); - } - - _glthread_UNLOCK_MUTEX(fMan->mutex); - - if (kbo) { - uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; - - ret = 0; - if (new_mask) { - ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, - new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); - } - if (ret == 0) - return kbo; - - driFreeKernelBO(kbo); - kbo = NULL; - goto retry; - } - - kbo = calloc(1, sizeof(struct _DriKernelBO)); - if (!kbo) - return NULL; - - kbo->fd = slabPool->fd; - DRMINITLISTHEAD(&kbo->head); - DRMINITLISTHEAD(&kbo->timeoutHead); - ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, - slabPool->proposedFlags, - DRM_BO_HINT_DONT_FENCE, &kbo->bo); - if (ret) - goto out_err0; - - ret = drmBOMap(kbo->fd, &kbo->bo, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0, &kbo->virtual); - - if (ret) - goto out_err1; - - ret = drmBOUnmap(kbo->fd, &kbo->bo); - if (ret) - goto out_err1; - - return kbo; - - out_err1: - drmBOUnreference(kbo->fd, &kbo->bo); - out_err0: - free(kbo); - return NULL; -} - - -static int -driAllocSlab(struct _DriSlabSizeHeader *header) -{ - struct _DriSlab *slab; - struct _DriSlabBuffer *buf; - uint32_t numBuffers; - int ret; - int i; - - slab = calloc(1, sizeof(*slab)); - if (!slab) - return -ENOMEM; - - slab->kbo = driAllocKernelBO(header); - if (!slab->kbo) { - ret = -ENOMEM; - goto out_err0; - } - - numBuffers = slab->kbo->bo.size / header->bufSize; - - slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); - if (!slab->buffers) { - ret = -ENOMEM; - goto out_err1; - } - - DRMINITLISTHEAD(&slab->head); - DRMINITLISTHEAD(&slab->freeBuffers); - slab->numBuffers = numBuffers; - slab->numFree = 0; - slab->header = header; - - buf = slab->buffers; - for (i=0; i < numBuffers; ++i) { - buf->parent = slab; - buf->start = i* header->bufSize; - buf->mapCount = 0; - buf->isSlabBuffer = 1; - _glthread_INIT_COND(buf->event); - DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); - slab->numFree++; - buf++; - } - - DRMLISTADDTAIL(&slab->head, &header->slabs); - - return 0; - - out_err1: - driSetKernelBOFree(header->slabPool->fMan, slab->kbo); - free(slab->buffers); - out_err0: - free(slab); - return ret; -} - -/* - * Delete a buffer from the slab header delayed list and put - * it on the slab free list. - */ - -static void -driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) -{ - struct _DriSlab *slab = buf->parent; - struct _DriSlabSizeHeader *header = slab->header; - drmMMListHead *list = &buf->head; - - DRMLISTDEL(list); - DRMLISTADDTAIL(list, &slab->freeBuffers); - slab->numFree++; - - if (slab->head.next == &slab->head) - DRMLISTADDTAIL(&slab->head, &header->slabs); - - if (slab->numFree == slab->numBuffers) { - list = &slab->head; - DRMLISTDEL(list); - DRMLISTADDTAIL(list, &header->freeSlabs); - } - - if (header->slabs.next == &header->slabs || - slab->numFree != slab->numBuffers) { - - drmMMListHead *next; - struct _DriFreeSlabManager *fMan = header->slabPool->fMan; - - for (list = header->freeSlabs.next, next = list->next; - list != &header->freeSlabs; - list = next, next = list->next) { - - slab = DRMLISTENTRY(struct _DriSlab, list, head); - - DRMLISTDELINIT(list); - driSetKernelBOFree(fMan, slab->kbo); - free(slab->buffers); - free(slab); - } - } -} - -static void -driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) -{ - drmMMListHead *list, *prev, *first; - struct _DriSlabBuffer *buf; - struct _DriSlab *slab; - int firstWasSignaled = 1; - int signaled; - int i; - int ret; - - /* - * Rerun the freeing test if the youngest tested buffer - * was signaled, since there might be more idle buffers - * in the delay list. - */ - - while (firstWasSignaled) { - firstWasSignaled = 0; - signaled = 0; - first = header->delayedBuffers.next; - - /* Only examine the oldest 1/3 of delayed buffers: - */ - if (header->numDelayed > 3) { - for (i = 0; i < header->numDelayed; i += 3) { - first = first->next; - } - } - - for (list = first, prev = list->prev; - list != &header->delayedBuffers; - list = prev, prev = list->prev) { - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - slab = buf->parent; - - if (!signaled) { - if (wait) { - ret = driFenceFinish(buf->fence, buf->fenceType, 0); - if (ret) - break; - signaled = 1; - wait = 0; - } else { - signaled = driFenceSignaled(buf->fence, buf->fenceType); - } - if (signaled) { - if (list == first) - firstWasSignaled = 1; - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - } - } -} - - -static struct _DriSlabBuffer * -driSlabAllocBuffer(struct _DriSlabSizeHeader *header) -{ - static struct _DriSlabBuffer *buf; - struct _DriSlab *slab; - drmMMListHead *list; - int count = DRI_SLABPOOL_ALLOC_RETRIES; - - _glthread_LOCK_MUTEX(header->mutex); - while(header->slabs.next == &header->slabs && count > 0) { - driSlabCheckFreeLocked(header, 0); - if (header->slabs.next != &header->slabs) - break; - - _glthread_UNLOCK_MUTEX(header->mutex); - if (count != DRI_SLABPOOL_ALLOC_RETRIES) - usleep(1); - _glthread_LOCK_MUTEX(header->mutex); - (void) driAllocSlab(header); - count--; - } - - list = header->slabs.next; - if (list == &header->slabs) { - _glthread_UNLOCK_MUTEX(header->mutex); - return NULL; - } - slab = DRMLISTENTRY(struct _DriSlab, list, head); - if (--slab->numFree == 0) - DRMLISTDELINIT(list); - - list = slab->freeBuffers.next; - DRMLISTDELINIT(list); - - _glthread_UNLOCK_MUTEX(header->mutex); - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - return buf; -} - -static void * -pool_create(struct _DriBufferPool *driPool, unsigned long size, - uint64_t flags, unsigned hint, unsigned alignment) -{ - struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; - struct _DriSlabSizeHeader *header; - struct _DriSlabBuffer *buf; - void *dummy; - int i; - int ret; - - /* - * FIXME: Check for compatibility. - */ - - header = pool->headers; - for (i=0; inumBuckets; ++i) { - if (header->bufSize >= size) - break; - header++; - } - - if (i < pool->numBuckets) - return driSlabAllocBuffer(header); - - - /* - * Fall back to allocate a buffer object directly from DRM. - * and wrap it in a driBO structure. - */ - - - buf = calloc(1, sizeof(*buf)); - - if (!buf) - return NULL; - - buf->bo = calloc(1, sizeof(*buf->bo)); - if (!buf->bo) - goto out_err0; - - if (alignment) { - if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) - goto out_err1; - if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) - goto out_err1; - } - - ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, - flags, hint, buf->bo); - if (ret) - goto out_err1; - - ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0, &dummy); - if (ret) - goto out_err2; - - ret = drmBOUnmap(pool->fd, buf->bo); - if (ret) - goto out_err2; - - return buf; - out_err2: - drmBOUnreference(pool->fd, buf->bo); - out_err1: - free(buf->bo); - out_err0: - free(buf); - return NULL; -} - -static int -pool_destroy(struct _DriBufferPool *driPool, void *private) -{ - struct _DriSlabBuffer *buf = - (struct _DriSlabBuffer *) private; - struct _DriSlab *slab; - struct _DriSlabSizeHeader *header; - - if (!buf->isSlabBuffer) { - struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; - int ret; - - ret = drmBOUnreference(pool->fd, buf->bo); - free(buf->bo); - free(buf); - return ret; - } - - slab = buf->parent; - header = slab->header; - - _glthread_LOCK_MUTEX(header->mutex); - buf->unFenced = 0; - buf->mapCount = 0; - - if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { - DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); - header->numDelayed++; - } else { - if (buf->fence) - driFenceUnReference(&buf->fence); - driSlabFreeBufferLocked(buf); - } - - _glthread_UNLOCK_MUTEX(header->mutex); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *driPool, void *private, - _glthread_Mutex *mutex, int lazy) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - while(buf->unFenced) - _glthread_COND_WAIT(buf->event, *mutex); - - if (!buf->fence) - return 0; - - driFenceFinish(buf->fence, buf->fenceType, lazy); - driFenceUnReference(&buf->fence); - - return 0; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - int busy; - - if (buf->isSlabBuffer) - busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); - else - busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); - - - if (busy) { - if (hint & DRM_BO_HINT_DONT_BLOCK) - return -EBUSY; - else { - (void) pool_waitIdle(pool, private, mutex, 0); - } - } - - ++buf->mapCount; - *virtual = (buf->isSlabBuffer) ? - (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : - (void *) buf->bo->virtual; - - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - --buf->mapCount; - if (buf->mapCount == 0 && buf->isSlabBuffer) - _glthread_COND_BROADCAST(buf->event); - - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - struct _DriSlab *slab; - struct _DriSlabSizeHeader *header; - - if (!buf->isSlabBuffer) { - assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); - return buf->bo->offset; - } - - slab = buf->parent; - header = slab->header; - - (void) header; - assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); - return slab->kbo->bo.offset + buf->start; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - return buf->start; -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf->isSlabBuffer) - return buf->bo->flags; - - return buf->parent->kbo->bo.flags; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - if (!buf->isSlabBuffer) - return buf->bo->size; - - return buf->parent->header->bufSize; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - drmBO *bo; - - if (buf->fence) - driFenceUnReference(&buf->fence); - - buf->fence = driFenceReference(fence); - bo = (buf->isSlabBuffer) ? - &buf->parent->kbo->bo: - buf->bo; - buf->fenceType = bo->fenceFlags; - - buf->unFenced = 0; - _glthread_COND_BROADCAST(buf->event); - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; -} - -static int -pool_validate(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf->isSlabBuffer) - return 0; - - while(buf->mapCount != 0) - _glthread_COND_WAIT(buf->event, *mutex); - - buf->unFenced = 1; - return 0; -} - - -struct _DriFreeSlabManager * -driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) -{ - struct _DriFreeSlabManager *tmp; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return NULL; - - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); - tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; - tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; - tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; - - tmp->checkInterval.tv_usec = checkIntervalMsec*1000; - tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; - tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; - - gettimeofday(&tmp->nextCheck, NULL); - driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); - DRMINITLISTHEAD(&tmp->timeoutList); - DRMINITLISTHEAD(&tmp->unCached); - DRMINITLISTHEAD(&tmp->cached); - _glthread_UNLOCK_MUTEX(tmp->mutex); - - return tmp; -} - -void -driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) -{ - struct timeval time; - - time = fMan->nextCheck; - driTimeAdd(&time, &fMan->checkInterval); - - _glthread_LOCK_MUTEX(fMan->mutex); - driFreeTimeoutKBOsLocked(fMan, &time); - _glthread_UNLOCK_MUTEX(fMan->mutex); - - assert(fMan->timeoutList.next == &fMan->timeoutList); - assert(fMan->unCached.next == &fMan->unCached); - assert(fMan->cached.next == &fMan->cached); - - free(fMan); -} - -static void -driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, - struct _DriSlabSizeHeader *header) -{ - _glthread_INIT_MUTEX(header->mutex); - _glthread_LOCK_MUTEX(header->mutex); - - DRMINITLISTHEAD(&header->slabs); - DRMINITLISTHEAD(&header->freeSlabs); - DRMINITLISTHEAD(&header->delayedBuffers); - - header->numDelayed = 0; - header->slabPool = pool; - header->bufSize = size; - - _glthread_UNLOCK_MUTEX(header->mutex); -} - -static void -driFinishSizeHeader(struct _DriSlabSizeHeader *header) -{ - drmMMListHead *list, *next; - struct _DriSlabBuffer *buf; - - _glthread_LOCK_MUTEX(header->mutex); - for (list = header->delayedBuffers.next, next = list->next; - list != &header->delayedBuffers; - list = next, next = list->next) { - - buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); - if (buf->fence) { - (void) driFenceFinish(buf->fence, buf->fenceType, 0); - driFenceUnReference(&buf->fence); - } - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - _glthread_UNLOCK_MUTEX(header->mutex); -} - -static void -pool_takedown(struct _DriBufferPool *driPool) -{ - struct _DriSlabPool *pool = driPool->data; - int i; - - for (i=0; inumBuckets; ++i) { - driFinishSizeHeader(&pool->headers[i]); - } - - free(pool->headers); - free(pool->bucketSizes); - free(pool); - free(driPool); -} - -struct _DriBufferPool * -driSlabPoolInit(int fd, uint64_t flags, - uint64_t validMask, - uint32_t smallestSize, - uint32_t numSizes, - uint32_t desiredNumBuffers, - uint32_t maxSlabSize, - uint32_t pageAlignment, - struct _DriFreeSlabManager *fMan) -{ - struct _DriBufferPool *driPool; - struct _DriSlabPool *pool; - uint32_t i; - - driPool = calloc(1, sizeof(*driPool)); - if (!driPool) - return NULL; - - pool = calloc(1, sizeof(*pool)); - if (!pool) - goto out_err0; - - pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); - if (!pool->bucketSizes) - goto out_err1; - - pool->headers = calloc(numSizes, sizeof(*pool->headers)); - if (!pool->headers) - goto out_err2; - - pool->fMan = fMan; - pool->proposedFlags = flags; - pool->validMask = validMask; - pool->numBuckets = numSizes; - pool->pageSize = getpagesize(); - pool->fd = fd; - pool->pageAlignment = pageAlignment; - pool->maxSlabSize = maxSlabSize; - pool->desiredNumBuffers = desiredNumBuffers; - - for (i=0; inumBuckets; ++i) { - pool->bucketSizes[i] = (smallestSize << i); - driInitSizeHeader(pool, pool->bucketSizes[i], - &pool->headers[i]); - } - - driPool->data = (void *) pool; - driPool->map = &pool_map; - driPool->unmap = &pool_unmap; - driPool->destroy = &pool_destroy; - driPool->offset = &pool_offset; - driPool->poolOffset = &pool_poolOffset; - driPool->flags = &pool_flags; - driPool->size = &pool_size; - driPool->create = &pool_create; - driPool->fence = &pool_fence; - driPool->kernel = &pool_kernel; - driPool->validate = &pool_validate; - driPool->waitIdle = &pool_waitIdle; - driPool->takeDown = &pool_takedown; - - return driPool; - - out_err2: - free(pool->bucketSizes); - out_err1: - free(pool); - out_err0: - free(driPool); - - return NULL; -} diff --git a/src/gallium/winsys/dri/Makefile b/src/gallium/winsys/dri/Makefile deleted file mode 100644 index f466ce6c3c..0000000000 --- a/src/gallium/winsys/dri/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# src/mesa/drivers/dri/Makefile - -TOP = ../../../.. - -include $(TOP)/configs/current - - - -default: $(TOP)/$(LIB_DIR) subdirs - - -$(TOP)/$(LIB_DIR): - -mkdir $(TOP)/$(LIB_DIR) - - -subdirs: - @for dir in $(DRI_DIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE)) || exit 1 ; \ - fi \ - done - - -install: - @for dir in $(DRI_DIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE) install) || exit 1 ; \ - fi \ - done - - -clean: - @for dir in $(DRI_DIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE) clean) ; \ - fi \ - done - -rm -f common/*.o diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template deleted file mode 100644 index 80e817b808..0000000000 --- a/src/gallium/winsys/dri/Makefile.template +++ /dev/null @@ -1,125 +0,0 @@ -# -*-makefile-*- - -MESA_MODULES = \ - $(TOP)/src/mesa/libmesa.a \ - $(GALLIUM_AUXILIARIES) - -COMMON_GALLIUM_SOURCES = \ - $(TOP)/src/mesa/drivers/dri/common/utils.c \ - $(TOP)/src/mesa/drivers/dri/common/vblank.c \ - $(TOP)/src/mesa/drivers/dri/common/dri_util.c \ - $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c - -COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ - $(TOP)/src/mesa/drivers/common/driverfuncs.c \ - $(TOP)/src/mesa/drivers/dri/common/texmem.c \ - $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c - -COMMON_BM_SOURCES = \ - $(TOP)/src/mesa/drivers/dri/common/dri_bufmgr.c \ - $(TOP)/src/mesa/drivers/dri/common/dri_drmpool.c - - -ifeq ($(WINDOW_SYSTEM),dri) -WINOBJ= -WINLIB= -INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) - -OBJECTS = \ - $(C_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) - -else -# miniglx -WINOBJ= -WINLIB=-L$(MESA)/src/glx/mini -MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini -INCLUDES = $(MINIGLX_INCLUDES) \ - $(SHARED_INCLUDES) \ - $(PCIACCESS_CFLAGS) - -OBJECTS = $(C_SOURCES:.c=.o) \ - $(MINIGLX_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) -endif - - -### Include directories -SHARED_INCLUDES = \ - -I. \ - -I$(TOP)/src/mesa/drivers/dri/common \ - -Iserver \ - -I$(TOP)/include \ - -I$(TOP)/include/GL/internal \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/gallium/winsys/common \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/main \ - -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/mesa/math \ - -I$(TOP)/src/mesa/transform \ - -I$(TOP)/src/mesa/shader \ - -I$(TOP)/src/mesa/swrast \ - -I$(TOP)/src/mesa/swrast_setup \ - -I$(TOP)/src/egl/main \ - -I$(TOP)/src/egl/drivers/dri \ - $(LIBDRM_CFLAGS) - - -##### RULES ##### - -.c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - - -##### TARGETS ##### - -default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR)/$(LIBNAME_EGL) - - -$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template - $(TOP)/bin/mklib -noprefix -o $@ \ - $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) - -$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS) - $(TOP)/bin/mklib -o $(LIBNAME_EGL) \ - -linker "$(CC)" \ - -noprefix \ - $(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \ - --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive - -$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) - $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) - -$(TOP)/$(LIB_DIR)/$(LIBNAME_EGL): $(LIBNAME_EGL) - $(INSTALL) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR) - -depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \ - $(ASM_SOURCES) 2> /dev/null - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` `find ../include` - - -# Remove .o and backup files -clean: - -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) - -rm -f depend depend.bak - - -install: $(LIBNAME) - $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) - $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) - - -include depend diff --git a/src/gallium/winsys/dri/SConscript b/src/gallium/winsys/dri/SConscript deleted file mode 100644 index aef5210a32..0000000000 --- a/src/gallium/winsys/dri/SConscript +++ /dev/null @@ -1,54 +0,0 @@ -Import('*') - -if env['dri']: - - drienv = env.Clone() - - drienv.Replace(CPPPATH = [ - '#src/mesa/drivers/dri/common', - '#include', - '#include/GL/internal', - '#src/gallium/include', - '#src/gallium/auxiliary', - '#src/gallium/drivers', - '#src/mesa', - '#src/mesa/main', - '#src/mesa/glapi', - '#src/mesa/math', - '#src/mesa/transform', - '#src/mesa/shader', - '#src/mesa/swrast', - '#src/mesa/swrast_setup', - '#src/egl/main', - '#src/egl/drivers/dri', - ]) - - drienv.ParseConfig('pkg-config --cflags --libs libdrm') - - COMMON_GALLIUM_SOURCES = [ - '#src/mesa/drivers/dri/common/utils.c', - '#src/mesa/drivers/dri/common/vblank.c', - '#src/mesa/drivers/dri/common/dri_util.c', - '#src/mesa/drivers/dri/common/xmlconfig.c', - ] - - COMMON_BM_SOURCES = [ - '#src/mesa/drivers/dri/common/dri_bufmgr.c', - '#src/mesa/drivers/dri/common/dri_drmpool.c', - ] - - Export([ - 'drienv', - 'COMMON_GALLIUM_SOURCES', - 'COMMON_BM_SOURCES', - ]) - - # TODO: Installation - #install: $(LIBNAME) - # $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) - # $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) - - if 'intel' in env['winsys']: - SConscript([ - 'intel/SConscript', - ]) diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile deleted file mode 100644 index e0716ea28e..0000000000 --- a/src/gallium/winsys/dri/intel/Makefile +++ /dev/null @@ -1,34 +0,0 @@ - -TOP = ../../../../.. -include $(TOP)/configs/current - -LIBNAME = i915_dri.so -LIBNAME_EGL = egl_i915_dri.so - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/winsys/common/intel_drm/libinteldrm.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a - - -DRIVER_SOURCES = \ - intel_winsys_softpipe.c \ - intel_swapbuffers.c \ - intel_context.c \ - intel_lock.c \ - intel_screen.c - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - -DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ - && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") - -include ../Makefile.template - -#intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c - -symlinks: diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript deleted file mode 100644 index 6a4f50afcc..0000000000 --- a/src/gallium/winsys/dri/intel/SConscript +++ /dev/null @@ -1,41 +0,0 @@ -Import('*') - -if 'mesa' in env['statetrackers']: - - env = drienv.Clone() - - env.Append(CPPPATH = [ - '../intel', - 'server' - ]) - - #MINIGLX_SOURCES = server/intel_dri.c - - DRIVER_SOURCES = [ - 'intel_winsys_pipe.c', - 'intel_winsys_softpipe.c', - 'intel_winsys_i915.c', - 'intel_batchbuffer.c', - 'intel_swapbuffers.c', - 'intel_context.c', - 'intel_lock.c', - 'intel_screen.c', - 'intel_batchpool.c', - ] - - sources = \ - COMMON_GALLIUM_SOURCES + \ - COMMON_BM_SOURCES + \ - DRIVER_SOURCES - - drivers = [ - softpipe, - i915simple - ] - - # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions - env.SharedLibrary( - target ='i915tex_dri.so', - source = sources, - LIBS = drivers + mesa + auxiliaries + env['LIBS'], - ) diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h deleted file mode 100644 index 1fa2719845..0000000000 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef INTEL_BATCHBUFFER_H -#define INTEL_BATCHBUFFER_H - -#include "intel_drm/intel_be_batchbuffer.h" - -/* - * Need to redefine the BATCH defines - */ - -#undef BEGIN_BATCH -#define BEGIN_BATCH(dwords, relocs) \ - (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) - -#undef OUT_BATCH -#define OUT_BATCH(d) \ - i915_batchbuffer_dword(&intel->base.batch->base, d) - -#undef OUT_RELOC -#define OUT_RELOC(buf,flags,mask,delta) do { \ - assert((delta) >= 0); \ - intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ -} while (0) - -#endif diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c deleted file mode 100644 index 97ef731aaa..0000000000 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ /dev/null @@ -1,337 +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 "i830_dri.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_swapbuffers.h" -#include "intel_batchbuffer.h" -#include "intel_winsys_softpipe.h" - -#include "i915simple/i915_screen.h" - -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_context.h" - -#include "utils.h" - - -#ifdef DEBUG -int __intel_debug = 0; -#endif - - -#define need_GL_ARB_multisample -#define need_GL_ARB_point_parameters -#define need_GL_ARB_texture_compression -#define need_GL_ARB_vertex_buffer_object -#define need_GL_ARB_vertex_program -#define need_GL_ARB_window_pos -#define need_GL_EXT_blend_color -#define need_GL_EXT_blend_equation_separate -#define need_GL_EXT_blend_func_separate -#define need_GL_EXT_blend_minmax -#define need_GL_EXT_cull_vertex -#define need_GL_EXT_fog_coord -#define need_GL_EXT_framebuffer_object -#define need_GL_EXT_multi_draw_arrays -#define need_GL_EXT_secondary_color -#define need_GL_NV_vertex_program -#include "extension_helper.h" - - -/** - * Extension strings exported by the intel driver. - * - * \note - * It appears that ARB_texture_env_crossbar has "disappeared" compared to the - * old i830-specific driver. - */ -const struct dri_extension card_extensions[] = { - {"GL_ARB_multisample", GL_ARB_multisample_functions}, - {"GL_ARB_multitexture", NULL}, - {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, - {"GL_ARB_texture_border_clamp", NULL}, - {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, - {"GL_ARB_texture_cube_map", NULL}, - {"GL_ARB_texture_env_add", NULL}, - {"GL_ARB_texture_env_combine", NULL}, - {"GL_ARB_texture_env_dot3", NULL}, - {"GL_ARB_texture_mirrored_repeat", NULL}, - {"GL_ARB_texture_rectangle", NULL}, - {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, - {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, - {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, - {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, - {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, - {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, - {"GL_EXT_blend_subtract", NULL}, - {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, - {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, - {"GL_EXT_packed_depth_stencil", NULL}, - {"GL_EXT_pixel_buffer_object", NULL}, - {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, - {"GL_EXT_stencil_wrap", NULL}, - {"GL_EXT_texture_edge_clamp", NULL}, - {"GL_EXT_texture_env_combine", NULL}, - {"GL_EXT_texture_env_dot3", NULL}, - {"GL_EXT_texture_filter_anisotropic", NULL}, - {"GL_EXT_texture_lod_bias", NULL}, - {"GL_3DFX_texture_compression_FXT1", NULL}, - {"GL_APPLE_client_storage", NULL}, - {"GL_MESA_pack_invert", NULL}, - {"GL_MESA_ycbcr_texture", NULL}, - {"GL_NV_blend_square", NULL}, - {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, - {"GL_NV_vertex_program1_1", NULL}, - {"GL_SGIS_generate_mipmap", NULL }, - {NULL, NULL} -}; - - - -#ifdef DEBUG -static const struct dri_debug_control debug_control[] = { - {"ioctl", DEBUG_IOCTL}, - {"bat", DEBUG_BATCH}, - {"lock", DEBUG_LOCK}, - {"swap", DEBUG_SWAP}, - {NULL, 0} -}; -#endif - - - -static void -intel_lock_hardware(struct intel_be_context *context) -{ - struct intel_context *intel = (struct intel_context *)context; - LOCK_HARDWARE(intel); -} - -static void -intel_unlock_hardware(struct intel_be_context *context) -{ - struct intel_context *intel = (struct intel_context *)context; - UNLOCK_HARDWARE(intel); -} - -static boolean -intel_locked_hardware(struct intel_be_context *context) -{ - struct intel_context *intel = (struct intel_context *)context; - return intel->locked ? TRUE : FALSE; -} - -GLboolean -intelCreateContext(const __GLcontextModes * visual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate) -{ - struct intel_context *intel = CALLOC_STRUCT(intel_context); - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - struct intel_screen *intelScreen = intel_screen(sPriv); - drmI830Sarea *saPriv = intelScreen->sarea; - int fthrottle_mode; - GLboolean havePools; - struct pipe_context *pipe; - struct st_context *st_share = NULL; - - if (sharedContextPrivate) { - st_share = ((struct intel_context *) sharedContextPrivate)->st; - } - - driContextPriv->driverPrivate = intel; - intel->intelScreen = intelScreen; - intel->driScreen = sPriv; - intel->sarea = saPriv; - - driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, - intel->driScreen->myNum, "i915"); - - - /* - * memory pools - */ - DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); - // ZZZ JB should be per screen and not be done per context - havePools = intelCreatePools(sPriv); - DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); - if (!havePools) - return GL_FALSE; - - - /* Dri stuff */ - intel->hHWContext = driContextPriv->hHWContext; - intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; - - fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); - intel->iw.irq_seq = -1; - intel->irqsEmitted = 0; - - intel->last_swap_fence = NULL; - intel->first_swap_fence = NULL; - -#ifdef DEBUG - __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); -#endif - intel->base.hardware_lock = intel_lock_hardware; - intel->base.hardware_unlock = intel_unlock_hardware; - intel->base.hardware_locked = intel_locked_hardware; - - intel_be_init_context(&intel->base, &intelScreen->base); - - /* - * Pipe-related setup - */ - if (getenv("INTEL_SP")) { - /* use softpipe driver instead of hw */ - pipe = intel_create_softpipe( intel, &intelScreen->base.base ); - } - else { - switch (intel->intelScreen->deviceID) { - case PCI_CHIP_I945_G: - case PCI_CHIP_I945_GM: - case PCI_CHIP_I945_GME: - case PCI_CHIP_G33_G: - case PCI_CHIP_Q33_G: - case PCI_CHIP_Q35_G: - case PCI_CHIP_I915_G: - case PCI_CHIP_I915_GM: - pipe = i915_create_context(intelScreen->base.screen, - &intelScreen->base.base, - &intel->base.base); - break; - default: - fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", - intel->intelScreen->deviceID, __FUNCTION__); - - pipe = intel_create_softpipe( intel, &intelScreen->base.base ); - break; - } - } - - pipe->priv = intel; - - intel->st = st_create_context(pipe, visual, st_share); - - driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE ); - - return GL_TRUE; -} - - -void -intelDestroyContext(__DRIcontextPrivate * driContextPriv) -{ - struct intel_context *intel = intel_context(driContextPriv); - - assert(intel); /* should never be null */ - if (intel) { - st_finish(intel->st); - - if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(&intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - if (intel->first_swap_fence) { - driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = NULL; - } - - if (intel->intelScreen->dummyContext == intel) - intel->intelScreen->dummyContext = NULL; - - st_destroy_context(intel->st); - intel_be_destroy_context(&intel->base); - free(intel); - } -} - - -GLboolean -intelUnbindContext(__DRIcontextPrivate * driContextPriv) -{ - struct intel_context *intel = intel_context(driContextPriv); - st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL); - /* XXX make_current(NULL)? */ - return GL_TRUE; -} - - -GLboolean -intelMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv) -{ - if (driContextPriv) { - struct intel_context *intel = intel_context(driContextPriv); - struct intel_framebuffer *draw_fb = intel_framebuffer(driDrawPriv); - struct intel_framebuffer *read_fb = intel_framebuffer(driReadPriv); - - assert(draw_fb->stfb); - assert(read_fb->stfb); - - /* This is for situations in which we need a rendering context but - * there may not be any currently bound. - */ - intel->intelScreen->dummyContext = intel; - - st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); - - if ((intel->driDrawable != driDrawPriv) || - (intel->lastStamp != driDrawPriv->lastStamp)) { - intel->driDrawable = driDrawPriv; - intelUpdateWindowSize(driDrawPriv); - intel->lastStamp = driDrawPriv->lastStamp; - } - - /* The size of the draw buffer will have been updated above. - * If the readbuffer is a different window, check/update its size now. - */ - if (driReadPriv != driDrawPriv) { - intelUpdateWindowSize(driReadPriv); - } - - } - else { - st_make_current(NULL, NULL, NULL); - } - - return GL_TRUE; -} diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h deleted file mode 100644 index ced18da143..0000000000 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ /dev/null @@ -1,164 +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. - * - **************************************************************************/ - -#ifndef INTEL_CONTEXT_H -#define INTEL_CONTEXT_H - -#include -#include "drm.h" - -#include "pipe/p_debug.h" - -#include "intel_screen.h" -#include "i915_drm.h" - -#include "intel_drm/intel_be_context.h" - - -struct pipe_context; -struct intel_context; -struct _DriBufferObject; -struct st_context; - - -#define INTEL_MAX_FIXUP 64 - -/** - * Intel rendering context, contains a state tracker and intel-specific info. - */ -struct intel_context -{ - struct intel_be_context base; - struct st_context *st; - - struct _DriFenceObject *last_swap_fence; - struct _DriFenceObject *first_swap_fence; - -// struct intel_batchbuffer *batch; - - boolean locked; - char *prevLockFile; - int prevLockLine; - - uint irqsEmitted; - drm_i915_irq_wait_t iw; - - drm_context_t hHWContext; - drmLock *driHwLock; - int driFd; - - __DRIdrawablePrivate *driDrawable; - __DRIscreenPrivate *driScreen; - struct intel_screen *intelScreen; - drmI830Sarea *sarea; - - uint lastStamp; - - /** - * Configuration cache - */ - driOptionCache optionCache; -}; - - - -/** - * Intel framebuffer. - */ -struct intel_framebuffer -{ - struct st_framebuffer *stfb; - - /* other fields TBD */ - int other; -}; - - - - -/* These are functions now: - */ -void LOCK_HARDWARE( struct intel_context *intel ); -void UNLOCK_HARDWARE( struct intel_context *intel ); - -extern char *__progname; - - - -/* ================================================================ - * Debugging: - */ -#ifdef DEBUG -extern int __intel_debug; - -#define DEBUG_SWAP 0x1 -#define DEBUG_LOCK 0x2 -#define DEBUG_IOCTL 0x4 -#define DEBUG_BATCH 0x8 - -#define DBG(flag, ...) do { \ - if (__intel_debug & (DEBUG_##flag)) \ - printf(__VA_ARGS__); \ -} while(0) - -#else -#define DBG(flag, ...) -#endif - - - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GME 0x27AE -#define PCI_CHIP_G33_G 0x29C2 -#define PCI_CHIP_Q35_G 0x29B2 -#define PCI_CHIP_Q33_G 0x29D2 - - -/** Cast wrapper */ -static INLINE struct intel_context * -intel_context(__DRIcontextPrivate *driContextPriv) -{ - return (struct intel_context *) driContextPriv->driverPrivate; -} - - -/** Cast wrapper */ -static INLINE struct intel_framebuffer * -intel_framebuffer(__DRIdrawablePrivate * driDrawPriv) -{ - return (struct intel_framebuffer *) driDrawPriv->driverPrivate; -} - - -#endif diff --git a/src/gallium/winsys/dri/intel/intel_lock.c b/src/gallium/winsys/dri/intel/intel_lock.c deleted file mode 100644 index 406284c98f..0000000000 --- a/src/gallium/winsys/dri/intel/intel_lock.c +++ /dev/null @@ -1,102 +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 "main/glheader.h" -#include "glapi/glthread.h" -#include -#include "state_tracker/st_public.h" -#include "intel_context.h" -#include "i830_dri.h" - - - -_glthread_DECLARE_STATIC_MUTEX( lockMutex ); - - -static void -intelContendedLock(struct intel_context *intel, uint flags) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - __DRIscreenPrivate *sPriv = intel->driScreen; - struct intel_screen *intelScreen = intel_screen(sPriv); - drmI830Sarea *sarea = intel->sarea; - - drmGetLock(intel->driFd, intel->hHWContext, flags); - - DBG(LOCK, "%s - got contended lock\n", __progname); - - /* 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); - - if (sarea->width != intelScreen->front.width || - sarea->height != intelScreen->front.height) { - - intelUpdateScreenRotation(sPriv, sarea); - } -} - - -/* Lock the hardware and validate our state. - */ -void LOCK_HARDWARE( struct intel_context *intel ) -{ - char __ret = 0; - - _glthread_LOCK_MUTEX(lockMutex); - assert(!intel->locked); - - DRM_CAS(intel->driHwLock, intel->hHWContext, - (DRM_LOCK_HELD|intel->hHWContext), __ret); - - if (__ret) - intelContendedLock( intel, 0 ); - - DBG(LOCK, "%s - locked\n", __progname); - - intel->locked = 1; -} - - -/* Unlock the hardware using the global current context - */ -void UNLOCK_HARDWARE( struct intel_context *intel ) -{ - assert(intel->locked); - intel->locked = 0; - - DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); - - _glthread_UNLOCK_MUTEX(lockMutex); - - DBG(LOCK, "%s - unlocked\n", __progname); -} diff --git a/src/gallium/winsys/dri/intel/intel_reg.h b/src/gallium/winsys/dri/intel/intel_reg.h deleted file mode 100644 index 4f33bee438..0000000000 --- a/src/gallium/winsys/dri/intel/intel_reg.h +++ /dev/null @@ -1,53 +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. - * - **************************************************************************/ - - -#ifndef _INTEL_REG_H_ -#define _INTEL_REG_H_ - - -#define BR00_BITBLT_CLIENT 0x40000000 -#define BR00_OP_COLOR_BLT 0x10000000 -#define BR00_OP_SRC_COPY_BLT 0x10C00000 -#define BR13_SOLID_PATTERN 0x80000000 - -#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) -#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) -#define XY_COLOR_BLT_WRITE_RGB (1<<20) - -#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) -#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) -#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) - -#define MI_WAIT_FOR_EVENT ((0x3<<23)) -#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) -#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) - -#define MI_BATCH_BUFFER_END (0xA<<23) - - -#endif diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c deleted file mode 100644 index b3022fd17a..0000000000 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ /dev/null @@ -1,607 +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 "utils.h" -#include "vblank.h" -#include "xmlpool.h" - -#include "intel_context.h" -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_swapbuffers.h" - -#include "i830_dri.h" -#include "intel_drm/ws_dri_bufpool.h" - -#include "pipe/p_context.h" -#include "pipe/p_screen.h" -#include "pipe/p_inlines.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_cb_fbo.h" - -static void -intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle); - -static void -intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle) -{ - struct pipe_screen *screen = intelScreen->base.screen; - struct pipe_texture *texture; - struct pipe_texture templat; - struct pipe_surface *surface; - struct pipe_buffer *buffer; - unsigned pitch; - - assert(intelScreen->front.cpp == 4); - - buffer = intel_be_buffer_from_handle(&intelScreen->base, - "front", handle); - - if (!buffer) - return; - - intelScreen->front.buffer = dri_bo(buffer); - - memset(&templat, 0, sizeof(templat)); - templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; - templat.target = PIPE_TEXTURE_2D; - templat.last_level = 0; - templat.depth[0] = 1; - templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; - templat.width[0] = intelScreen->front.width; - templat.height[0] = intelScreen->front.height; - pf_get_block(templat.format, &templat.block); - pitch = intelScreen->front.pitch; - - texture = screen->texture_blanket(screen, - &templat, - &pitch, - buffer); - - /* Unref the buffer we don't need it anyways */ - pipe_buffer_reference(screen->winsys, &buffer, NULL); - - surface = screen->get_tex_surface(screen, - texture, - 0, - 0, - 0, - PIPE_BUFFER_USAGE_GPU_WRITE); - - intelScreen->front.texture = texture; - intelScreen->front.surface = surface; -} - -PUBLIC const char __driConfigOptions[] = - DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE - DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) - DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) - DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY -// DRI_CONF_FORCE_S3TC_ENABLE(false) - DRI_CONF_ALLOW_LARGE_TEXTURES(1) - DRI_CONF_SECTION_END DRI_CONF_END; - -const uint __driNConfigOptions = 3; - -#ifdef USE_NEW_INTERFACE -static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; -#endif /*USE_NEW_INTERFACE */ - -extern const struct dri_extension card_extensions[]; - - - - -static void -intelPrintDRIInfo(struct intel_screen * intelScreen, - __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) -{ - fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", - intelScreen->front.size, intelScreen->front.offset, - intelScreen->front.pitch); - fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); -} - - -#if 0 -static void -intelPrintSAREA(const drmI830Sarea * sarea) -{ - fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, - sarea->height); - fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); - fprintf(stderr, - "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->front_offset, sarea->front_size, - (unsigned) sarea->front_handle); - fprintf(stderr, - "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->back_offset, sarea->back_size, - (unsigned) sarea->back_handle); - fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->depth_offset, sarea->depth_size, - (unsigned) sarea->depth_handle); - fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); - fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); - fprintf(stderr, - "SAREA: rotated offset: 0x%08x size: 0x%x\n", - sarea->rotated_offset, sarea->rotated_size); - fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); -} -#endif - - -/** - * Use the information in the sarea to update the screen parameters - * related to screen rotation. Needs to be called locked. - */ -void -intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) -{ - struct intel_screen *intelScreen = intel_screen(sPriv); - - if (intelScreen->front.map) { - drmUnmap(intelScreen->front.map, intelScreen->front.size); - intelScreen->front.map = NULL; - } - - if (intelScreen->front.buffer) - driDeleteBuffers(1, &intelScreen->front.buffer); - - intelScreen->front.width = sarea->width; - intelScreen->front.height = sarea->height; - intelScreen->front.offset = sarea->front_offset; - intelScreen->front.pitch = sarea->pitch * intelScreen->front.cpp; - intelScreen->front.size = sarea->front_size; - intelScreen->front.handle = sarea->front_handle; - - assert( sarea->front_size >= - intelScreen->front.pitch * intelScreen->front.height ); - -#if 0 /* JB not important */ - if (!sarea->front_handle) - return; - - if (drmMap(sPriv->fd, - sarea->front_handle, - intelScreen->front.size, - (drmAddress *) & intelScreen->front.map) != 0) { - fprintf(stderr, "drmMap(frontbuffer) failed!\n"); - return; - } -#endif - -#if 0 /* JB */ - if (intelScreen->staticPool) { - driGenBuffers(intelScreen->staticPool, "static region", 1, - &intelScreen->front.buffer, 64, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - - driBOSetStatic(intelScreen->front.buffer, - intelScreen->front.offset, - intelScreen->front.pitch * intelScreen->front.height, - intelScreen->front.map, 0); - } -#else - if (intelScreen->base.staticPool) { - if (intelScreen->front.buffer) { - driBOUnReference(intelScreen->front.buffer); - pipe_surface_reference(&intelScreen->front.surface, NULL); - pipe_texture_reference(&intelScreen->front.texture, NULL); - } - intelCreateSurface(intelScreen, &intelScreen->base.base, sarea->front_bo_handle); - } -#endif -} - - -boolean -intelCreatePools(__DRIscreenPrivate * sPriv) -{ - //unsigned batchPoolSize = 1024*1024; - struct intel_screen *intelScreen = intel_screen(sPriv); - - if (intelScreen->havePools) - return GL_TRUE; - - intelScreen->havePools = GL_TRUE; - - intelUpdateScreenRotation(sPriv, intelScreen->sarea); - - return GL_TRUE; -} - -static const char * -intel_get_name( struct pipe_winsys *winsys ) -{ - return "Intel/DRI/ttm"; -} - -/* - * The state tracker (should!) keep track of whether the fake - * frontbuffer has been touched by any rendering since the last time - * we copied its contents to the real frontbuffer. Our task is easy: - */ -static void -intel_flush_frontbuffer( struct pipe_winsys *winsys, - struct pipe_surface *surf, - void *context_private) -{ - struct intel_context *intel = (struct intel_context *) context_private; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - intelDisplaySurface(dPriv, surf, NULL); -} - -static boolean -intelInitDriver(__DRIscreenPrivate * sPriv) -{ - struct intel_screen *intelScreen; - I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; - - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> - getProcAddress("glxEnableExtension")); - void *const psc = sPriv->psc->screenConfigs; - - if (sPriv->devPrivSize != sizeof(I830DRIRec)) { - fprintf(stderr, - "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); - return GL_FALSE; - } - - /* Allocate the private area */ - intelScreen = CALLOC_STRUCT(intel_screen); - if (!intelScreen) - return GL_FALSE; - - /* parse information in __driConfigOptions */ - driParseOptionInfo(&intelScreen->optionCache, - __driConfigOptions, __driNConfigOptions); - - sPriv->private = (void *) intelScreen; - - intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + - gDRIPriv->sarea_priv_offset); - intelScreen->deviceID = gDRIPriv->deviceID; - intelScreen->front.cpp = gDRIPriv->cpp; - intelScreen->drmMinor = sPriv->drmMinor; - - assert(gDRIPriv->bitsPerPixel == 16 || - gDRIPriv->bitsPerPixel == 32); - - intelUpdateScreenRotation(sPriv, intelScreen->sarea); - - if (0) - intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - - if (glx_enable_extension != NULL) { - (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); - (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); - (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); - } - - intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; - intelScreen->base.base.get_name = intel_get_name; - intel_be_init_device(&intelScreen->base, sPriv->fd, intelScreen->deviceID); - - return GL_TRUE; -} - - -static void -intelDestroyScreen(__DRIscreenPrivate * sPriv) -{ - struct intel_screen *intelScreen = intel_screen(sPriv); - - intel_be_destroy_device(&intelScreen->base); - /* intelUnmapScreenRegions(intelScreen); */ - - FREE(intelScreen); - sPriv->private = NULL; -} - - -/** - * This is called when we need to set up GL rendering to a new X window. - */ -static boolean -intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, - __DRIdrawablePrivate * driDrawPriv, - const __GLcontextModes * visual, boolean isPixmap) -{ - if (isPixmap) { - return GL_FALSE; /* not implemented */ - } - else { - enum pipe_format colorFormat, depthFormat, stencilFormat; - struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); - - if (!intelfb) - return GL_FALSE; - - if (visual->redBits == 5) - colorFormat = PIPE_FORMAT_R5G6B5_UNORM; - else - colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; - - if (visual->depthBits == 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (visual->depthBits == 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_NONE; - - if (visual->stencilBits == 8) - stencilFormat = PIPE_FORMAT_S8Z24_UNORM; - else - stencilFormat = PIPE_FORMAT_NONE; - - intelfb->stfb = st_create_framebuffer(visual, - colorFormat, - depthFormat, - stencilFormat, - driDrawPriv->w, - driDrawPriv->h, - (void*) intelfb); - if (!intelfb->stfb) { - free(intelfb); - return GL_FALSE; - } - - driDrawPriv->driverPrivate = (void *) intelfb; - return GL_TRUE; - } -} - -static void -intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) -{ - struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv); - assert(intelfb->stfb); - st_unreference_framebuffer(&intelfb->stfb); - free(intelfb); -} - - -/** - * Get information about previous buffer swaps. - */ -static int -intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) -{ - if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) - || (sInfo == NULL)) { - return -1; - } - - return 0; -} - - -static void -intelSetTexOffset(__DRIcontext *pDRICtx, int texname, - unsigned long long offset, int depth, uint pitch) -{ - abort(); -#if 0 - struct intel_context *intel = (struct intel_context*) - ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; - struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); - struct st_texture_object *stObj = st_texture_object(tObj); - - if (!stObj) - return; - - if (stObj->pt) - st->pipe->texture_release(intel->st->pipe, &stObj->pt); - - stObj->imageOverride = GL_TRUE; - stObj->depthOverride = depth; - stObj->pitchOverride = pitch; - - if (offset) - stObj->textureOffset = offset; -#endif -} - - -static const struct __DriverAPIRec intelAPI = { - .InitDriver = intelInitDriver, - .DestroyScreen = intelDestroyScreen, - .CreateContext = intelCreateContext, - .DestroyContext = intelDestroyContext, - .CreateBuffer = intelCreateBuffer, - .DestroyBuffer = intelDestroyBuffer, - .SwapBuffers = intelSwapBuffers, - .MakeCurrent = intelMakeCurrent, - .UnbindContext = intelUnbindContext, - .GetSwapInfo = intelGetSwapInfo, - .GetMSC = driGetMSC32, - .WaitForMSC = driWaitForMSC32, - .WaitForSBC = NULL, - .SwapBuffersMSC = NULL, - .CopySubBuffer = intelCopySubBuffer, - .setTexOffset = intelSetTexOffset, -}; - - -static __GLcontextModes * -intelFillInModes(unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, boolean have_back_buffer) -{ - __GLcontextModes *modes; - __GLcontextModes *m; - unsigned num_modes; - unsigned depth_buffer_factor; - unsigned back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't - * support pageflipping at all. - */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_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; - msaa_samples_array[0] = 0; - - /* 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; - - depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; - back_buffer_factor = (have_back_buffer) ? 3 : 1; - - num_modes = depth_buffer_factor * back_buffer_factor * 4; - - 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; - } - - modes = - (*dri_interface->createContextModes) (num_modes, - sizeof(__GLcontextModes)); - m = modes; - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, msaa_samples_array, 1, GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, msaa_samples_array, 1, GLX_DIRECT_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - - /* Mark the visual as slow if there are "fake" stencil bits. - */ - for (m = modes; m != NULL; m = m->next) { - if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { - m->visualRating = GLX_SLOW_CONFIG; - } - } - - return modes; -} - - -/** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. - * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. - */ -PUBLIC void * -__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, - __DRIscreen * psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) -{ - __DRIscreenPrivate *psp; - static const __DRIversion ddx_expected = { 1, 7, 0 }; - static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 7, 0 }; - - dri_interface = interface; - - if (!driCheckDriDdxDrmVersions2("i915", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { - return NULL; - } - - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &intelAPI); - - if (psp != NULL) { - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - *driver_modes = intelFillInModes(dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, 1); - - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create - * is called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions(NULL, card_extensions, GL_FALSE); - } - - return (void *) psp; -} - diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h deleted file mode 100644 index e62f9e71ec..0000000000 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ /dev/null @@ -1,122 +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. - * - **************************************************************************/ - -#ifndef _INTEL_SCREEN_H_ -#define _INTEL_SCREEN_H_ - -#include "dri_util.h" -#include "i830_common.h" -#include "xmlconfig.h" -#include "intel_drm/ws_dri_bufpool.h" - -#include "pipe/p_compiler.h" - -#include "intel_drm/intel_be_device.h" - -struct intel_screen -{ - struct intel_be_device base; - - struct { - drm_handle_t handle; - - /* We create a static dri buffer for the frontbuffer. - */ - struct _DriBufferObject *buffer; - struct pipe_surface *surface; - struct pipe_texture *texture; - - char *map; /* memory map */ - int offset; /* from start of video mem, in bytes */ - int pitch; /* row stride, in bytes */ - int width; - int height; - int size; - int cpp; /* for front and back buffers */ - } front; - - int deviceID; - int drmMinor; - - drmI830Sarea *sarea; - - /** - * Configuration cache with default values for all contexts - */ - driOptionCache optionCache; - - boolean havePools; - - /** - * Temporary(?) context to use for SwapBuffers or other situations in - * which we need a rendering context, but none is currently bound. - */ - struct intel_context *dummyContext; - - /* - * New stuff form the i915tex integration - */ - unsigned batch_id; - - - struct pipe_winsys *winsys; -}; - - - -/** cast wrapper */ -static INLINE struct intel_screen * -intel_screen(__DRIscreenPrivate *sPriv) -{ - return (struct intel_screen *) sPriv->private; -} - - -extern void -intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); - - -extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); - -extern boolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); - -extern boolean -intelMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv); - - -extern boolean -intelCreatePools(__DRIscreenPrivate *sPriv); - -extern boolean -intelCreateContext(const __GLcontextModes * visual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - - -#endif diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c deleted file mode 100644 index f751f97524..0000000000 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ /dev/null @@ -1,261 +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 "intel_screen.h" -#include "intel_context.h" -#include "intel_swapbuffers.h" - -#include "intel_reg.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 "intel_drm/ws_dri_bufmgr.h" -#include "intel_batchbuffer.h" - -/** - * Display a colorbuffer surface in an X window. - * Used for SwapBuffers and flushing front buffer rendering. - * - * \param dPriv the window/drawable to display into - * \param surf the surface to display - * \param rect optional subrect of surface to display (may be NULL). - */ -void -intelDisplaySurface(__DRIdrawablePrivate *dPriv, - struct pipe_surface *surf, - const drm_clip_rect_t *rect) -{ - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - struct intel_context *intel = intelScreen->dummyContext; - - DBG(SWAP, "%s\n", __FUNCTION__); - - if (!intel) { - /* XXX this is where some kind of extra/meta context could be useful */ - return; - } - - if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); - driFenceUnReference(&intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - intel->last_swap_fence = intel->first_swap_fence; - intel->first_swap_fence = NULL; - - /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets - * should work regardless. - */ - LOCK_HARDWARE(intel); - /* if this drawable isn't currently bound the LOCK_HARDWARE done on the - * current context (which is what intelScreenContext should return) might - * not get a contended lock and thus cliprects not updated (tests/manywin) - */ - if (intel_context(dPriv->driContextPriv) != intel) - DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); - - - if (dPriv && dPriv->numClipRects) { - const int srcWidth = surf->width; - const int srcHeight = surf->height; - const int nbox = dPriv->numClipRects; - const drm_clip_rect_t *pbox = dPriv->pClipRects; - const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; - const int cpp = intelScreen->front.cpp; - const int srcpitch = surf->stride / cpp; - int BR13, CMD; - int i; - - ASSERT(surf->buffer); - ASSERT(surf->cpp == cpp); - - DBG(SWAP, "screen pitch %d src surface pitch %d\n", - pitch, surf->stride); - - if (cpp == 2) { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); - CMD = XY_SRC_COPY_BLT_CMD; - } - else { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - } - - for (i = 0; i < nbox; i++, pbox++) { - drm_clip_rect_t box; - drm_clip_rect_t sbox; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > intelScreen->front.width || - pbox->y2 > intelScreen->front.height) { - /* invalid cliprect, skip it */ - continue; - } - - box = *pbox; - - if (rect) { - /* intersect cliprect with user-provided src rect */ - drm_clip_rect_t rrect; - - rrect.x1 = dPriv->x + rect->x1; - rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; - rrect.x2 = rect->x2 + rrect.x1; - rrect.y2 = rect->y2 + rrect.y1; - if (rrect.x1 > box.x1) - box.x1 = rrect.x1; - if (rrect.y1 > box.y1) - box.y1 = rrect.y1; - if (rrect.x2 < box.x2) - box.x2 = rrect.x2; - if (rrect.y2 < box.y2) - box.y2 = rrect.y2; - - if (box.x1 > box.x2 || box.y1 > box.y2) - continue; - } - - /* restrict blit to size of actually rendered area */ - if (box.x2 - box.x1 > srcWidth) - box.x2 = srcWidth + box.x1; - if (box.y2 - box.y1 > srcHeight) - box.y2 = srcHeight + box.y1; - - DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", - box.x1, box.x2, box.y1, box.y2); - - sbox.x1 = box.x1 - dPriv->x; - sbox.y1 = box.y1 - dPriv->y; - - assert(box.x1 < box.x2); - assert(box.y1 < box.y2); - - /* XXX this could be done with pipe->surface_copy() */ - /* XXX should have its own batch buffer */ - if (!BEGIN_BATCH(8, 2)) { - /* - * Since we share this batch buffer with a context - * we can't flush it since that risks a GPU lockup - */ - assert(0); - continue; - } - - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((box.y1 << 16) | box.x1); - OUT_BATCH((box.y2 << 16) | box.x2); - - OUT_RELOC(intelScreen->front.buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); - OUT_BATCH((sbox.y1 << 16) | sbox.x1); - OUT_BATCH((srcpitch * cpp) & 0xffff); - OUT_RELOC(dri_bo(surf->buffer), - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - - } - - if (intel->first_swap_fence) - driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); - } - - UNLOCK_HARDWARE(intel); - - if (intel->lastStamp != dPriv->lastStamp) { - intelUpdateWindowSize(dPriv); - intel->lastStamp = dPriv->lastStamp; - } -} - - - -/** - * This will be called whenever the currently bound window is moved/resized. - */ -void -intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) -{ - struct intel_framebuffer *intelfb = intel_framebuffer(dPriv); - assert(intelfb->stfb); - st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); -} - - - -void -intelSwapBuffers(__DRIdrawablePrivate * dPriv) -{ - struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_surface *back_surf; - - assert(intel_fb); - assert(intel_fb->stfb); - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_surf) { - st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_surf, NULL); - st_notify_swapbuffers_complete(intel_fb->stfb); - } -} - - -/** - * Called via glXCopySubBufferMESA() to copy a subrect of the back - * buffer to the front buffer/screen. - */ -void -intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) -{ - struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_surface *back_surf; - - assert(intel_fb); - assert(intel_fb->stfb); - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_surf) { - drm_clip_rect_t rect; - rect.x1 = x; - rect.y1 = y; - rect.x2 = w; - rect.y2 = h; - - st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_surf, &rect); - } -} diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.h b/src/gallium/winsys/dri/intel/intel_swapbuffers.h deleted file mode 100644 index 46c9bab3af..0000000000 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.h +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 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. - * - **************************************************************************/ - -#ifndef INTEL_SWAPBUFFERS_H -#define INTEL_SWAPBUFFERS_H - - -struct pipe_surface; - - -extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, - struct pipe_surface *surf, - const drm_clip_rect_t * rect); - -extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); - -extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, - int x, int y, int w, int h); - -extern void intelUpdateWindowSize(__DRIdrawablePrivate *dPriv); - - -#endif /* INTEL_SWAPBUFFERS_H */ diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c deleted file mode 100644 index 0d98d16cf1..0000000000 --- a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include "intel_context.h" -#include "intel_winsys_softpipe.h" -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "pipe/p_format.h" -#include "softpipe/sp_winsys.h" - - -struct intel_softpipe_winsys { - struct softpipe_winsys sws; - struct intel_context *intel; -}; - -/** - * Return list of surface formats supported by this driver. - */ -static boolean -intel_is_format_supported(struct softpipe_winsys *sws, - enum pipe_format format) -{ - switch(format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_S8Z24_UNORM: - return TRUE; - default: - return FALSE; - } -} - - -/** - * Create rendering context which uses software rendering. - */ -struct pipe_context * -intel_create_softpipe( struct intel_context *intel, - struct pipe_winsys *winsys ) -{ - struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); - struct pipe_screen *screen = softpipe_create_screen(winsys); - - /* Fill in this struct with callbacks that softpipe will need to - * communicate with the window system, buffer manager, etc. - */ - isws->sws.is_format_supported = intel_is_format_supported; - isws->intel = intel; - - /* Create the softpipe context: - */ - return softpipe_create( screen, winsys, &isws->sws ); -} diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.h b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.h deleted file mode 100644 index 5fa14cb749..0000000000 --- a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.h +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 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. - * - **************************************************************************/ - -#ifndef INTEL_SOFTPIPE_H -#define INTEL_SOFTPIPE_H - -struct pipe_winsys; -struct pipe_context; -struct intel_context; - -struct pipe_context * -intel_create_softpipe( struct intel_context *intel, - struct pipe_winsys *winsys ); - -#endif diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h deleted file mode 100644 index 3452ddb3c9..0000000000 --- a/src/gallium/winsys/dri/intel/server/i830_common.h +++ /dev/null @@ -1,255 +0,0 @@ -/************************************************************************** - -Copyright 2001 VA Linux Systems Inc., Fremont, California. -Copyright 2002 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 -on 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 -ATI, VA LINUX SYSTEMS AND/OR THEIR 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. - -**************************************************************************/ - - -#ifndef _I830_COMMON_H_ -#define _I830_COMMON_H_ - - -#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ -#define I830_LOG_MIN_TEX_REGION_SIZE 14 - - -/* Driver specific DRM command indices - * NOTE: these are not OS specific, but they are driver specific - */ -#define DRM_I830_INIT 0x00 -#define DRM_I830_FLUSH 0x01 -#define DRM_I830_FLIP 0x02 -#define DRM_I830_BATCHBUFFER 0x03 -#define DRM_I830_IRQ_EMIT 0x04 -#define DRM_I830_IRQ_WAIT 0x05 -#define DRM_I830_GETPARAM 0x06 -#define DRM_I830_SETPARAM 0x07 -#define DRM_I830_ALLOC 0x08 -#define DRM_I830_FREE 0x09 -#define DRM_I830_INIT_HEAP 0x0a -#define DRM_I830_CMDBUFFER 0x0b -#define DRM_I830_DESTROY_HEAP 0x0c -#define DRM_I830_SET_VBLANK_PIPE 0x0d -#define DRM_I830_GET_VBLANK_PIPE 0x0e -#define DRM_I830_MMIO 0x10 - -typedef struct { - enum { - I830_INIT_DMA = 0x01, - I830_CLEANUP_DMA = 0x02, - I830_RESUME_DMA = 0x03 - } func; - unsigned int mmio_offset; - int sarea_priv_offset; - unsigned int ring_start; - unsigned int ring_end; - unsigned int ring_size; - unsigned int front_offset; - unsigned int back_offset; - unsigned int depth_offset; - unsigned int w; - unsigned int h; - unsigned int pitch; - unsigned int pitch_bits; - unsigned int back_pitch; - unsigned int depth_pitch; - unsigned int cpp; - unsigned int chipset; -} drmI830Init; - -typedef struct { - drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; - int last_upload; /* last time texture was uploaded */ - int last_enqueue; /* last time a buffer was enqueued */ - int last_dispatch; /* age of the most recently dispatched buffer */ - int ctxOwner; /* last context to upload state */ - /** Last context that used the buffer manager. */ - int texAge; - int pf_enabled; /* is pageflipping allowed? */ - int pf_active; - int pf_current_page; /* which buffer is being displayed? */ - int perf_boxes; /* performance boxes to be displayed */ - int width, height; /* screen size in pixels */ - - drm_handle_t front_handle; - int front_offset; - int front_size; - - drm_handle_t back_handle; - int back_offset; - int back_size; - - drm_handle_t depth_handle; - int depth_offset; - int depth_size; - - drm_handle_t tex_handle; - int tex_offset; - int tex_size; - int log_tex_granularity; - int pitch; - int rotation; /* 0, 90, 180 or 270 */ - int rotated_offset; - int rotated_size; - int rotated_pitch; - int virtualX, virtualY; - - unsigned int front_tiled; - unsigned int back_tiled; - unsigned int depth_tiled; - unsigned int rotated_tiled; - unsigned int rotated2_tiled; - - int planeA_x; - int planeA_y; - int planeA_w; - int planeA_h; - int planeB_x; - int planeB_y; - int planeB_w; - int planeB_h; - - /* Triple buffering */ - drm_handle_t third_handle; - int third_offset; - int third_size; - unsigned int third_tiled; - - /* buffer object handles for the static buffers. May change - * over the lifetime of the client, though it doesn't in our current - * implementation. - */ - unsigned int front_bo_handle; - unsigned int back_bo_handle; - unsigned int third_bo_handle; - unsigned int depth_bo_handle; -} drmI830Sarea; - -/* Flags for perf_boxes - */ -#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ -#define I830_BOX_FLIP 0x2 /* populated by kernel */ -#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ -#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ -#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ - - -typedef struct { - int start; /* agp offset */ - int used; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ - int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ -} drmI830BatchBuffer; - -typedef struct { - char *buf; /* agp offset */ - int sz; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ - int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ -} drmI830CmdBuffer; - -typedef struct { - int *irq_seq; -} drmI830IrqEmit; - -typedef struct { - int irq_seq; -} drmI830IrqWait; - -typedef struct { - int param; - int *value; -} drmI830GetParam; - -#define I830_PARAM_IRQ_ACTIVE 1 -#define I830_PARAM_ALLOW_BATCHBUFFER 2 - -typedef struct { - int param; - int value; -} drmI830SetParam; - -#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 -#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 -#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 - - -/* A memory manager for regions of shared memory: - */ -#define I830_MEM_REGION_AGP 1 - -typedef struct { - int region; - int alignment; - int size; - int *region_offset; /* offset from start of fb or agp */ -} drmI830MemAlloc; - -typedef struct { - int region; - int region_offset; -} drmI830MemFree; - -typedef struct { - int region; - int size; - int start; -} drmI830MemInitHeap; - -typedef struct { - int region; -} drmI830MemDestroyHeap; - -#define DRM_I830_VBLANK_PIPE_A 1 -#define DRM_I830_VBLANK_PIPE_B 2 - -typedef struct { - int pipe; -} drmI830VBlankPipe; - -#define MMIO_READ 0 -#define MMIO_WRITE 1 - -#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 -#define MMIO_REGS_IA_VERTICES_COUNT 1 -#define MMIO_REGS_VS_INVOCATION_COUNT 2 -#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 -#define MMIO_REGS_GS_INVOCATION_COUNT 4 -#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 -#define MMIO_REGS_CL_INVOCATION_COUNT 6 -#define MMIO_REGS_PS_INVOCATION_COUNT 7 -#define MMIO_REGS_PS_DEPTH_COUNT 8 - -typedef struct { - unsigned int read_write:1; - unsigned int reg:31; - void __user *data; -} drmI830MMIO; - -#endif /* _I830_DRM_H_ */ diff --git a/src/gallium/winsys/dri/intel/server/i830_dri.h b/src/gallium/winsys/dri/intel/server/i830_dri.h deleted file mode 100644 index 0d514b6c38..0000000000 --- a/src/gallium/winsys/dri/intel/server/i830_dri.h +++ /dev/null @@ -1,62 +0,0 @@ - -#ifndef _I830_DRI_H -#define _I830_DRI_H - -#include "xf86drm.h" -#include "i830_common.h" - -#define I830_MAX_DRAWABLES 256 - -#define I830_MAJOR_VERSION 1 -#define I830_MINOR_VERSION 7 -#define I830_PATCHLEVEL 2 - -#define I830_REG_SIZE 0x80000 - -typedef struct _I830DRIRec { - drm_handle_t regs; - drmSize regsSize; - - drmSize unused1; /* backbufferSize */ - drm_handle_t unused2; /* backbuffer */ - - drmSize unused3; /* depthbufferSize */ - drm_handle_t unused4; /* depthbuffer */ - - drmSize unused5; /* rotatedSize */ - drm_handle_t unused6; /* rotatedbuffer */ - - drm_handle_t unused7; /* textures */ - int unused8; /* textureSize */ - - drm_handle_t unused9; /* agp_buffers */ - drmSize unused10; /* agp_buf_size */ - - int deviceID; - int width; - int height; - int mem; - int cpp; - int bitsPerPixel; - - int unused11[8]; /* was front/back/depth/rotated offset/pitch */ - - int unused12; /* logTextureGranularity */ - int unused13; /* textureOffset */ - - int irq; - int sarea_priv_offset; -} I830DRIRec, *I830DRIPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830ConfigPrivRec, *I830ConfigPrivPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830DRIContextRec, *I830DRIContextPtr; - - -#endif diff --git a/src/gallium/winsys/drm/Makefile b/src/gallium/winsys/drm/Makefile new file mode 100644 index 0000000000..f466ce6c3c --- /dev/null +++ b/src/gallium/winsys/drm/Makefile @@ -0,0 +1,38 @@ +# src/mesa/drivers/dri/Makefile + +TOP = ../../../.. + +include $(TOP)/configs/current + + + +default: $(TOP)/$(LIB_DIR) subdirs + + +$(TOP)/$(LIB_DIR): + -mkdir $(TOP)/$(LIB_DIR) + + +subdirs: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +install: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) install) || exit 1 ; \ + fi \ + done + + +clean: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) clean) ; \ + fi \ + done + -rm -f common/*.o diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template new file mode 100644 index 0000000000..80e817b808 --- /dev/null +++ b/src/gallium/winsys/drm/Makefile.template @@ -0,0 +1,125 @@ +# -*-makefile-*- + +MESA_MODULES = \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + +COMMON_GALLIUM_SOURCES = \ + $(TOP)/src/mesa/drivers/dri/common/utils.c \ + $(TOP)/src/mesa/drivers/dri/common/vblank.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_util.c \ + $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c + +COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ + $(TOP)/src/mesa/drivers/common/driverfuncs.c \ + $(TOP)/src/mesa/drivers/dri/common/texmem.c \ + $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c + +COMMON_BM_SOURCES = \ + $(TOP)/src/mesa/drivers/dri/common/dri_bufmgr.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_drmpool.c + + +ifeq ($(WINDOW_SYSTEM),dri) +WINOBJ= +WINLIB= +INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) + +OBJECTS = \ + $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) + +else +# miniglx +WINOBJ= +WINLIB=-L$(MESA)/src/glx/mini +MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini +INCLUDES = $(MINIGLX_INCLUDES) \ + $(SHARED_INCLUDES) \ + $(PCIACCESS_CFLAGS) + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(MINIGLX_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) +endif + + +### Include directories +SHARED_INCLUDES = \ + -I. \ + -I$(TOP)/src/mesa/drivers/dri/common \ + -Iserver \ + -I$(TOP)/include \ + -I$(TOP)/include/GL/internal \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/winsys/common \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/mesa/glapi \ + -I$(TOP)/src/mesa/math \ + -I$(TOP)/src/mesa/transform \ + -I$(TOP)/src/mesa/shader \ + -I$(TOP)/src/mesa/swrast \ + -I$(TOP)/src/mesa/swrast_setup \ + -I$(TOP)/src/egl/main \ + -I$(TOP)/src/egl/drivers/dri \ + $(LIBDRM_CFLAGS) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR)/$(LIBNAME_EGL) + + +$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template + $(TOP)/bin/mklib -noprefix -o $@ \ + $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) + +$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS) + $(TOP)/bin/mklib -o $(LIBNAME_EGL) \ + -linker "$(CC)" \ + -noprefix \ + $(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \ + --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive + +$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) + $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) + +$(TOP)/$(LIB_DIR)/$(LIBNAME_EGL): $(LIBNAME_EGL) + $(INSTALL) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR) + +depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +install: $(LIBNAME) + $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) + $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + + +include depend diff --git a/src/gallium/winsys/drm/SConscript b/src/gallium/winsys/drm/SConscript new file mode 100644 index 0000000000..aef5210a32 --- /dev/null +++ b/src/gallium/winsys/drm/SConscript @@ -0,0 +1,54 @@ +Import('*') + +if env['dri']: + + drienv = env.Clone() + + drienv.Replace(CPPPATH = [ + '#src/mesa/drivers/dri/common', + '#include', + '#include/GL/internal', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/gallium/drivers', + '#src/mesa', + '#src/mesa/main', + '#src/mesa/glapi', + '#src/mesa/math', + '#src/mesa/transform', + '#src/mesa/shader', + '#src/mesa/swrast', + '#src/mesa/swrast_setup', + '#src/egl/main', + '#src/egl/drivers/dri', + ]) + + drienv.ParseConfig('pkg-config --cflags --libs libdrm') + + COMMON_GALLIUM_SOURCES = [ + '#src/mesa/drivers/dri/common/utils.c', + '#src/mesa/drivers/dri/common/vblank.c', + '#src/mesa/drivers/dri/common/dri_util.c', + '#src/mesa/drivers/dri/common/xmlconfig.c', + ] + + COMMON_BM_SOURCES = [ + '#src/mesa/drivers/dri/common/dri_bufmgr.c', + '#src/mesa/drivers/dri/common/dri_drmpool.c', + ] + + Export([ + 'drienv', + 'COMMON_GALLIUM_SOURCES', + 'COMMON_BM_SOURCES', + ]) + + # TODO: Installation + #install: $(LIBNAME) + # $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) + # $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + + if 'intel' in env['winsys']: + SConscript([ + 'intel/SConscript', + ]) diff --git a/src/gallium/winsys/drm/intel/Makefile b/src/gallium/winsys/drm/intel/Makefile new file mode 100644 index 0000000000..a670ac044d --- /dev/null +++ b/src/gallium/winsys/drm/intel/Makefile @@ -0,0 +1,25 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + + +SUBDIRS = common dri egl + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` + rm -f `find . -name depend` + + +# Dummy install target +install: diff --git a/src/gallium/winsys/drm/intel/common/Makefile b/src/gallium/winsys/drm/intel/common/Makefile new file mode 100644 index 0000000000..bf1a7d691f --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/Makefile @@ -0,0 +1,23 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +LIBNAME = inteldrm + +C_SOURCES = \ + intel_be_batchbuffer.c \ + intel_be_context.c \ + intel_be_device.c \ + ws_dri_bufmgr.c \ + ws_dri_drmpool.c \ + ws_dri_fencemgr.c \ + ws_dri_mallocpool.c \ + ws_dri_slabpool.c + + +include ./Makefile.template + +DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \ + && pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") +symlinks: + diff --git a/src/gallium/winsys/drm/intel/common/Makefile.template b/src/gallium/winsys/drm/intel/common/Makefile.template new file mode 100644 index 0000000000..02ed363a43 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/Makefile.template @@ -0,0 +1,64 @@ +# -*-makefile-*- + + +# We still have a dependency on the "dri" buffer manager. Most likely +# the interface can be reused in non-dri environments, and also as a +# frontend to simpler memory managers. +# +COMMON_SOURCES = + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(CPP_SOURCES:.cpp=.o) \ + $(ASM_SOURCES:.S=.o) + + +### Include directories +INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/include \ + $(DRIVER_INCLUDES) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) + + +$(LIBNAME): $(OBJECTS) Makefile Makefile.template + $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) + + +depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean:: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +include depend diff --git a/src/gallium/winsys/drm/intel/common/glthread.h b/src/gallium/winsys/drm/intel/common/glthread.h new file mode 100644 index 0000000000..b8e9d5f59b --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/glthread.h @@ -0,0 +1,359 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.2 + * + * Copyright (C) 1999-2006 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + + +/* + * Thread support for gl dispatch. + * + * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) + * and Christoph Poliwoda (poliwoda@volumegraphics.com) + * Revised by Keith Whitwell + * Adapted for new gl dispatcher by Brian Paul + * + * + * + * DOCUMENTATION + * + * This thread module exports the following types: + * _glthread_TSD Thread-specific data area + * _glthread_Thread Thread datatype + * _glthread_Mutex Mutual exclusion lock + * + * Macros: + * _glthread_DECLARE_STATIC_MUTEX(name) Declare a non-local mutex + * _glthread_INIT_MUTEX(name) Initialize a mutex + * _glthread_LOCK_MUTEX(name) Lock a mutex + * _glthread_UNLOCK_MUTEX(name) Unlock a mutex + * + * Functions: + * _glthread_GetID(v) Get integer thread ID + * _glthread_InitTSD() Initialize thread-specific data + * _glthread_GetTSD() Get thread-specific data + * _glthread_SetTSD() Set thread-specific data + * + */ + +/* + * If this file is accidentally included by a non-threaded build, + * it should not cause the build to fail, or otherwise cause problems. + * In general, it should only be included when needed however. + */ + +#ifndef GLTHREAD_H +#define GLTHREAD_H + + +#if defined(USE_MGL_NAMESPACE) +#define _glapi_Dispatch _mglapi_Dispatch +#endif + + + +#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\ + defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \ + && !defined(THREADS) +# define THREADS +#endif + +#ifdef VMS +#include +#endif + +/* + * POSIX threads. This should be your choice in the Unix world + * whenever possible. When building with POSIX threads, be sure + * to enable any compiler flags which will cause the MT-safe + * libc (if one exists) to be used when linking, as well as any + * header macros for MT-safe errno, etc. For Solaris, this is the -mt + * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable + * proper compiling for MT-safe libc etc. + */ +#if defined(PTHREADS) +#include /* POSIX threads headers */ + +typedef struct { + pthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef pthread_t _glthread_Thread; + +typedef pthread_mutex_t _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = PTHREAD_MUTEX_INITIALIZER + +#define _glthread_INIT_MUTEX(name) \ + pthread_mutex_init(&(name), NULL) + +#define _glthread_DESTROY_MUTEX(name) \ + pthread_mutex_destroy(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) pthread_mutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) pthread_mutex_unlock(&(name)) + +typedef pthread_cond_t _glthread_Cond; + +#define _glthread_DECLARE_STATIC_COND(name) \ + static _glthread_Cond name = PTHREAD_COND_INITIALIZER + +#define _glthread_INIT_COND(cond) \ + pthread_cond_init(&(cond), NULL) + +#define _glthread_DESTROY_COND(name) \ + pthread_cond_destroy(&(name)) + +#define _glthread_COND_WAIT(cond, mutex) \ + pthread_cond_wait(&(cond), &(mutex)) + +#define _glthread_COND_SIGNAL(cond) \ + pthread_cond_signal(&(cond)) + +#define _glthread_COND_BROADCAST(cond) \ + pthread_cond_broadcast(&(cond)) + + +#else /* PTHREADS */ + +typedef unsigned int _glthread_Cond; +#define _glthread_DECLARE_STATIC_COND(name) \ +// #warning Condition variables not implemented. + +#define _glthread_INIT_COND(cond) \ + abort(); + +#define _glthread_DESTROY_COND(name) \ + abort(); + +#define _glthread_COND_WAIT(cond, mutex) \ + abort(); + +#define _glthread_COND_SIGNAL(cond) \ + abort(); + +#define _glthread_COND_BROADCAST(cond) \ + abort(); + +#endif + + +/* + * Solaris threads. Use only up to Solaris 2.4. + * Solaris 2.5 and higher provide POSIX threads. + * Be sure to compile with -mt on the Solaris compilers, or + * use -D_REENTRANT if using gcc. + */ +#ifdef SOLARIS_THREADS +#include + +typedef struct { + thread_key_t key; + mutex_t keylock; + int initMagic; +} _glthread_TSD; + +typedef thread_t _glthread_Thread; + +typedef mutex_t _glthread_Mutex; + +/* XXX need to really implement mutex-related macros */ +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 +#define _glthread_INIT_MUTEX(name) (void) name +#define _glthread_DESTROY_MUTEX(name) (void) name +#define _glthread_LOCK_MUTEX(name) (void) name +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* SOLARIS_THREADS */ + + + + +/* + * Windows threads. Should work with Windows NT and 95. + * IMPORTANT: Link with multithreaded runtime library when THREADS are + * used! + */ +#ifdef WIN32_THREADS +#include + +typedef struct { + DWORD key; + int initMagic; +} _glthread_TSD; + +typedef HANDLE _glthread_Thread; + +typedef CRITICAL_SECTION _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) /*static*/ _glthread_Mutex name = {0,0,0,0,0,0} +#define _glthread_INIT_MUTEX(name) InitializeCriticalSection(&name) +#define _glthread_DESTROY_MUTEX(name) DeleteCriticalSection(&name) +#define _glthread_LOCK_MUTEX(name) EnterCriticalSection(&name) +#define _glthread_UNLOCK_MUTEX(name) LeaveCriticalSection(&name) + +#endif /* WIN32_THREADS */ + + + + +/* + * XFree86 has its own thread wrapper, Xthreads.h + * We wrap it again for GL. + */ +#ifdef USE_XTHREADS +#include + +typedef struct { + xthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef xthread_t _glthread_Thread; + +typedef xmutex_rec _glthread_Mutex; + +#ifdef XMUTEX_INITIALIZER +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = XMUTEX_INITIALIZER +#else +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name +#endif + +#define _glthread_INIT_MUTEX(name) \ + xmutex_init(&(name)) + +#define _glthread_DESTROY_MUTEX(name) \ + xmutex_clear(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) xmutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) xmutex_unlock(&(name)) + +#endif /* USE_XTHREADS */ + + + +/* + * BeOS threads. R5.x required. + */ +#ifdef BEOS_THREADS + +#include +#include + +typedef struct { + int32 key; + int initMagic; +} _glthread_TSD; + +typedef thread_id _glthread_Thread; + +/* Use Benaphore, aka speeder semaphore */ +typedef struct { + int32 lock; + sem_id sem; +} benaphore; +typedef benaphore _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = { 0, 0 } +#define _glthread_INIT_MUTEX(name) name.sem = create_sem(0, #name"_benaphore"), name.lock = 0 +#define _glthread_DESTROY_MUTEX(name) delete_sem(name.sem), name.lock = 0 +#define _glthread_LOCK_MUTEX(name) if (name.sem == 0) _glthread_INIT_MUTEX(name); \ + if (atomic_add(&(name.lock), 1) >= 1) acquire_sem(name.sem) +#define _glthread_UNLOCK_MUTEX(name) if (atomic_add(&(name.lock), -1) > 1) release_sem(name.sem) + +#endif /* BEOS_THREADS */ + + + +#ifndef THREADS + +/* + * THREADS not defined + */ + +typedef GLuint _glthread_TSD; + +typedef GLuint _glthread_Thread; + +typedef GLuint _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 + +#define _glthread_INIT_MUTEX(name) (void) name + +#define _glthread_DESTROY_MUTEX(name) (void) name + +#define _glthread_LOCK_MUTEX(name) (void) name + +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* THREADS */ + + + +/* + * Platform independent thread specific data API. + */ + +extern unsigned long +_glthread_GetID(void); + + +extern void +_glthread_InitTSD(_glthread_TSD *); + + +extern void * +_glthread_GetTSD(_glthread_TSD *); + + +extern void +_glthread_SetTSD(_glthread_TSD *, void *); + +#if defined(GLX_USE_TLS) + +extern __thread struct _glapi_table * _glapi_tls_Dispatch + __attribute__((tls_model("initial-exec"))); + +#define GET_DISPATCH() _glapi_tls_Dispatch + +#elif !defined(GL_CALL) +# if defined(THREADS) +# define GET_DISPATCH() \ + ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ + ? _glapi_Dispatch : _glapi_get_dispatch()) +# else +# define GET_DISPATCH() _glapi_Dispatch +# endif /* defined(THREADS) */ +#endif /* ndef GL_CALL */ + + +#endif /* THREADS_H */ diff --git a/src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.c new file mode 100644 index 0000000000..bc13a5761e --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.c @@ -0,0 +1,429 @@ + +#include "intel_be_batchbuffer.h" +#include "intel_be_context.h" +#include "intel_be_device.h" +#include + +#include "xf86drm.h" + +static void +intel_realloc_relocs(struct intel_be_batchbuffer *batch, int num_relocs) +{ + unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; + + size *= sizeof(uint32_t); + batch->reloc = realloc(batch->reloc, size); + batch->reloc_size = num_relocs; +} + + +void +intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch) +{ + /* + * Get a new, free batchbuffer. + */ + drmBO *bo; + struct drm_bo_info_req *req; + + driBOUnrefUserList(batch->list); + driBOResetList(batch->list); + + /* base.size is the size available to the i915simple driver */ + batch->base.size = batch->device->max_batch_size - BATCH_RESERVED; + batch->base.actual_size = batch->device->max_batch_size; + driBOData(batch->buffer, batch->base.actual_size, NULL, NULL, 0); + + /* + * Add the batchbuffer to the validate list. + */ + + driBOAddListItem(batch->list, batch->buffer, + DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, + &batch->dest_location, &batch->node); + + req = &batch->node->bo_arg.d.req.bo_req; + + /* + * Set up information needed for us to make relocations + * relative to the underlying drm buffer objects. + */ + + driReadLockKernelBO(); + bo = driBOKernel(batch->buffer); + req->presumed_offset = (uint64_t) bo->offset; + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + batch->drmBOVirtual = (uint8_t *) bo->virtual; + driReadUnlockKernelBO(); + + /* + * Adjust the relocation buffer size. + */ + + if (batch->reloc_size > INTEL_MAX_RELOCS || + batch->reloc == NULL) + intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); + + assert(batch->reloc != NULL); + batch->reloc[0] = 0; /* No relocs yet. */ + batch->reloc[1] = 1; /* Reloc type 1 */ + batch->reloc[2] = 0; /* Only a single relocation list. */ + batch->reloc[3] = 0; /* Only a single relocation list. */ + + batch->base.map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->poolOffset = driBOPoolOffset(batch->buffer); + batch->base.ptr = batch->base.map; + batch->dirty_state = ~0; + batch->nr_relocs = 0; + batch->flags = 0; + batch->id = 0;//batch->intel->intelScreen->batch_id++; +} + +/*====================================================================== + * Public functions + */ +struct intel_be_batchbuffer * +intel_be_batchbuffer_alloc(struct intel_be_context *intel) +{ + struct intel_be_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + batch->device = intel->device; + + driGenBuffers(intel->device->batchPool, "batchbuffer", 1, + &batch->buffer, 4096, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); + batch->last_fence = NULL; + batch->list = driBOCreateList(20); + batch->reloc = NULL; + intel_be_batchbuffer_reset(batch); + return batch; +} + +void +intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch) +{ + if (batch->last_fence) { + driFenceFinish(batch->last_fence, + DRM_FENCE_TYPE_EXE, FALSE); + driFenceUnReference(&batch->last_fence); + } + if (batch->base.map) { + driBOUnmap(batch->buffer); + batch->base.map = NULL; + } + driBOUnReference(batch->buffer); + driBOFreeList(batch->list); + if (batch->reloc) + free(batch->reloc); + batch->buffer = NULL; + free(batch); +} + +void +intel_be_offset_relocation(struct intel_be_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask) +{ + int itemLoc; + struct _drmBONode *node; + uint32_t *reloc; + struct drm_bo_info_req *req; + + driBOAddListItem(batch->list, driBO, val_flags, val_mask, + &itemLoc, &node); + req = &node->bo_arg.d.req.bo_req; + + if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { + + /* + * Stop other threads from tampering with the underlying + * drmBO while we're reading its offset. + */ + + driReadLockKernelBO(); + req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; + driReadUnlockKernelBO(); + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + } + + pre_add += driBOPoolOffset(driBO); + + if (batch->nr_relocs == batch->reloc_size) + intel_realloc_relocs(batch, batch->reloc_size * 2); + + reloc = batch->reloc + + (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); + + reloc[0] = ((uint8_t *)batch->base.ptr - batch->drmBOVirtual); + i915_batchbuffer_dword(&batch->base, req->presumed_offset + pre_add); + reloc[1] = pre_add; + reloc[2] = itemLoc; + reloc[3] = batch->dest_location; + batch->nr_relocs++; +} + +static void +i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) +{ + buf->handle = rep->handle; + buf->flags = rep->flags; + buf->size = rep->size; + buf->offset = rep->offset; + buf->mapHandle = rep->arg_handle; + buf->proposedFlags = rep->proposed_flags; + buf->start = rep->buffer_start; + buf->fenceFlags = rep->fence_flags; + buf->replyFlags = rep->rep_flags; + buf->pageAlignment = rep->page_alignment; +} + +static int +i915_execbuf(struct intel_be_batchbuffer *batch, + unsigned int used, + boolean ignore_cliprects, + drmBOList *list, + struct drm_i915_execbuffer *ea) +{ +// struct intel_be_context *intel = batch->intel; + drmBONode *node; + drmMMListHead *l; + struct drm_i915_op_arg *arg, *first; + struct drm_bo_op_req *req; + struct drm_bo_info_rep *rep; + uint64_t *prevNext = NULL; + drmBO *buf; + int ret = 0; + uint32_t count = 0; + + first = NULL; + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + + arg = &node->bo_arg; + req = &arg->d.req; + + if (!first) + first = arg; + + if (prevNext) + *prevNext = (unsigned long)arg; + + prevNext = &arg->next; + req->bo_req.handle = node->buf->handle; + req->op = drm_bo_validate; + req->bo_req.flags = node->arg0; + req->bo_req.mask = node->arg1; + req->bo_req.hint |= 0; + count++; + } + + memset(ea, 0, sizeof(*ea)); + ea->num_buffers = count; + ea->batch.start = batch->poolOffset; + ea->batch.used = used; +#if 0 /* ZZZ JB: no cliprects used */ + ea->batch.cliprects = intel->pClipRects; + ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); +#else + ea->batch.cliprects = NULL; + ea->batch.num_cliprects = 0; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0; +#endif + ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; + ea->ops_list = (unsigned long) first; + first->reloc_ptr = (unsigned long) batch->reloc; + batch->reloc[0] = batch->nr_relocs; + + //return -EFAULT; + do { + ret = drmCommandWriteRead(batch->device->fd, DRM_I915_EXECBUFFER, ea, + sizeof(*ea)); + } while (ret == -EAGAIN); + + if (ret != 0) + return ret; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + arg = &node->bo_arg; + rep = &arg->d.rep.bo_info; + + if (!arg->handled) { + return -EFAULT; + } + if (arg->d.rep.ret) + return arg->d.rep.ret; + + buf = node->buf; + i915_drm_copy_reply(rep, buf); + } + return 0; +} + +/* TODO: Push this whole function into bufmgr. + */ +static struct _DriFenceObject * +do_flush_locked(struct intel_be_batchbuffer *batch, + unsigned int used, + boolean ignore_cliprects, boolean allow_unlock) +{ + struct intel_be_context *intel = batch->intel; + struct _DriFenceObject *fo; + drmFence fence; + drmBOList *boList; + struct drm_i915_execbuffer ea; + int ret = 0; + + driBOValidateUserList(batch->list); + boList = driGetdrmBOList(batch->list); + +#if 0 /* ZZZ JB Allways run */ + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { +#else + if (1) { +#endif + ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); + } else { + driPutdrmBOList(batch->list); + fo = NULL; + goto out; + } + driPutdrmBOList(batch->list); + if (ret) + abort(); + + if (ea.fence_arg.error != 0) { + + /* + * The hardware has been idled by the kernel. + * Don't fence the driBOs. + */ + + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); +#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ + _mesa_printf("fence error\n"); +#endif + batch->last_fence = NULL; + fo = NULL; + goto out; + } + + fence.handle = ea.fence_arg.handle; + fence.fence_class = ea.fence_arg.fence_class; + fence.type = ea.fence_arg.type; + fence.flags = ea.fence_arg.flags; + fence.signaled = ea.fence_arg.signaled; + + fo = driBOFenceUserList(batch->device->fenceMgr, batch->list, + "SuperFence", &fence); + + if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); + /* + * FIXME: Context last fence?? + */ + batch->last_fence = fo; + driFenceReference(fo); + } + out: +#if 0 /* ZZZ JB: fix this */ + intel->vtbl.lost_hardware(intel); +#else + (void)intel; +#endif + return fo; +} + + +struct _DriFenceObject * +intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch) +{ + struct intel_be_context *intel = batch->intel; + unsigned int used = batch->base.ptr - batch->base.map; + boolean was_locked = batch->intel->hardware_locked(intel); + struct _DriFenceObject *fence; + + if (used == 0) { + driFenceReference(batch->last_fence); + return batch->last_fence; + } + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ +#if 0 /* ZZZ JB: what should we do here? */ + if (used & 4) { + ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->base.ptr)[1] = 0; + ((int *) batch->base.ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->base.ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } +#else + if (used & 4) { + ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->base.ptr)[1] = 0; + ((int *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 8; + } +#endif + driBOUnmap(batch->buffer); + batch->base.ptr = NULL; + batch->base.map = NULL; + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!was_locked) + intel->hardware_lock(intel); + + fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + FALSE); + + if (!was_locked) + intel->hardware_unlock(intel); + + /* Reset the buffer: + */ + intel_be_batchbuffer_reset(batch); + return fence; +} + +void +intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch) +{ + struct _DriFenceObject *fence = intel_be_batchbuffer_flush(batch); + driFenceFinish(fence, driFenceType(fence), FALSE); + driFenceUnReference(&fence); +} + +#if 0 +void +intel_be_batchbuffer_data(struct intel_be_batchbuffer *batch, + const void *data, unsigned int bytes, unsigned int flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + memcpy(batch->base.ptr, data, bytes); + batch->base.ptr += bytes; +} +#endif diff --git a/src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.h b/src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.h new file mode 100644 index 0000000000..f150e3a674 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.h @@ -0,0 +1,69 @@ + +#ifndef INTEL_BE_BATCHBUFFER_H +#define INTEL_BE_BATCHBUFFER_H + +#include "i915simple/i915_batch.h" + +#include "ws_dri_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_batchbuffer +{ + struct i915_batchbuffer base; + + struct intel_be_context *intel; + struct intel_be_device *device; + + struct _DriBufferObject *buffer; + struct _DriFenceObject *last_fence; + uint32_t flags; + + struct _DriBufferList *list; + size_t list_count; + + uint32_t *reloc; + size_t reloc_size; + size_t nr_relocs; + + uint32_t dirty_state; + uint32_t id; + + uint32_t poolOffset; + uint8_t *drmBOVirtual; + struct _drmBONode *node; /* Validation list node for this buffer */ + int dest_location; /* Validation list sequence for this buffer */ +}; + +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); + +struct _DriFenceObject * +intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch); + +void +intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch); + +void +intel_be_offset_relocation(struct intel_be_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask); + +#endif diff --git a/src/gallium/winsys/drm/intel/common/intel_be_context.c b/src/gallium/winsys/drm/intel/common/intel_be_context.c new file mode 100644 index 0000000000..1af39674f4 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/intel_be_context.c @@ -0,0 +1,107 @@ + +/* + * Authors: Jakob Bornecrantz + */ + +#include "ws_dri_fencemgr.h" +#include "intel_be_device.h" +#include "intel_be_context.h" +#include "intel_be_batchbuffer.h" + +static INLINE struct intel_be_context * +intel_be_context(struct i915_winsys *sws) +{ + return (struct intel_be_context *)sws; +} + +/* Simple batchbuffer interface: + */ + +static struct i915_batchbuffer* +intel_i915_batch_get(struct i915_winsys *sws) +{ + struct intel_be_context *intel = intel_be_context(sws); + return &intel->batch->base; +} + +static void intel_i915_batch_reloc(struct i915_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta) +{ + struct intel_be_context *intel = intel_be_context(sws); + + unsigned flags = DRM_BO_FLAG_MEM_TT; + unsigned mask = DRM_BO_MASK_MEM; + + if (access_flags & I915_BUFFER_ACCESS_WRITE) { + flags |= DRM_BO_FLAG_WRITE; + mask |= DRM_BO_FLAG_WRITE; + } + + if (access_flags & I915_BUFFER_ACCESS_READ) { + flags |= DRM_BO_FLAG_READ; + mask |= DRM_BO_FLAG_READ; + } + + intel_be_offset_relocation(intel->batch, + delta, + dri_bo(buf), + flags, + mask); +} + +static void intel_i915_batch_flush(struct i915_winsys *sws, + struct pipe_fence_handle **fence) +{ + struct intel_be_context *intel = intel_be_context(sws); + + union { + struct _DriFenceObject *dri; + struct pipe_fence_handle *pipe; + } fu; + + if (fence) + assert(!*fence); + + fu.dri = intel_be_batchbuffer_flush(intel->batch); + + if (!fu.dri) { + assert(0); + *fence = NULL; + return; + } + + if (fu.dri) { + if (fence) + *fence = fu.pipe; + else + driFenceUnReference(&fu.dri); + } + +} + +boolean +intel_be_init_context(struct intel_be_context *intel, struct intel_be_device *device) +{ + assert(intel); + assert(device); + + intel->device = device; + + /* TODO move framebuffer createion to the driver */ + + intel->base.batch_get = intel_i915_batch_get; + intel->base.batch_reloc = intel_i915_batch_reloc; + intel->base.batch_flush = intel_i915_batch_flush; + + intel->batch = intel_be_batchbuffer_alloc(intel); + + return true; +} + +void +intel_be_destroy_context(struct intel_be_context *intel) +{ + intel_be_batchbuffer_free(intel->batch); +} diff --git a/src/gallium/winsys/drm/intel/common/intel_be_context.h b/src/gallium/winsys/drm/intel/common/intel_be_context.h new file mode 100644 index 0000000000..d5cbc93594 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/intel_be_context.h @@ -0,0 +1,40 @@ +/* These need to be diffrent from the intel winsys */ +#ifndef INTEL_BE_CONTEXT_H +#define INTEL_BE_CONTEXT_H + +#include "i915simple/i915_winsys.h" + +struct intel_be_context +{ + /** Interface to i915simple driver */ + struct i915_winsys base; + + struct intel_be_device *device; + struct intel_be_batchbuffer *batch; + + /* + * Hardware lock functions. + * + * Needs to be filled in by the winsys. + */ + void (*hardware_lock)(struct intel_be_context *context); + void (*hardware_unlock)(struct intel_be_context *context); + boolean (*hardware_locked)(struct intel_be_context *context); +}; + +/** + * Intialize a allocated intel_be_context struct. + * + * Remember to set the hardware_* functions. + */ +boolean +intel_be_init_context(struct intel_be_context *intel, + struct intel_be_device *device); + +/** + * Destroy a intel_be_context. + * Does not free the struct that is up to the winsys. + */ +void +intel_be_destroy_context(struct intel_be_context *intel); +#endif diff --git a/src/gallium/winsys/drm/intel/common/intel_be_device.c b/src/gallium/winsys/drm/intel/common/intel_be_device.c new file mode 100644 index 0000000000..8db0329615 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/intel_be_device.c @@ -0,0 +1,308 @@ + + +/* + * Authors: Keith Whitwell + * Jakob Bornecrantz + */ + +#include "intel_be_device.h" +#include "ws_dri_bufmgr.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "i915simple/i915_screen.h" + +/* Turn a pipe winsys into an intel/pipe winsys: + */ +static INLINE struct intel_be_device * +intel_be_device( struct pipe_winsys *winsys ) +{ + return (struct intel_be_device *)winsys; +} + + +/* + * Buffer functions. + * + * Most callbacks map direcly onto dri_bufmgr operations: + */ + +static void *intel_be_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags ) +{ + unsigned drm_flags = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + drm_flags |= DRM_BO_FLAG_WRITE; + + if (flags & PIPE_BUFFER_USAGE_CPU_READ) + drm_flags |= DRM_BO_FLAG_READ; + + return driBOMap( dri_bo(buf), drm_flags, 0 ); +} + +static void intel_be_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnmap( dri_bo(buf) ); +} + +static void +intel_be_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnReference( dri_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 *iws = intel_be_device(winsys); + unsigned flags = 0; + struct _DriBufferPool *pool; + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { + flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; + pool = iws->mallocPool; + } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { + /* For vertex buffers */ + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + pool = iws->vertexPool; + } else { + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + pool = iws->regionPool; + } + + if (usage & PIPE_BUFFER_USAGE_GPU_READ) + flags |= DRM_BO_FLAG_READ; + + if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) + flags |= DRM_BO_FLAG_WRITE; + + /* drm complains if we don't set any read/write flags. + */ + if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) + flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + buffer->pool = pool; + driGenBuffers( buffer->pool, + "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); + + driBOData( buffer->driBO, size, NULL, buffer->pool, 0 ); + + return &buffer->base; +} + + +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 *iws = intel_be_device(winsys); + + driGenUserBuffer( iws->regionPool, + "pipe user buffer", &buffer->driBO, ptr, bytes ); + + buffer->base.refcount = 1; + + return &buffer->base; +} + +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle) +{ + struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); + struct pipe_buffer *buffer; + + if (!be_buf) + goto err; + + memset(be_buf, 0, sizeof(*be_buf)); + + driGenBuffers(device->staticPool, name, 1, &be_buf->driBO, 0, 0, 0); + driBOSetReferenced(be_buf->driBO, handle); + + if (0) /** XXX TODO check error */ + goto err_bo; + + buffer = &be_buf->base; + buffer->refcount = 1; + buffer->alignment = 0; + buffer->usage = 0; + buffer->size = driBOSize(be_buf->driBO); + + return buffer; +err_bo: + free(be_buf); +err: + return NULL; +} + + +/* + * Surface functions. + * + * Deprecated! + */ + +static struct pipe_surface * +intel_i915_surface_alloc(struct pipe_winsys *winsys) +{ + assert((size_t)"intel_i915_surface_alloc is deprecated" & 0); + return NULL; +} + +static int +intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + assert((size_t)"intel_i915_surface_alloc_storage is deprecated" & 0); + return -1; +} + +static void +intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + assert((size_t)"intel_i915_surface_release is deprecated" & 0); +} + + +/* + * Fence functions + */ + +static void +intel_be_fence_reference( struct pipe_winsys *sws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence ) +{ + if (*ptr) + driFenceUnReference((struct _DriFenceObject **)ptr); + + if (fence) + *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); +} + +static int +intel_be_fence_signalled( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + return driFenceSignaled((struct _DriFenceObject *)fence, flag); +} + +static int +intel_be_fence_finish( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); +} + + +/* + * Misc functions + */ + +boolean +intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id) +{ + dev->fd = fd; + dev->max_batch_size = 16 * 4096; + dev->max_vertex_size = 128 * 4096; + + dev->base.buffer_create = intel_be_buffer_create; + dev->base.user_buffer_create = intel_be_user_buffer_create; + dev->base.buffer_map = intel_be_buffer_map; + dev->base.buffer_unmap = intel_be_buffer_unmap; + dev->base.buffer_destroy = intel_be_buffer_destroy; + dev->base.surface_alloc = intel_i915_surface_alloc; + dev->base.surface_alloc_storage = intel_i915_surface_alloc_storage; + dev->base.surface_release = intel_i915_surface_release; + dev->base.fence_reference = intel_be_fence_reference; + dev->base.fence_signalled = intel_be_fence_signalled; + dev->base.fence_finish = intel_be_fence_finish; + +#if 0 /* Set by the winsys */ + dev->base.flush_frontbuffer = intel_flush_frontbuffer; + dev->base.get_name = intel_get_name; +#endif + + dev->fMan = driInitFreeSlabManager(10, 10); + dev->fenceMgr = driFenceMgrTTMInit(dev->fd); + + dev->mallocPool = driMallocPoolInit(); + dev->staticPool = driDRMPoolInit(dev->fd); + /* Sizes: 64 128 256 512 1024 2048 4096 8192 16384 32768 */ + dev->regionPool = driSlabPoolInit(dev->fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + 64, + 10, 120, 4096 * 64, 0, + dev->fMan); + + dev->vertexPool = driSlabPoolInit(dev->fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + dev->max_vertex_size, + 1, 120, dev->max_vertex_size * 4, 0, + dev->fMan); + + dev->batchPool = driSlabPoolInit(dev->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + dev->max_batch_size, + 1, 40, dev->max_batch_size * 16, 0, + dev->fMan); + + /* Fill in this struct with callbacks that i915simple will need to + * communicate with the window system, buffer manager, etc. + */ + dev->screen = i915_create_screen(&dev->base, id); + + return true; +} + +void +intel_be_destroy_device(struct intel_be_device *dev) +{ + driPoolTakeDown(dev->mallocPool); + driPoolTakeDown(dev->staticPool); + driPoolTakeDown(dev->regionPool); + driPoolTakeDown(dev->vertexPool); + driPoolTakeDown(dev->batchPool); + + /** TODO takedown fenceMgr and fMan */ +} diff --git a/src/gallium/winsys/drm/intel/common/intel_be_device.h b/src/gallium/winsys/drm/intel/common/intel_be_device.h new file mode 100644 index 0000000000..3f8b3f585c --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/intel_be_device.h @@ -0,0 +1,72 @@ +#ifndef INTEL_DRM_DEVICE_H +#define INTEL_DRM_DEVICE_H + +#include "pipe/p_winsys.h" +#include "pipe/p_context.h" + +/* + * Device + */ + +struct intel_be_device +{ + struct pipe_winsys base; + + /** + * Hw level screen + */ + struct pipe_screen *screen; + + int fd; /**< Drm file discriptor */ + + size_t max_batch_size; + size_t max_vertex_size; + + struct _DriFenceMgr *fenceMgr; + + struct _DriBufferPool *batchPool; + struct _DriBufferPool *regionPool; + struct _DriBufferPool *mallocPool; + struct _DriBufferPool *vertexPool; + struct _DriBufferPool *staticPool; + struct _DriFreeSlabManager *fMan; +}; + +boolean +intel_be_init_device(struct intel_be_device *device, int fd, unsigned id); + +void +intel_be_destroy_device(struct intel_be_device *dev); + +/* + * Buffer + */ + +struct intel_be_buffer { + struct pipe_buffer base; + struct _DriBufferPool *pool; + struct _DriBufferObject *driBO; +}; + +/** + * Create a be buffer from a drm bo handle + * + * Takes a reference + */ +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle); + +static INLINE struct intel_be_buffer * +intel_be_buffer(struct pipe_buffer *buf) +{ + return (struct intel_be_buffer *)buf; +} + +static INLINE struct _DriBufferObject * +dri_bo(struct pipe_buffer *buf) +{ + return intel_be_buffer(buf)->driBO; +} + +#endif diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c b/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c new file mode 100644 index 0000000000..b6d901f85e --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c @@ -0,0 +1,949 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + * Keith Whitwell + */ + +#include +#include +#include +#include "glthread.h" +#include "errno.h" +#include "ws_dri_bufmgr.h" +#include "string.h" +#include "pipe/p_debug.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" + + +/* + * This lock is here to protect drmBO structs changing underneath us during a + * validate list call, since validatelist cannot take individiual locks for + * each drmBO. Validatelist takes this lock in write mode. Any access to an + * individual drmBO should take this lock in read mode, since in that case, the + * driBufferObject mutex will protect the access. Locking order is + * driBufferObject mutex - > this rw lock. + */ + +_glthread_DECLARE_STATIC_MUTEX(bmMutex); +_glthread_DECLARE_STATIC_COND(bmCond); + +static int kernelReaders = 0; +static int num_buffers = 0; +static int num_user_buffers = 0; + +static drmBO *drmBOListBuf(void *iterator) +{ + drmBONode *node; + drmMMListHead *l = (drmMMListHead *) iterator; + node = DRMLISTENTRY(drmBONode, l, head); + return node->buf; +} + +static void *drmBOListIterator(drmBOList *list) +{ + void *ret = list->list.next; + + if (ret == &list->list) + return NULL; + return ret; +} + +static void *drmBOListNext(drmBOList *list, void *iterator) +{ + void *ret; + + drmMMListHead *l = (drmMMListHead *) iterator; + ret = l->next; + if (ret == &list->list) + return NULL; + return ret; +} + +static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, + uint64_t arg0, + uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } + else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADD(&node->head, &list->list); + list->numOnList++; + return node; +} + +static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, + uint64_t mask, int *newItem) +{ + drmBONode *node, *cur; + drmMMListHead *l; + + *newItem = 0; + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + } + if (!cur) { + cur = drmAddListItem(list, buf, flags, mask); + if (!cur) { + return -ENOMEM; + } + *newItem = 1; + cur->arg0 = flags; + cur->arg1 = mask; + } + else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + return 0; +} + +static void drmBOFreeList(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->list.next; + while(l != &list->list) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->list.next; + list->numCurrent--; + list->numOnList--; + } + + l = list->free.next; + while(l != &list->free) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->free.next; + list->numCurrent--; + } +} + +static int drmAdjustListNodes(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + int ret = 0; + + while(list->numCurrent < list->numTarget) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + ret = -ENOMEM; + break; + } + list->numCurrent++; + DRMLISTADD(&node->head, &list->free); + } + + while(list->numCurrent > list->numTarget) { + l = list->free.next; + if (l == &list->free) + break; + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + list->numCurrent--; + } + return ret; +} + +static int drmBOCreateList(int numTarget, drmBOList *list) +{ + DRMINITLISTHEAD(&list->list); + DRMINITLISTHEAD(&list->free); + list->numTarget = numTarget; + list->numCurrent = 0; + list->numOnList = 0; + return drmAdjustListNodes(list); +} + +static int drmBOResetList(drmBOList *list) +{ + drmMMListHead *l; + int ret; + + ret = drmAdjustListNodes(list); + if (ret) + return ret; + + l = list->list.next; + while (l != &list->list) { + DRMLISTDEL(l); + DRMLISTADD(l, &list->free); + list->numOnList--; + l = list->list.next; + } + return drmAdjustListNodes(list); +} + +void driWriteLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + while(kernelReaders != 0) + _glthread_COND_WAIT(bmCond, bmMutex); +} + +void driWriteUnlockKernelBO(void) +{ + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + kernelReaders++; + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadUnlockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + if (--kernelReaders == 0) + _glthread_COND_BROADCAST(bmCond); + _glthread_UNLOCK_MUTEX(bmMutex); +} + + + + +/* + * TODO: Introduce fence pools in the same way as + * buffer object pools. + */ + +typedef struct _DriBufferObject +{ + DriBufferPool *pool; + _glthread_Mutex mutex; + int refCount; + const char *name; + uint64_t flags; + unsigned hint; + unsigned alignment; + unsigned createdByReference; + void *private; + /* user-space buffer: */ + unsigned userBuffer; + void *userData; + unsigned userSize; +} DriBufferObject; + +typedef struct _DriBufferList { + drmBOList drmBuffers; /* List of kernel buffers needing validation */ + drmBOList driBuffers; /* List of user-space buffers needing validation */ +} DriBufferList; + + +void +bmError(int val, const char *file, const char *function, int line) +{ + printf("Fatal video memory manager error \"%s\".\n" + "Check kernel logs or set the LIBGL_DEBUG\n" + "environment variable to \"verbose\" for more info.\n" + "Detected in file %s, line %d, function %s.\n", + strerror(-val), file, line, function); +#ifndef NDEBUG + abort(); +#else + abort(); +#endif +} + +extern drmBO * +driBOKernel(struct _DriBufferObject *buf) +{ + drmBO *ret; + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + ret = buf->pool->kernel(buf->pool, buf->private); + if (!ret) + BM_CKFATAL(-EINVAL); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + + return ret; +} + +void +driBOWaitIdle(struct _DriBufferObject *buf, int lazy) +{ + + /* + * This function may block. Is it sane to keep the mutex held during + * that time?? + */ + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void * +driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) +{ + void *virtual; + int retval; + + if (buf->userBuffer) { + return buf->userData; + } + + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + retval = buf->pool->map(buf->pool, buf->private, flags, hint, + &buf->mutex, &virtual); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval == 0 ? virtual : NULL; +} + +void +driBOUnmap(struct _DriBufferObject *buf) +{ + if (buf->userBuffer) + return; + + assert(buf->private != NULL); + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +unsigned long +driBOOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->offset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +unsigned long +driBOPoolOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->poolOffset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +uint64_t +driBOFlags(struct _DriBufferObject *buf) +{ + uint64_t ret; + + assert(buf->private != NULL); + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->flags(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + return ret; +} + +struct _DriBufferObject * +driBOReference(struct _DriBufferObject *buf) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (++buf->refCount == 1) { + _glthread_UNLOCK_MUTEX(buf->mutex); + BM_CKFATAL(-EINVAL); + } + _glthread_UNLOCK_MUTEX(buf->mutex); + return buf; +} + +void +driBOUnReference(struct _DriBufferObject *buf) +{ + int tmp; + + if (!buf) + return; + + _glthread_LOCK_MUTEX(buf->mutex); + tmp = --buf->refCount; + if (!tmp) { + _glthread_UNLOCK_MUTEX(buf->mutex); + if (buf->private) { + if (buf->createdByReference) + buf->pool->unreference(buf->pool, buf->private); + else + buf->pool->destroy(buf->pool, buf->private); + } + if (buf->userBuffer) + num_user_buffers--; + else + num_buffers--; + free(buf); + } else + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + + +int +driBOData(struct _DriBufferObject *buf, + unsigned size, const void *data, + DriBufferPool *newPool, + uint64_t flags) +{ + void *virtual = NULL; + int newBuffer; + int retval = 0; + struct _DriBufferPool *pool; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + pool = buf->pool; + + if (pool == NULL && newPool != NULL) { + buf->pool = newPool; + pool = newPool; + } + if (newPool == NULL) + newPool = pool; + + if (!pool->create) { + assert((size_t)"driBOData called on invalid buffer\n" & 0); + BM_CKFATAL(-EINVAL); + } + + newBuffer = (!buf->private || pool != newPool || + pool->size(pool, buf->private) < size); + + if (!flags) + flags = buf->flags; + + if (newBuffer) { + + if (buf->createdByReference) { + assert((size_t)"driBOData requiring resizing called on shared buffer.\n" & 0); + BM_CKFATAL(-EINVAL); + } + + if (buf->private) + buf->pool->destroy(buf->pool, buf->private); + + pool = newPool; + buf->pool = newPool; + buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (!buf->private) + retval = -ENOMEM; + + if (retval == 0) + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); + } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { + /* + * Buffer is busy. need to create a new one. + */ + + void *newBuf; + + newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (newBuf) { + buf->pool->destroy(buf->pool, buf->private); + buf->private = newBuf; + } + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } else { + uint64_t flag_diff = flags ^ buf->flags; + + /* + * We might need to change buffer flags. + */ + + if (flag_diff){ + assert(pool->setStatus != NULL); + BM_CKFATAL(pool->unmap(pool, buf->private)); + BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, + buf->flags)); + if (!data) + goto out; + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } + } + + if (retval == 0) { + if (data) + memcpy(virtual, data, size); + + BM_CKFATAL(pool->unmap(pool, buf->private)); + } + + out: + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval; +} + +void +driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, const void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, + &virtual)); + memcpy((unsigned char *) virtual + offset, data, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); + memcpy(data, (unsigned char *) virtual + offset, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->private != NULL) { + assert((size_t)"Invalid buffer for setReferenced\n" & 0); + BM_CKFATAL(-EINVAL); + + } + if (buf->pool->reference == NULL) { + assert((size_t)"Invalid buffer pool for setReferenced\n" & 0); + BM_CKFATAL(-EINVAL); + } + buf->private = buf->pool->reference(buf->pool, handle); + if (!buf->private) { + assert((size_t)"Invalid buffer pool for setStatic\n" & 0); + BM_CKFATAL(-ENOMEM); + } + buf->createdByReference = TRUE; + buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +int +driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint) +{ + struct _DriBufferObject *buf; + int i; + + flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + ++num_buffers; + + assert(pool); + + for (i = 0; i < n; ++i) { + buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); + if (!buf) + return -ENOMEM; + + _glthread_INIT_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(buf->mutex); + buf->refCount = 1; + buf->flags = flags; + buf->hint = hint; + buf->name = name; + buf->alignment = alignment; + buf->pool = pool; + buf->createdByReference = 0; + _glthread_UNLOCK_MUTEX(buf->mutex); + buffers[i] = buf; + } + return 0; +} + +void +driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject **buffers, + void *ptr, unsigned bytes) +{ + const unsigned alignment = 1, flags = 0, hint = 0; + + --num_buffers; /* JB: is inced in GenBuffes */ + driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); + ++num_user_buffers; + + (*buffers)->userBuffer = 1; + (*buffers)->userData = ptr; + (*buffers)->userSize = bytes; +} + +void +driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) +{ + int i; + + for (i = 0; i < n; ++i) { + driBOUnReference(buffers[i]); + } +} + + +void +driInitBufMgr(int fd) +{ + ; +} + +/* + * Note that lists are per-context and don't need mutex protection. + */ + +struct _DriBufferList * +driBOCreateList(int target) +{ + struct _DriBufferList *list = calloc(sizeof(*list), 1); + + BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); + BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); + return list; +} + +int +driBOResetList(struct _DriBufferList * list) +{ + int ret; + ret = drmBOResetList(&list->drmBuffers); + if (ret) + return ret; + ret = drmBOResetList(&list->driBuffers); + return ret; +} + +void +driBOFreeList(struct _DriBufferList * list) +{ + drmBOFreeList(&list->drmBuffers); + drmBOFreeList(&list->driBuffers); + free(list); +} + + +/* + * Copied from libdrm, because it is needed by driAddValidateItem. + */ + +static drmBONode * +driAddListItem(drmBOList * list, drmBO * item, + uint64_t arg0, uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + memset(&node->bo_arg, 0, sizeof(node->bo_arg)); + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADDTAIL(&node->head, &list->list); + list->numOnList++; + return node; +} + +/* + * Slightly modified version compared to the libdrm version. + * This one returns the list index of the buffer put on the list. + */ + +static int +driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, + uint64_t mask, int *itemLoc, + struct _drmBONode **pnode) +{ + drmBONode *node, *cur; + drmMMListHead *l; + int count = 0; + + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + count++; + } + if (!cur) { + cur = driAddListItem(list, buf, flags, mask); + if (!cur) + return -ENOMEM; + + cur->arg0 = flags; + cur->arg1 = mask; + } else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + *itemLoc = count; + *pnode = cur; + return 0; +} + + +void +driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node) +{ + int newItem; + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(driAddValidateItem(&list->drmBuffers, + buf->pool->kernel(buf->pool, buf->private), + flags, mask, itemLoc, node)); + BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, + flags, mask, &newItem)); + if (newItem) + buf->refCount++; + + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +drmBOList *driGetdrmBOList(struct _DriBufferList *list) +{ + driWriteLockKernelBO(); + return &list->drmBuffers; +} + +void driPutdrmBOList(struct _DriBufferList *list) +{ + driWriteUnlockKernelBO(); +} + + +void +driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->fence) + BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + +void +driBOUnrefUserList(struct _DriBufferList *list) +{ + struct _DriBufferObject *buf; + void *curBuf; + + curBuf = drmBOListIterator(&list->driBuffers); + while (curBuf) { + buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + +struct _DriFenceObject * +driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, const char *name, + drmFence *kFence) +{ + struct _DriFenceObject *fence; + struct _DriBufferObject *buf; + void *curBuf; + + fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, + kFence, sizeof(*kFence)); + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space fencing callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + driBOFence(buf, fence); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } + + driBOResetList(list); + return fence; +} + +void +driBOValidateUserList(struct _DriBufferList * list) +{ + void *curBuf; + struct _DriBufferObject *buf; + + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space validation callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->validate) + BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); + _glthread_UNLOCK_MUTEX(buf->mutex); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + + +void +driPoolTakeDown(struct _DriBufferPool *pool) +{ + pool->takeDown(pool); + +} + +unsigned long +driBOSize(struct _DriBufferObject *buf) +{ + unsigned long size; + + _glthread_LOCK_MUTEX(buf->mutex); + size = buf->pool->size(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return size; + +} + +drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) +{ + return &list->drmBuffers; +} + +drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) +{ + return &list->driBuffers; +} + diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.h b/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.h new file mode 100644 index 0000000000..e6c0cff0a0 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.h @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + * Keith Whitwell + */ + +#ifndef _PSB_BUFMGR_H_ +#define _PSB_BUFMGR_H_ +#include +#include "i915_drm.h" +#include "ws_dri_fencemgr.h" + +typedef struct _drmBONode +{ + drmMMListHead head; + drmBO *buf; + struct drm_i915_op_arg bo_arg; + uint64_t arg0; + uint64_t arg1; +} drmBONode; + +typedef struct _drmBOList { + unsigned numTarget; + unsigned numCurrent; + unsigned numOnList; + drmMMListHead list; + drmMMListHead free; +} drmBOList; + + +struct _DriFenceObject; +struct _DriBufferObject; +struct _DriBufferPool; +struct _DriBufferList; + +/* + * Return a pointer to the libdrm buffer object this DriBufferObject + * uses. + */ + +extern drmBO *driBOKernel(struct _DriBufferObject *buf); +extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, + unsigned hint); +extern void driBOUnmap(struct _DriBufferObject *buf); +extern unsigned long driBOOffset(struct _DriBufferObject *buf); +extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); + +extern uint64_t driBOFlags(struct _DriBufferObject *buf); +extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); +extern void driBOUnReference(struct _DriBufferObject *buf); + +extern int driBOData(struct _DriBufferObject *r_buf, + unsigned size, const void *data, + struct _DriBufferPool *pool, uint64_t flags); + +extern void driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + const void *data); +extern void driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + void *data); +extern int driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint); +extern void driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject *buffers[], + void *ptr, unsigned bytes); +extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); +extern void driInitBufMgr(int fd); +extern struct _DriBufferList *driBOCreateList(int target); +extern int driBOResetList(struct _DriBufferList * list); +extern void driBOAddListItem(struct _DriBufferList * list, + struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node); + +extern void driBOValidateList(int fd, struct _DriBufferList * list); +extern void driBOFreeList(struct _DriBufferList * list); +extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, + const char *name, + drmFence *kFence); +extern void driBOUnrefUserList(struct _DriBufferList *list); +extern void driBOValidateUserList(struct _DriBufferList * list); +extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); +extern void driPutdrmBOList(struct _DriBufferList *list); + +extern void driBOFence(struct _DriBufferObject *buf, + struct _DriFenceObject *fence); + +extern void driPoolTakeDown(struct _DriBufferPool *pool); +extern void driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle); +unsigned long driBOSize(struct _DriBufferObject *buf); +extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); +extern void driPoolTakeDown(struct _DriBufferPool *pool); + +extern void driReadLockKernelBO(void); +extern void driReadUnlockKernelBO(void); +extern void driWriteLockKernelBO(void); +extern void driWriteUnlockKernelBO(void); + +/* + * For debugging purposes. + */ + +extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); +extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); +#endif diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_bufpool.h b/src/gallium/winsys/drm/intel/common/ws_dri_bufpool.h new file mode 100644 index 0000000000..bf60798924 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_bufpool.h @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +#ifndef _PSB_BUFPOOL_H_ +#define _PSB_BUFPOOL_H_ + +#include +#include +struct _DriFenceObject; + +typedef struct _DriBufferPool +{ + int fd; + int (*map) (struct _DriBufferPool * pool, void *private, + unsigned flags, int hint, _glthread_Mutex *mutex, + void **virtual); + int (*unmap) (struct _DriBufferPool * pool, void *private); + int (*destroy) (struct _DriBufferPool * pool, void *private); + unsigned long (*offset) (struct _DriBufferPool * pool, void *private); + unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); + uint64_t (*flags) (struct _DriBufferPool * pool, void *private); + unsigned long (*size) (struct _DriBufferPool * pool, void *private); + void *(*create) (struct _DriBufferPool * pool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment); + void *(*reference) (struct _DriBufferPool * pool, unsigned handle); + int (*unreference) (struct _DriBufferPool * pool, void *private); + int (*fence) (struct _DriBufferPool * pool, void *private, + struct _DriFenceObject * fence); + drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); + int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy); + int (*setStatus) (struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags); + void (*takeDown) (struct _DriBufferPool * pool); + void *data; +} DriBufferPool; + +extern void bmError(int val, const char *file, const char *function, + int line); +#define BM_CKFATAL(val) \ + do{ \ + int tstVal = (val); \ + if (tstVal) \ + bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ + } while(0); + + +/* + * Builtin pools. + */ + +/* + * Kernel buffer objects. Size in multiples of page size. Page size aligned. + */ + +extern struct _DriBufferPool *driDRMPoolInit(int fd); +extern struct _DriBufferPool *driMallocPoolInit(void); + +struct _DriFreeSlabManager; +extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan); +extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); +extern struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); + + +#endif diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_drmpool.c b/src/gallium/winsys/drm/intel/common/ws_dri_drmpool.c new file mode 100644 index 0000000000..40929efa2f --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_drmpool.c @@ -0,0 +1,268 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" +#include "assert.h" + +/* + * Buffer pool implementation using DRM buffer objects as DRI buffer objects. + */ + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + unsigned pageSize = getpagesize(); + + if (!buf) + return NULL; + + if ((alignment > pageSize) && (alignment % pageSize)) { + free(buf); + return NULL; + } + + ret = drmBOCreate(pool->fd, size, alignment / pageSize, + NULL, + flags, hint, buf); + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static void * +pool_reference(struct _DriBufferPool *pool, unsigned handle) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + + if (!buf) + return NULL; + + ret = drmBOReference(pool->fd, handle, buf); + + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unreference(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOMap(pool->fd, buf, flags, hint, virtual); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOUnmap(pool->fd, buf); + driReadUnlockKernelBO(); + + return ret; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long offset; + + driReadLockKernelBO(); + assert(buf->flags & DRM_BO_FLAG_NO_MOVE); + offset = buf->offset; + driReadUnlockKernelBO(); + + return buf->offset; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + uint64_t flags; + + driReadLockKernelBO(); + flags = buf->flags; + driReadUnlockKernelBO(); + + return flags; +} + + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long size; + + driReadLockKernelBO(); + size = buf->size; + driReadUnlockKernelBO(); + + return buf->size; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + /* + * Noop. The kernel handles all fencing. + */ + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + return (drmBO *) private; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); + driReadUnlockKernelBO(); + + return ret; +} + + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + +/*static int +pool_setStatus(struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags) +{ + drmBO *buf = (drmBO *) private; + uint64_t new_flags = old_flags ^ flag_diff; + int ret; + + driReadLockKernelBO(); + ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, + 0, 0, 0); + driReadUnlockKernelBO(); + return ret; +}*/ + +struct _DriBufferPool * +driDRMPoolInit(int fd) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + + if (!pool) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + pool->reference = &pool_reference; + pool->unreference = &pool_unreference; + pool->data = NULL; + return pool; +} diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.c b/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.c new file mode 100644 index 0000000000..b56bc269da --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.c @@ -0,0 +1,377 @@ +#include "ws_dri_fencemgr.h" +#include "glthread.h" +#include +#include +#include + +/* + * Note: Locking order is + * _DriFenceObject::mutex + * _DriFenceMgr::mutex + */ + +struct _DriFenceMgr { + /* + * Constant members. Need no mutex protection. + */ + struct _DriFenceMgrCreateInfo info; + void *private; + + /* + * These members are protected by this->mutex + */ + _glthread_Mutex mutex; + int refCount; + drmMMListHead *heads; + int num_fences; +}; + +struct _DriFenceObject { + + /* + * These members are constant and need no mutex protection. + */ + struct _DriFenceMgr *mgr; + uint32_t fence_class; + uint32_t fence_type; + + /* + * These members are protected by mgr->mutex. + */ + drmMMListHead head; + int refCount; + + /* + * These members are protected by this->mutex. + */ + _glthread_Mutex mutex; + uint32_t signaled_type; + void *private; +}; + +uint32_t +driFenceType(struct _DriFenceObject *fence) +{ + return fence->fence_type; +} + +struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) +{ + struct _DriFenceMgr *tmp; + uint32_t i; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->refCount = 1; + tmp->info = *info; + tmp->num_fences = 0; + tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); + if (!tmp->heads) + goto out_err; + + for (i=0; iinfo.num_classes; ++i) { + DRMINITLISTHEAD(&tmp->heads[i]); + } + _glthread_UNLOCK_MUTEX(tmp->mutex); + return tmp; + + out_err: + if (tmp) + free(tmp); + return NULL; +} + +static void +driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) +{ + struct _DriFenceMgr *mgr = *pMgr; + + *pMgr = NULL; + if (--mgr->refCount == 0) + free(mgr); + else + _glthread_UNLOCK_MUTEX(mgr->mutex); +} + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr) +{ + _glthread_LOCK_MUTEX((*pMgr)->mutex); + driFenceMgrUnrefUnlock(pMgr); +} + +static void +driFenceUnReferenceLocked(struct _DriFenceObject **pFence) +{ + struct _DriFenceObject *fence = *pFence; + struct _DriFenceMgr *mgr = fence->mgr; + + *pFence = NULL; + if (--fence->refCount == 0) { + DRMLISTDELINIT(&fence->head); + if (fence->private) + mgr->info.unreference(mgr, &fence->private); + --mgr->num_fences; + fence->mgr = NULL; + --mgr->refCount; + free(fence); + + } +} + + +static void +driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, + drmMMListHead *list, + uint32_t fence_class, + uint32_t fence_type) +{ + struct _DriFenceObject *entry; + drmMMListHead *prev; + + while(list != &mgr->heads[fence_class]) { + entry = DRMLISTENTRY(struct _DriFenceObject, list, head); + + /* + * Up refcount so that entry doesn't disappear from under us + * when we unlock-relock mgr to get the correct locking order. + */ + + ++entry->refCount; + _glthread_UNLOCK_MUTEX(mgr->mutex); + _glthread_LOCK_MUTEX(entry->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + + prev = list->prev; + + + + if (list->prev == list) { + + /* + * Somebody else removed the entry from the list. + */ + + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + return; + } + + entry->signaled_type |= (fence_type & entry->fence_type); + if (entry->signaled_type == entry->fence_type) { + DRMLISTDELINIT(list); + mgr->info.unreference(mgr, &entry->private); + } + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + list = prev; + } +} + + +int +driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint) +{ + struct _DriFenceMgr *mgr = fence->mgr; + int ret = 0; + + _glthread_LOCK_MUTEX(fence->mutex); + + if ((fence->signaled_type & fence_type) == fence_type) + goto out0; + + ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); + if (ret) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + fence_type); + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) +{ + uint32_t ret; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = fence->signaled_type; + _glthread_UNLOCK_MUTEX(fence->mutex); + + return ret; +} + +int +driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, + uint32_t *signaled) +{ + int ret = 0; + struct _DriFenceMgr *mgr; + + _glthread_LOCK_MUTEX(fence->mutex); + mgr = fence->mgr; + *signaled = fence->signaled_type; + if ((fence->signaled_type & flush_type) == flush_type) + goto out0; + + ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); + if (ret) { + *signaled = fence->signaled_type; + goto out0; + } + + if ((fence->signaled_type | *signaled) == fence->signaled_type) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + *signaled); + + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +struct _DriFenceObject * +driFenceReference(struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(fence->mgr->mutex); + ++fence->refCount; + _glthread_UNLOCK_MUTEX(fence->mgr->mutex); + return fence; +} + +void +driFenceUnReference(struct _DriFenceObject **pFence) +{ + struct _DriFenceMgr *mgr; + + if (*pFence == NULL) + return; + + mgr = (*pFence)->mgr; + _glthread_LOCK_MUTEX(mgr->mutex); + ++mgr->refCount; + driFenceUnReferenceLocked(pFence); + driFenceMgrUnrefUnlock(&mgr); +} + +struct _DriFenceObject +*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, + uint32_t fence_type, void *private, size_t private_size) +{ + struct _DriFenceObject *fence; + size_t fence_size = sizeof(*fence); + + if (private_size) + fence_size = ((fence_size + 15) & ~15); + + fence = calloc(1, fence_size + private_size); + + if (!fence) { + int ret = mgr->info.finish(mgr, private, fence_type, 0); + + if (ret) + usleep(10000000); + + return NULL; + } + + _glthread_INIT_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + fence->refCount = 1; + DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); + fence->mgr = mgr; + ++mgr->refCount; + ++mgr->num_fences; + _glthread_UNLOCK_MUTEX(mgr->mutex); + fence->fence_class = fence_class; + fence->fence_type = fence_type; + fence->signaled_type = 0; + fence->private = private; + if (private_size) { + fence->private = (void *)(((uint8_t *) fence) + fence_size); + memcpy(fence->private, private, private_size); + } + + _glthread_UNLOCK_MUTEX(fence->mutex); + return fence; +} + + +static int +tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type) +{ + long fd = (long) mgr->private; + int dummy; + drmFence *fence = (drmFence *) private; + int ret; + + *signaled_type = 0; + ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); + if (ret) + return ret; + + *signaled_type = fence->signaled; + + return 0; +} + +static int +tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, + int lazy_hint) +{ + long fd = (long) mgr->private; + unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; + + return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); +} + +static int +tUnref(struct _DriFenceMgr *mgr, void **private) +{ + long fd = (long) mgr->private; + drmFence *fence = (drmFence *) *private; + *private = NULL; + + return drmFenceUnreference(fd, fence); +} + +struct _DriFenceMgr *driFenceMgrTTMInit(int fd) +{ + struct _DriFenceMgrCreateInfo info; + struct _DriFenceMgr *mgr; + + info.flags = DRI_FENCE_CLASS_ORDERED; + info.num_classes = 4; + info.signaled = tSignaled; + info.finish = tFinish; + info.unreference = tUnref; + + mgr = driFenceMgrCreate(&info); + if (mgr == NULL) + return NULL; + + mgr->private = (void *) (long) fd; + return mgr; +} + diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.h b/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.h new file mode 100644 index 0000000000..4ea58dfe18 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.h @@ -0,0 +1,115 @@ +#ifndef DRI_FENCEMGR_H +#define DRI_FENCEMGR_H + +#include +#include + +struct _DriFenceObject; +struct _DriFenceMgr; + +/* + * Do a quick check to see if the fence manager has registered the fence + * object as signaled. Note that this function may return a false negative + * answer. + */ +extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); + +/* + * Check if the fence object is signaled. This function can be substantially + * more expensive to call than the above function, but will not return a false + * negative answer. The argument "flush_type" sets the types that the + * underlying mechanism must make sure will eventually signal. + */ +extern int driFenceSignaledType(struct _DriFenceObject *fence, + uint32_t flush_type, uint32_t *signaled); + +/* + * Convenience functions. + */ + +static inline int driFenceSignaled(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types; + int ret = driFenceSignaledType(fence, flush_type, &signaled_types); + if (ret) + return 0; + return ((signaled_types & flush_type) == flush_type); +} + +static inline int driFenceSignaledCached(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types = + driFenceSignaledTypeCached(fence); + + return ((signaled_types & flush_type) == flush_type); +} + +/* + * Reference a fence object. + */ +extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); + +/* + * Unreference a fence object. The fence object pointer will be reset to NULL. + */ + +extern void driFenceUnReference(struct _DriFenceObject **pFence); + + +/* + * Wait for a fence to signal the indicated fence_type. + * If "lazy_hint" is true, it indicates that the wait may sleep to avoid + * busy-wait polling. + */ +extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint); + +/* + * Create a DriFenceObject for manager "mgr". + * + * "private" is a pointer that should be used for the callbacks in + * struct _DriFenceMgrCreateInfo. + * + * if private_size is nonzero, then the info stored at *private, with size + * private size will be copied and the fence manager will instead use a + * pointer to the copied data for the callbacks in + * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by + * "private" may be destroyed after the call to driFenceCreate. + */ +extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, + uint32_t fence_class, + uint32_t fence_type, + void *private, + size_t private_size); + +extern uint32_t driFenceType(struct _DriFenceObject *fence); + +/* + * Fence creations are ordered. If a fence signals a fence_type, + * it is safe to assume that all fences of the same class that was + * created before that fence has signaled the same type. + */ + +#define DRI_FENCE_CLASS_ORDERED (1 << 0) + +struct _DriFenceMgrCreateInfo { + uint32_t flags; + uint32_t num_classes; + int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type); + int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); + int (*unreference) (struct _DriFenceMgr *mgr, void **private); +}; + +extern struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr); + +extern struct _DriFenceMgr * +driFenceMgrTTMInit(int fd); + +#endif diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_mallocpool.c b/src/gallium/winsys/drm/intel/common/ws_dri_mallocpool.c new file mode 100644 index 0000000000..a80555c9c7 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_mallocpool.c @@ -0,0 +1,161 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr鰉 + */ + +#include +#include +#include +#include "pipe/p_debug.h" +#include "glthread.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + unsigned long *private = malloc(size + 2*sizeof(unsigned long)); + if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) + abort(); + + *private = size; + return (void *)private; +} + + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + free(private); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + *virtual = (void *)((unsigned long *)private + 2); + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); + return 0UL; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + return *(unsigned long *) private; +} + + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + abort(); + return 0UL; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + abort(); + return NULL; +} + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + + +struct _DriBufferPool * +driMallocPoolInit(void) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + if (!pool) + return NULL; + + pool->data = NULL; + pool->fd = -1; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + return pool; +} diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_slabpool.c b/src/gallium/winsys/drm/intel/common/ws_dri_slabpool.c new file mode 100644 index 0000000000..dfcf6d6b19 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_slabpool.c @@ -0,0 +1,968 @@ +/************************************************************************** + * + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#include +#include +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" +#include "ws_dri_bufmgr.h" +#include "glthread.h" + +#define DRI_SLABPOOL_ALLOC_RETRIES 100 + +struct _DriSlab; + +struct _DriSlabBuffer { + int isSlabBuffer; + drmBO *bo; + struct _DriFenceObject *fence; + struct _DriSlab *parent; + drmMMListHead head; + uint32_t mapCount; + uint32_t start; + uint32_t fenceType; + int unFenced; + _glthread_Cond event; +}; + +struct _DriKernelBO { + int fd; + drmBO bo; + drmMMListHead timeoutHead; + drmMMListHead head; + struct timeval timeFreed; + uint32_t pageAlignment; + void *virtual; +}; + +struct _DriSlab{ + drmMMListHead head; + drmMMListHead freeBuffers; + uint32_t numBuffers; + uint32_t numFree; + struct _DriSlabBuffer *buffers; + struct _DriSlabSizeHeader *header; + struct _DriKernelBO *kbo; +}; + + +struct _DriSlabSizeHeader { + drmMMListHead slabs; + drmMMListHead freeSlabs; + drmMMListHead delayedBuffers; + uint32_t numDelayed; + struct _DriSlabPool *slabPool; + uint32_t bufSize; + _glthread_Mutex mutex; +}; + +struct _DriFreeSlabManager { + struct timeval slabTimeout; + struct timeval checkInterval; + struct timeval nextCheck; + drmMMListHead timeoutList; + drmMMListHead unCached; + drmMMListHead cached; + _glthread_Mutex mutex; +}; + + +struct _DriSlabPool { + + /* + * The data of this structure remains constant after + * initialization and thus needs no mutex protection. + */ + + struct _DriFreeSlabManager *fMan; + uint64_t proposedFlags; + uint64_t validMask; + uint32_t *bucketSizes; + uint32_t numBuckets; + uint32_t pageSize; + int fd; + int pageAlignment; + int maxSlabSize; + int desiredNumBuffers; + struct _DriSlabSizeHeader *headers; +}; + +/* + * FIXME: Perhaps arrange timeout slabs in size buckets for fast + * retreival?? + */ + + +static inline int +driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) +{ + return ((arg1->tv_sec > arg2->tv_sec) || + ((arg1->tv_sec == arg2->tv_sec) && + (arg1->tv_usec > arg2->tv_usec))); +} + +static inline void +driTimeAdd(struct timeval *arg, struct timeval *add) +{ + unsigned int sec; + + arg->tv_sec += add->tv_sec; + arg->tv_usec += add->tv_usec; + sec = arg->tv_usec / 1000000; + arg->tv_sec += sec; + arg->tv_usec -= sec*1000000; +} + +static void +driFreeKernelBO(struct _DriKernelBO *kbo) +{ + if (!kbo) + return; + + (void) drmBOUnreference(kbo->fd, &kbo->bo); + free(kbo); +} + + +static void +driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, + struct timeval *time) +{ + drmMMListHead *list, *next; + struct _DriKernelBO *kbo; + + if (!driTimeAfterEq(time, &fMan->nextCheck)) + return; + + for (list = fMan->timeoutList.next, next = list->next; + list != &fMan->timeoutList; + list = next, next = list->next) { + + kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); + + if (!driTimeAfterEq(time, &kbo->timeFreed)) + break; + + DRMLISTDELINIT(&kbo->timeoutHead); + DRMLISTDELINIT(&kbo->head); + driFreeKernelBO(kbo); + } + + fMan->nextCheck = *time; + driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); +} + + +/* + * Add a _DriKernelBO to the free slab manager. + * This means that it is available for reuse, but if it's not + * reused in a while, it will be freed. + */ + +static void +driSetKernelBOFree(struct _DriFreeSlabManager *fMan, + struct _DriKernelBO *kbo) +{ + struct timeval time; + + _glthread_LOCK_MUTEX(fMan->mutex); + gettimeofday(&time, NULL); + driTimeAdd(&time, &fMan->slabTimeout); + + kbo->timeFreed = time; + + if (kbo->bo.flags & DRM_BO_FLAG_CACHED) + DRMLISTADD(&kbo->head, &fMan->cached); + else + DRMLISTADD(&kbo->head, &fMan->unCached); + + DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); + driFreeTimeoutKBOsLocked(fMan, &time); + + _glthread_UNLOCK_MUTEX(fMan->mutex); +} + +/* + * Get a _DriKernelBO for us to use as storage for a slab. + * + */ + +static struct _DriKernelBO * +driAllocKernelBO(struct _DriSlabSizeHeader *header) + +{ + struct _DriSlabPool *slabPool = header->slabPool; + struct _DriFreeSlabManager *fMan = slabPool->fMan; + drmMMListHead *list, *next, *head; + uint32_t size = header->bufSize * slabPool->desiredNumBuffers; + struct _DriKernelBO *kbo; + struct _DriKernelBO *kboTmp; + int ret; + + /* + * FIXME: We should perhaps allow some variation in slabsize in order + * to efficiently reuse slabs. + */ + + size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; + size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); + _glthread_LOCK_MUTEX(fMan->mutex); + + kbo = NULL; + + retry: + head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? + &fMan->cached : &fMan->unCached; + + for (list = head->next, next = list->next; + list != head; + list = next, next = list->next) { + + kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); + + if ((kboTmp->bo.size == size) && + (slabPool->pageAlignment == 0 || + (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { + + if (!kbo) + kbo = kboTmp; + + if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) + break; + + } + } + + if (kbo) { + DRMLISTDELINIT(&kbo->head); + DRMLISTDELINIT(&kbo->timeoutHead); + } + + _glthread_UNLOCK_MUTEX(fMan->mutex); + + if (kbo) { + uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; + + ret = 0; + if (new_mask) { + ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, + new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); + } + if (ret == 0) + return kbo; + + driFreeKernelBO(kbo); + kbo = NULL; + goto retry; + } + + kbo = calloc(1, sizeof(struct _DriKernelBO)); + if (!kbo) + return NULL; + + kbo->fd = slabPool->fd; + DRMINITLISTHEAD(&kbo->head); + DRMINITLISTHEAD(&kbo->timeoutHead); + ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, + slabPool->proposedFlags, + DRM_BO_HINT_DONT_FENCE, &kbo->bo); + if (ret) + goto out_err0; + + ret = drmBOMap(kbo->fd, &kbo->bo, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &kbo->virtual); + + if (ret) + goto out_err1; + + ret = drmBOUnmap(kbo->fd, &kbo->bo); + if (ret) + goto out_err1; + + return kbo; + + out_err1: + drmBOUnreference(kbo->fd, &kbo->bo); + out_err0: + free(kbo); + return NULL; +} + + +static int +driAllocSlab(struct _DriSlabSizeHeader *header) +{ + struct _DriSlab *slab; + struct _DriSlabBuffer *buf; + uint32_t numBuffers; + int ret; + int i; + + slab = calloc(1, sizeof(*slab)); + if (!slab) + return -ENOMEM; + + slab->kbo = driAllocKernelBO(header); + if (!slab->kbo) { + ret = -ENOMEM; + goto out_err0; + } + + numBuffers = slab->kbo->bo.size / header->bufSize; + + slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); + if (!slab->buffers) { + ret = -ENOMEM; + goto out_err1; + } + + DRMINITLISTHEAD(&slab->head); + DRMINITLISTHEAD(&slab->freeBuffers); + slab->numBuffers = numBuffers; + slab->numFree = 0; + slab->header = header; + + buf = slab->buffers; + for (i=0; i < numBuffers; ++i) { + buf->parent = slab; + buf->start = i* header->bufSize; + buf->mapCount = 0; + buf->isSlabBuffer = 1; + _glthread_INIT_COND(buf->event); + DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); + slab->numFree++; + buf++; + } + + DRMLISTADDTAIL(&slab->head, &header->slabs); + + return 0; + + out_err1: + driSetKernelBOFree(header->slabPool->fMan, slab->kbo); + free(slab->buffers); + out_err0: + free(slab); + return ret; +} + +/* + * Delete a buffer from the slab header delayed list and put + * it on the slab free list. + */ + +static void +driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) +{ + struct _DriSlab *slab = buf->parent; + struct _DriSlabSizeHeader *header = slab->header; + drmMMListHead *list = &buf->head; + + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &slab->freeBuffers); + slab->numFree++; + + if (slab->head.next == &slab->head) + DRMLISTADDTAIL(&slab->head, &header->slabs); + + if (slab->numFree == slab->numBuffers) { + list = &slab->head; + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &header->freeSlabs); + } + + if (header->slabs.next == &header->slabs || + slab->numFree != slab->numBuffers) { + + drmMMListHead *next; + struct _DriFreeSlabManager *fMan = header->slabPool->fMan; + + for (list = header->freeSlabs.next, next = list->next; + list != &header->freeSlabs; + list = next, next = list->next) { + + slab = DRMLISTENTRY(struct _DriSlab, list, head); + + DRMLISTDELINIT(list); + driSetKernelBOFree(fMan, slab->kbo); + free(slab->buffers); + free(slab); + } + } +} + +static void +driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) +{ + drmMMListHead *list, *prev, *first; + struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + int firstWasSignaled = 1; + int signaled; + int i; + int ret; + + /* + * Rerun the freeing test if the youngest tested buffer + * was signaled, since there might be more idle buffers + * in the delay list. + */ + + while (firstWasSignaled) { + firstWasSignaled = 0; + signaled = 0; + first = header->delayedBuffers.next; + + /* Only examine the oldest 1/3 of delayed buffers: + */ + if (header->numDelayed > 3) { + for (i = 0; i < header->numDelayed; i += 3) { + first = first->next; + } + } + + for (list = first, prev = list->prev; + list != &header->delayedBuffers; + list = prev, prev = list->prev) { + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + slab = buf->parent; + + if (!signaled) { + if (wait) { + ret = driFenceFinish(buf->fence, buf->fenceType, 0); + if (ret) + break; + signaled = 1; + wait = 0; + } else { + signaled = driFenceSignaled(buf->fence, buf->fenceType); + } + if (signaled) { + if (list == first) + firstWasSignaled = 1; + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } + } +} + + +static struct _DriSlabBuffer * +driSlabAllocBuffer(struct _DriSlabSizeHeader *header) +{ + static struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + drmMMListHead *list; + int count = DRI_SLABPOOL_ALLOC_RETRIES; + + _glthread_LOCK_MUTEX(header->mutex); + while(header->slabs.next == &header->slabs && count > 0) { + driSlabCheckFreeLocked(header, 0); + if (header->slabs.next != &header->slabs) + break; + + _glthread_UNLOCK_MUTEX(header->mutex); + if (count != DRI_SLABPOOL_ALLOC_RETRIES) + usleep(1); + _glthread_LOCK_MUTEX(header->mutex); + (void) driAllocSlab(header); + count--; + } + + list = header->slabs.next; + if (list == &header->slabs) { + _glthread_UNLOCK_MUTEX(header->mutex); + return NULL; + } + slab = DRMLISTENTRY(struct _DriSlab, list, head); + if (--slab->numFree == 0) + DRMLISTDELINIT(list); + + list = slab->freeBuffers.next; + DRMLISTDELINIT(list); + + _glthread_UNLOCK_MUTEX(header->mutex); + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + return buf; +} + +static void * +pool_create(struct _DriBufferPool *driPool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment) +{ + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + struct _DriSlabSizeHeader *header; + struct _DriSlabBuffer *buf; + void *dummy; + int i; + int ret; + + /* + * FIXME: Check for compatibility. + */ + + header = pool->headers; + for (i=0; inumBuckets; ++i) { + if (header->bufSize >= size) + break; + header++; + } + + if (i < pool->numBuckets) + return driSlabAllocBuffer(header); + + + /* + * Fall back to allocate a buffer object directly from DRM. + * and wrap it in a driBO structure. + */ + + + buf = calloc(1, sizeof(*buf)); + + if (!buf) + return NULL; + + buf->bo = calloc(1, sizeof(*buf->bo)); + if (!buf->bo) + goto out_err0; + + if (alignment) { + if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) + goto out_err1; + if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) + goto out_err1; + } + + ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, + flags, hint, buf->bo); + if (ret) + goto out_err1; + + ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &dummy); + if (ret) + goto out_err2; + + ret = drmBOUnmap(pool->fd, buf->bo); + if (ret) + goto out_err2; + + return buf; + out_err2: + drmBOUnreference(pool->fd, buf->bo); + out_err1: + free(buf->bo); + out_err0: + free(buf); + return NULL; +} + +static int +pool_destroy(struct _DriBufferPool *driPool, void *private) +{ + struct _DriSlabBuffer *buf = + (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + int ret; + + ret = drmBOUnreference(pool->fd, buf->bo); + free(buf->bo); + free(buf); + return ret; + } + + slab = buf->parent; + header = slab->header; + + _glthread_LOCK_MUTEX(header->mutex); + buf->unFenced = 0; + buf->mapCount = 0; + + if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { + DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); + header->numDelayed++; + } else { + if (buf->fence) + driFenceUnReference(&buf->fence); + driSlabFreeBufferLocked(buf); + } + + _glthread_UNLOCK_MUTEX(header->mutex); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *driPool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + while(buf->unFenced) + _glthread_COND_WAIT(buf->event, *mutex); + + if (!buf->fence) + return 0; + + driFenceFinish(buf->fence, buf->fenceType, lazy); + driFenceUnReference(&buf->fence); + + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + int busy; + + if (buf->isSlabBuffer) + busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); + else + busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); + + + if (busy) { + if (hint & DRM_BO_HINT_DONT_BLOCK) + return -EBUSY; + else { + (void) pool_waitIdle(pool, private, mutex, 0); + } + } + + ++buf->mapCount; + *virtual = (buf->isSlabBuffer) ? + (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : + (void *) buf->bo->virtual; + + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + --buf->mapCount; + if (buf->mapCount == 0 && buf->isSlabBuffer) + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return buf->bo->offset; + } + + slab = buf->parent; + header = slab->header; + + (void) header; + assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return slab->kbo->bo.offset + buf->start; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return buf->start; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return buf->bo->flags; + + return buf->parent->kbo->bo.flags; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + if (!buf->isSlabBuffer) + return buf->bo->size; + + return buf->parent->header->bufSize; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + drmBO *bo; + + if (buf->fence) + driFenceUnReference(&buf->fence); + + buf->fence = driFenceReference(fence); + bo = (buf->isSlabBuffer) ? + &buf->parent->kbo->bo: + buf->bo; + buf->fenceType = bo->fenceFlags; + + buf->unFenced = 0; + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; +} + +static int +pool_validate(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return 0; + + while(buf->mapCount != 0) + _glthread_COND_WAIT(buf->event, *mutex); + + buf->unFenced = 1; + return 0; +} + + +struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) +{ + struct _DriFreeSlabManager *tmp; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; + tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; + tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; + + tmp->checkInterval.tv_usec = checkIntervalMsec*1000; + tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; + tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; + + gettimeofday(&tmp->nextCheck, NULL); + driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); + DRMINITLISTHEAD(&tmp->timeoutList); + DRMINITLISTHEAD(&tmp->unCached); + DRMINITLISTHEAD(&tmp->cached); + _glthread_UNLOCK_MUTEX(tmp->mutex); + + return tmp; +} + +void +driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) +{ + struct timeval time; + + time = fMan->nextCheck; + driTimeAdd(&time, &fMan->checkInterval); + + _glthread_LOCK_MUTEX(fMan->mutex); + driFreeTimeoutKBOsLocked(fMan, &time); + _glthread_UNLOCK_MUTEX(fMan->mutex); + + assert(fMan->timeoutList.next == &fMan->timeoutList); + assert(fMan->unCached.next == &fMan->unCached); + assert(fMan->cached.next == &fMan->cached); + + free(fMan); +} + +static void +driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, + struct _DriSlabSizeHeader *header) +{ + _glthread_INIT_MUTEX(header->mutex); + _glthread_LOCK_MUTEX(header->mutex); + + DRMINITLISTHEAD(&header->slabs); + DRMINITLISTHEAD(&header->freeSlabs); + DRMINITLISTHEAD(&header->delayedBuffers); + + header->numDelayed = 0; + header->slabPool = pool; + header->bufSize = size; + + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +driFinishSizeHeader(struct _DriSlabSizeHeader *header) +{ + drmMMListHead *list, *next; + struct _DriSlabBuffer *buf; + + _glthread_LOCK_MUTEX(header->mutex); + for (list = header->delayedBuffers.next, next = list->next; + list != &header->delayedBuffers; + list = next, next = list->next) { + + buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); + if (buf->fence) { + (void) driFenceFinish(buf->fence, buf->fenceType, 0); + driFenceUnReference(&buf->fence); + } + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +pool_takedown(struct _DriBufferPool *driPool) +{ + struct _DriSlabPool *pool = driPool->data; + int i; + + for (i=0; inumBuckets; ++i) { + driFinishSizeHeader(&pool->headers[i]); + } + + free(pool->headers); + free(pool->bucketSizes); + free(pool); + free(driPool); +} + +struct _DriBufferPool * +driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan) +{ + struct _DriBufferPool *driPool; + struct _DriSlabPool *pool; + uint32_t i; + + driPool = calloc(1, sizeof(*driPool)); + if (!driPool) + return NULL; + + pool = calloc(1, sizeof(*pool)); + if (!pool) + goto out_err0; + + pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); + if (!pool->bucketSizes) + goto out_err1; + + pool->headers = calloc(numSizes, sizeof(*pool->headers)); + if (!pool->headers) + goto out_err2; + + pool->fMan = fMan; + pool->proposedFlags = flags; + pool->validMask = validMask; + pool->numBuckets = numSizes; + pool->pageSize = getpagesize(); + pool->fd = fd; + pool->pageAlignment = pageAlignment; + pool->maxSlabSize = maxSlabSize; + pool->desiredNumBuffers = desiredNumBuffers; + + for (i=0; inumBuckets; ++i) { + pool->bucketSizes[i] = (smallestSize << i); + driInitSizeHeader(pool, pool->bucketSizes[i], + &pool->headers[i]); + } + + driPool->data = (void *) pool; + driPool->map = &pool_map; + driPool->unmap = &pool_unmap; + driPool->destroy = &pool_destroy; + driPool->offset = &pool_offset; + driPool->poolOffset = &pool_poolOffset; + driPool->flags = &pool_flags; + driPool->size = &pool_size; + driPool->create = &pool_create; + driPool->fence = &pool_fence; + driPool->kernel = &pool_kernel; + driPool->validate = &pool_validate; + driPool->waitIdle = &pool_waitIdle; + driPool->takeDown = &pool_takedown; + + return driPool; + + out_err2: + free(pool->bucketSizes); + out_err1: + free(pool); + out_err0: + free(driPool); + + return NULL; +} diff --git a/src/gallium/winsys/drm/intel/dri/Makefile b/src/gallium/winsys/drm/intel/dri/Makefile new file mode 100644 index 0000000000..2046441a22 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/Makefile @@ -0,0 +1,33 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +LIBNAME = i915_dri.so +LIBNAME_EGL = egl_i915_dri.so + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + ../common/libinteldrm.a \ + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a + + +DRIVER_SOURCES = \ + intel_winsys_softpipe.c \ + intel_swapbuffers.c \ + intel_context.c \ + intel_lock.c \ + intel_screen.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +DRIVER_DEFINES = -I../common $(shell pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") + +include ../../Makefile.template + +#intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c + +symlinks: diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript new file mode 100644 index 0000000000..6a4f50afcc --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/SConscript @@ -0,0 +1,41 @@ +Import('*') + +if 'mesa' in env['statetrackers']: + + env = drienv.Clone() + + env.Append(CPPPATH = [ + '../intel', + 'server' + ]) + + #MINIGLX_SOURCES = server/intel_dri.c + + DRIVER_SOURCES = [ + 'intel_winsys_pipe.c', + 'intel_winsys_softpipe.c', + 'intel_winsys_i915.c', + 'intel_batchbuffer.c', + 'intel_swapbuffers.c', + 'intel_context.c', + 'intel_lock.c', + 'intel_screen.c', + 'intel_batchpool.c', + ] + + sources = \ + COMMON_GALLIUM_SOURCES + \ + COMMON_BM_SOURCES + \ + DRIVER_SOURCES + + drivers = [ + softpipe, + i915simple + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='i915tex_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/winsys/drm/intel/dri/intel_batchbuffer.h b/src/gallium/winsys/drm/intel/dri/intel_batchbuffer.h new file mode 100644 index 0000000000..3e95326168 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_batchbuffer.h @@ -0,0 +1,24 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "intel_be_batchbuffer.h" + +/* + * Need to redefine the BATCH defines + */ + +#undef BEGIN_BATCH +#define BEGIN_BATCH(dwords, relocs) \ + (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) + +#undef OUT_BATCH +#define OUT_BATCH(d) \ + i915_batchbuffer_dword(&intel->base.batch->base, d) + +#undef OUT_RELOC +#define OUT_RELOC(buf,flags,mask,delta) do { \ + assert((delta) >= 0); \ + intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ +} while (0) + +#endif diff --git a/src/gallium/winsys/drm/intel/dri/intel_context.c b/src/gallium/winsys/drm/intel/dri/intel_context.c new file mode 100644 index 0000000000..97ef731aaa --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_context.c @@ -0,0 +1,337 @@ +/************************************************************************** + * + * 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 "i830_dri.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_swapbuffers.h" +#include "intel_batchbuffer.h" +#include "intel_winsys_softpipe.h" + +#include "i915simple/i915_screen.h" + +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" + +#include "utils.h" + + +#ifdef DEBUG +int __intel_debug = 0; +#endif + + +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_NV_vertex_program +#include "extension_helper.h" + + +/** + * Extension strings exported by the intel driver. + * + * \note + * It appears that ARB_texture_env_crossbar has "disappeared" compared to the + * old i830-specific driver. + */ +const struct dri_extension card_extensions[] = { + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, + {"GL_SGIS_generate_mipmap", NULL }, + {NULL, NULL} +}; + + + +#ifdef DEBUG +static const struct dri_debug_control debug_control[] = { + {"ioctl", DEBUG_IOCTL}, + {"bat", DEBUG_BATCH}, + {"lock", DEBUG_LOCK}, + {"swap", DEBUG_SWAP}, + {NULL, 0} +}; +#endif + + + +static void +intel_lock_hardware(struct intel_be_context *context) +{ + struct intel_context *intel = (struct intel_context *)context; + LOCK_HARDWARE(intel); +} + +static void +intel_unlock_hardware(struct intel_be_context *context) +{ + struct intel_context *intel = (struct intel_context *)context; + UNLOCK_HARDWARE(intel); +} + +static boolean +intel_locked_hardware(struct intel_be_context *context) +{ + struct intel_context *intel = (struct intel_context *)context; + return intel->locked ? TRUE : FALSE; +} + +GLboolean +intelCreateContext(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + struct intel_context *intel = CALLOC_STRUCT(intel_context); + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + struct intel_screen *intelScreen = intel_screen(sPriv); + drmI830Sarea *saPriv = intelScreen->sarea; + int fthrottle_mode; + GLboolean havePools; + struct pipe_context *pipe; + struct st_context *st_share = NULL; + + if (sharedContextPrivate) { + st_share = ((struct intel_context *) sharedContextPrivate)->st; + } + + driContextPriv->driverPrivate = intel; + intel->intelScreen = intelScreen; + intel->driScreen = sPriv; + intel->sarea = saPriv; + + driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, "i915"); + + + /* + * memory pools + */ + DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + // ZZZ JB should be per screen and not be done per context + havePools = intelCreatePools(sPriv); + DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + if (!havePools) + return GL_FALSE; + + + /* Dri stuff */ + intel->hHWContext = driContextPriv->hHWContext; + intel->driFd = sPriv->fd; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + + fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); + intel->iw.irq_seq = -1; + intel->irqsEmitted = 0; + + intel->last_swap_fence = NULL; + intel->first_swap_fence = NULL; + +#ifdef DEBUG + __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); +#endif + intel->base.hardware_lock = intel_lock_hardware; + intel->base.hardware_unlock = intel_unlock_hardware; + intel->base.hardware_locked = intel_locked_hardware; + + intel_be_init_context(&intel->base, &intelScreen->base); + + /* + * Pipe-related setup + */ + if (getenv("INTEL_SP")) { + /* use softpipe driver instead of hw */ + pipe = intel_create_softpipe( intel, &intelScreen->base.base ); + } + else { + switch (intel->intelScreen->deviceID) { + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + case PCI_CHIP_I945_GME: + case PCI_CHIP_G33_G: + case PCI_CHIP_Q33_G: + case PCI_CHIP_Q35_G: + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + pipe = i915_create_context(intelScreen->base.screen, + &intelScreen->base.base, + &intel->base.base); + break; + default: + fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", + intel->intelScreen->deviceID, __FUNCTION__); + + pipe = intel_create_softpipe( intel, &intelScreen->base.base ); + break; + } + } + + pipe->priv = intel; + + intel->st = st_create_context(pipe, visual, st_share); + + driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE ); + + return GL_TRUE; +} + + +void +intelDestroyContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = intel_context(driContextPriv); + + assert(intel); /* should never be null */ + if (intel) { + st_finish(intel->st); + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(&intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + if (intel->first_swap_fence) { + driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(&intel->first_swap_fence); + intel->first_swap_fence = NULL; + } + + if (intel->intelScreen->dummyContext == intel) + intel->intelScreen->dummyContext = NULL; + + st_destroy_context(intel->st); + intel_be_destroy_context(&intel->base); + free(intel); + } +} + + +GLboolean +intelUnbindContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = intel_context(driContextPriv); + st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL); + /* XXX make_current(NULL)? */ + return GL_TRUE; +} + + +GLboolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) +{ + if (driContextPriv) { + struct intel_context *intel = intel_context(driContextPriv); + struct intel_framebuffer *draw_fb = intel_framebuffer(driDrawPriv); + struct intel_framebuffer *read_fb = intel_framebuffer(driReadPriv); + + assert(draw_fb->stfb); + assert(read_fb->stfb); + + /* This is for situations in which we need a rendering context but + * there may not be any currently bound. + */ + intel->intelScreen->dummyContext = intel; + + st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); + + if ((intel->driDrawable != driDrawPriv) || + (intel->lastStamp != driDrawPriv->lastStamp)) { + intel->driDrawable = driDrawPriv; + intelUpdateWindowSize(driDrawPriv); + intel->lastStamp = driDrawPriv->lastStamp; + } + + /* The size of the draw buffer will have been updated above. + * If the readbuffer is a different window, check/update its size now. + */ + if (driReadPriv != driDrawPriv) { + intelUpdateWindowSize(driReadPriv); + } + + } + else { + st_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} diff --git a/src/gallium/winsys/drm/intel/dri/intel_context.h b/src/gallium/winsys/drm/intel/dri/intel_context.h new file mode 100644 index 0000000000..5d22a422af --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_context.h @@ -0,0 +1,164 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef INTEL_CONTEXT_H +#define INTEL_CONTEXT_H + +#include +#include "drm.h" + +#include "pipe/p_debug.h" + +#include "intel_screen.h" +#include "i915_drm.h" + +#include "intel_be_context.h" + + +struct pipe_context; +struct intel_context; +struct _DriBufferObject; +struct st_context; + + +#define INTEL_MAX_FIXUP 64 + +/** + * Intel rendering context, contains a state tracker and intel-specific info. + */ +struct intel_context +{ + struct intel_be_context base; + struct st_context *st; + + struct _DriFenceObject *last_swap_fence; + struct _DriFenceObject *first_swap_fence; + +// struct intel_batchbuffer *batch; + + boolean locked; + char *prevLockFile; + int prevLockLine; + + uint irqsEmitted; + drm_i915_irq_wait_t iw; + + drm_context_t hHWContext; + drmLock *driHwLock; + int driFd; + + __DRIdrawablePrivate *driDrawable; + __DRIscreenPrivate *driScreen; + struct intel_screen *intelScreen; + drmI830Sarea *sarea; + + uint lastStamp; + + /** + * Configuration cache + */ + driOptionCache optionCache; +}; + + + +/** + * Intel framebuffer. + */ +struct intel_framebuffer +{ + struct st_framebuffer *stfb; + + /* other fields TBD */ + int other; +}; + + + + +/* These are functions now: + */ +void LOCK_HARDWARE( struct intel_context *intel ); +void UNLOCK_HARDWARE( struct intel_context *intel ); + +extern char *__progname; + + + +/* ================================================================ + * Debugging: + */ +#ifdef DEBUG +extern int __intel_debug; + +#define DEBUG_SWAP 0x1 +#define DEBUG_LOCK 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BATCH 0x8 + +#define DBG(flag, ...) do { \ + if (__intel_debug & (DEBUG_##flag)) \ + printf(__VA_ARGS__); \ +} while(0) + +#else +#define DBG(flag, ...) +#endif + + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_Q33_G 0x29D2 + + +/** Cast wrapper */ +static INLINE struct intel_context * +intel_context(__DRIcontextPrivate *driContextPriv) +{ + return (struct intel_context *) driContextPriv->driverPrivate; +} + + +/** Cast wrapper */ +static INLINE struct intel_framebuffer * +intel_framebuffer(__DRIdrawablePrivate * driDrawPriv) +{ + return (struct intel_framebuffer *) driDrawPriv->driverPrivate; +} + + +#endif diff --git a/src/gallium/winsys/drm/intel/dri/intel_lock.c b/src/gallium/winsys/drm/intel/dri/intel_lock.c new file mode 100644 index 0000000000..406284c98f --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_lock.c @@ -0,0 +1,102 @@ +/************************************************************************** + * + * 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 "main/glheader.h" +#include "glapi/glthread.h" +#include +#include "state_tracker/st_public.h" +#include "intel_context.h" +#include "i830_dri.h" + + + +_glthread_DECLARE_STATIC_MUTEX( lockMutex ); + + +static void +intelContendedLock(struct intel_context *intel, uint flags) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIscreenPrivate *sPriv = intel->driScreen; + struct intel_screen *intelScreen = intel_screen(sPriv); + drmI830Sarea *sarea = intel->sarea; + + drmGetLock(intel->driFd, intel->hHWContext, flags); + + DBG(LOCK, "%s - got contended lock\n", __progname); + + /* 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); + + if (sarea->width != intelScreen->front.width || + sarea->height != intelScreen->front.height) { + + intelUpdateScreenRotation(sPriv, sarea); + } +} + + +/* Lock the hardware and validate our state. + */ +void LOCK_HARDWARE( struct intel_context *intel ) +{ + char __ret = 0; + + _glthread_LOCK_MUTEX(lockMutex); + assert(!intel->locked); + + DRM_CAS(intel->driHwLock, intel->hHWContext, + (DRM_LOCK_HELD|intel->hHWContext), __ret); + + if (__ret) + intelContendedLock( intel, 0 ); + + DBG(LOCK, "%s - locked\n", __progname); + + intel->locked = 1; +} + + +/* Unlock the hardware using the global current context + */ +void UNLOCK_HARDWARE( struct intel_context *intel ) +{ + assert(intel->locked); + intel->locked = 0; + + DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); + + _glthread_UNLOCK_MUTEX(lockMutex); + + DBG(LOCK, "%s - unlocked\n", __progname); +} diff --git a/src/gallium/winsys/drm/intel/dri/intel_reg.h b/src/gallium/winsys/drm/intel/dri/intel_reg.h new file mode 100644 index 0000000000..4f33bee438 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_reg.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + + +#ifndef _INTEL_REG_H_ +#define _INTEL_REG_H_ + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) + +#define MI_BATCH_BUFFER_END (0xA<<23) + + +#endif diff --git a/src/gallium/winsys/drm/intel/dri/intel_screen.c b/src/gallium/winsys/drm/intel/dri/intel_screen.c new file mode 100644 index 0000000000..46d4861e77 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_screen.c @@ -0,0 +1,607 @@ +/************************************************************************** + * + * 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 "utils.h" +#include "vblank.h" +#include "xmlpool.h" + +#include "intel_context.h" +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_swapbuffers.h" + +#include "i830_dri.h" +#include "ws_dri_bufpool.h" + +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_inlines.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_cb_fbo.h" + +static void +intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle); + +static void +intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle) +{ + struct pipe_screen *screen = intelScreen->base.screen; + struct pipe_texture *texture; + struct pipe_texture templat; + struct pipe_surface *surface; + struct pipe_buffer *buffer; + unsigned pitch; + + assert(intelScreen->front.cpp == 4); + + buffer = intel_be_buffer_from_handle(&intelScreen->base, + "front", handle); + + if (!buffer) + return; + + intelScreen->front.buffer = dri_bo(buffer); + + memset(&templat, 0, sizeof(templat)); + templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + templat.target = PIPE_TEXTURE_2D; + templat.last_level = 0; + templat.depth[0] = 1; + templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; + templat.width[0] = intelScreen->front.width; + templat.height[0] = intelScreen->front.height; + pf_get_block(templat.format, &templat.block); + pitch = intelScreen->front.pitch; + + texture = screen->texture_blanket(screen, + &templat, + &pitch, + buffer); + + /* Unref the buffer we don't need it anyways */ + pipe_buffer_reference(screen->winsys, &buffer, NULL); + + surface = screen->get_tex_surface(screen, + texture, + 0, + 0, + 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + + intelScreen->front.texture = texture; + intelScreen->front.surface = surface; +} + +PUBLIC const char __driConfigOptions[] = + DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY +// DRI_CONF_FORCE_S3TC_ENABLE(false) + DRI_CONF_ALLOW_LARGE_TEXTURES(1) + DRI_CONF_SECTION_END DRI_CONF_END; + +const uint __driNConfigOptions = 3; + +#ifdef USE_NEW_INTERFACE +static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; +#endif /*USE_NEW_INTERFACE */ + +extern const struct dri_extension card_extensions[]; + + + + +static void +intelPrintDRIInfo(struct intel_screen * intelScreen, + __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) +{ + fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->front.size, intelScreen->front.offset, + intelScreen->front.pitch); + fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); +} + + +#if 0 +static void +intelPrintSAREA(const drmI830Sarea * sarea) +{ + fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, + sarea->height); + fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); + fprintf(stderr, + "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->front_offset, sarea->front_size, + (unsigned) sarea->front_handle); + fprintf(stderr, + "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->back_offset, sarea->back_size, + (unsigned) sarea->back_handle); + fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->depth_offset, sarea->depth_size, + (unsigned) sarea->depth_handle); + fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); + fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); + fprintf(stderr, + "SAREA: rotated offset: 0x%08x size: 0x%x\n", + sarea->rotated_offset, sarea->rotated_size); + fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); +} +#endif + + +/** + * Use the information in the sarea to update the screen parameters + * related to screen rotation. Needs to be called locked. + */ +void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) +{ + struct intel_screen *intelScreen = intel_screen(sPriv); + + if (intelScreen->front.map) { + drmUnmap(intelScreen->front.map, intelScreen->front.size); + intelScreen->front.map = NULL; + } + + if (intelScreen->front.buffer) + driDeleteBuffers(1, &intelScreen->front.buffer); + + intelScreen->front.width = sarea->width; + intelScreen->front.height = sarea->height; + intelScreen->front.offset = sarea->front_offset; + intelScreen->front.pitch = sarea->pitch * intelScreen->front.cpp; + intelScreen->front.size = sarea->front_size; + intelScreen->front.handle = sarea->front_handle; + + assert( sarea->front_size >= + intelScreen->front.pitch * intelScreen->front.height ); + +#if 0 /* JB not important */ + if (!sarea->front_handle) + return; + + if (drmMap(sPriv->fd, + sarea->front_handle, + intelScreen->front.size, + (drmAddress *) & intelScreen->front.map) != 0) { + fprintf(stderr, "drmMap(frontbuffer) failed!\n"); + return; + } +#endif + +#if 0 /* JB */ + if (intelScreen->staticPool) { + driGenBuffers(intelScreen->staticPool, "static region", 1, + &intelScreen->front.buffer, 64, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + + driBOSetStatic(intelScreen->front.buffer, + intelScreen->front.offset, + intelScreen->front.pitch * intelScreen->front.height, + intelScreen->front.map, 0); + } +#else + if (intelScreen->base.staticPool) { + if (intelScreen->front.buffer) { + driBOUnReference(intelScreen->front.buffer); + pipe_surface_reference(&intelScreen->front.surface, NULL); + pipe_texture_reference(&intelScreen->front.texture, NULL); + } + intelCreateSurface(intelScreen, &intelScreen->base.base, sarea->front_bo_handle); + } +#endif +} + + +boolean +intelCreatePools(__DRIscreenPrivate * sPriv) +{ + //unsigned batchPoolSize = 1024*1024; + struct intel_screen *intelScreen = intel_screen(sPriv); + + if (intelScreen->havePools) + return GL_TRUE; + + intelScreen->havePools = GL_TRUE; + + intelUpdateScreenRotation(sPriv, intelScreen->sarea); + + return GL_TRUE; +} + +static const char * +intel_get_name( struct pipe_winsys *winsys ) +{ + return "Intel/DRI/ttm"; +} + +/* + * The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +intel_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + intelDisplaySurface(dPriv, surf, NULL); +} + +static boolean +intelInitDriver(__DRIscreenPrivate * sPriv) +{ + struct intel_screen *intelScreen; + I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; + + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> + getProcAddress("glxEnableExtension")); + void *const psc = sPriv->psc->screenConfigs; + + if (sPriv->devPrivSize != sizeof(I830DRIRec)) { + fprintf(stderr, + "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); + return GL_FALSE; + } + + /* Allocate the private area */ + intelScreen = CALLOC_STRUCT(intel_screen); + if (!intelScreen) + return GL_FALSE; + + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); + + sPriv->private = (void *) intelScreen; + + intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + + gDRIPriv->sarea_priv_offset); + intelScreen->deviceID = gDRIPriv->deviceID; + intelScreen->front.cpp = gDRIPriv->cpp; + intelScreen->drmMinor = sPriv->drmMinor; + + assert(gDRIPriv->bitsPerPixel == 16 || + gDRIPriv->bitsPerPixel == 32); + + intelUpdateScreenRotation(sPriv, intelScreen->sarea); + + if (0) + intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); + + if (glx_enable_extension != NULL) { + (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); + (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); + (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); + } + + intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; + intelScreen->base.base.get_name = intel_get_name; + intel_be_init_device(&intelScreen->base, sPriv->fd, intelScreen->deviceID); + + return GL_TRUE; +} + + +static void +intelDestroyScreen(__DRIscreenPrivate * sPriv) +{ + struct intel_screen *intelScreen = intel_screen(sPriv); + + intel_be_destroy_device(&intelScreen->base); + /* intelUnmapScreenRegions(intelScreen); */ + + FREE(intelScreen); + sPriv->private = NULL; +} + + +/** + * This is called when we need to set up GL rendering to a new X window. + */ +static boolean +intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, + __DRIdrawablePrivate * driDrawPriv, + const __GLcontextModes * visual, boolean isPixmap) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + + if (!intelfb) + return GL_FALSE; + + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + driDrawPriv->w, + driDrawPriv->h, + (void*) intelfb); + if (!intelfb->stfb) { + free(intelfb); + return GL_FALSE; + } + + driDrawPriv->driverPrivate = (void *) intelfb; + return GL_TRUE; + } +} + +static void +intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) +{ + struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv); + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); +} + + +/** + * Get information about previous buffer swaps. + */ +static int +intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) +{ + if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) + || (sInfo == NULL)) { + return -1; + } + + return 0; +} + + +static void +intelSetTexOffset(__DRIcontext *pDRICtx, int texname, + unsigned long long offset, int depth, uint pitch) +{ + abort(); +#if 0 + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct st_texture_object *stObj = st_texture_object(tObj); + + if (!stObj) + return; + + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); + + stObj->imageOverride = GL_TRUE; + stObj->depthOverride = depth; + stObj->pitchOverride = pitch; + + if (offset) + stObj->textureOffset = offset; +#endif +} + + +static const struct __DriverAPIRec intelAPI = { + .InitDriver = intelInitDriver, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = intelCopySubBuffer, + .setTexOffset = intelSetTexOffset, +}; + + +static __GLcontextModes * +intelFillInModes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, boolean have_back_buffer) +{ + __GLcontextModes *modes; + __GLcontextModes *m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_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; + msaa_samples_array[0] = 0; + + /* 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; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + 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; + } + + modes = + (*dri_interface->createContextModes) (num_modes, + sizeof(__GLcontextModes)); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, msaa_samples_array, 1, GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, msaa_samples_array, 1, GLX_DIRECT_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for (m = modes; m != NULL; m = m->next) { + if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, + __DRIscreen * psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 7, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 7, 0 }; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("i915", + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &intelAPI); + + if (psp != NULL) { + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + *driver_modes = intelFillInModes(dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create + * is called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + } + + return (void *) psp; +} + diff --git a/src/gallium/winsys/drm/intel/dri/intel_screen.h b/src/gallium/winsys/drm/intel/dri/intel_screen.h new file mode 100644 index 0000000000..0bb43a915c --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_screen.h @@ -0,0 +1,122 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef _INTEL_SCREEN_H_ +#define _INTEL_SCREEN_H_ + +#include "dri_util.h" +#include "i830_common.h" +#include "xmlconfig.h" +#include "ws_dri_bufpool.h" + +#include "pipe/p_compiler.h" + +#include "intel_be_device.h" + +struct intel_screen +{ + struct intel_be_device base; + + struct { + drm_handle_t handle; + + /* We create a static dri buffer for the frontbuffer. + */ + struct _DriBufferObject *buffer; + struct pipe_surface *surface; + struct pipe_texture *texture; + + char *map; /* memory map */ + int offset; /* from start of video mem, in bytes */ + int pitch; /* row stride, in bytes */ + int width; + int height; + int size; + int cpp; /* for front and back buffers */ + } front; + + int deviceID; + int drmMinor; + + drmI830Sarea *sarea; + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; + + boolean havePools; + + /** + * Temporary(?) context to use for SwapBuffers or other situations in + * which we need a rendering context, but none is currently bound. + */ + struct intel_context *dummyContext; + + /* + * New stuff form the i915tex integration + */ + unsigned batch_id; + + + struct pipe_winsys *winsys; +}; + + + +/** cast wrapper */ +static INLINE struct intel_screen * +intel_screen(__DRIscreenPrivate *sPriv) +{ + return (struct intel_screen *) sPriv->private; +} + + +extern void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); + + +extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); + +extern boolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); + +extern boolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + + +extern boolean +intelCreatePools(__DRIscreenPrivate *sPriv); + +extern boolean +intelCreateContext(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + + +#endif diff --git a/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c b/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c new file mode 100644 index 0000000000..8a18bfd9a4 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c @@ -0,0 +1,261 @@ +/************************************************************************** + * + * 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 "intel_screen.h" +#include "intel_context.h" +#include "intel_swapbuffers.h" + +#include "intel_reg.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 "ws_dri_bufmgr.h" +#include "intel_batchbuffer.h" + +/** + * Display a colorbuffer surface in an X window. + * Used for SwapBuffers and flushing front buffer rendering. + * + * \param dPriv the window/drawable to display into + * \param surf the surface to display + * \param rect optional subrect of surface to display (may be NULL). + */ +void +intelDisplaySurface(__DRIdrawablePrivate *dPriv, + struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + struct intel_context *intel = intelScreen->dummyContext; + + DBG(SWAP, "%s\n", __FUNCTION__); + + if (!intel) { + /* XXX this is where some kind of extra/meta context could be useful */ + return; + } + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); + driFenceUnReference(&intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + /* if this drawable isn't currently bound the LOCK_HARDWARE done on the + * current context (which is what intelScreenContext should return) might + * not get a contended lock and thus cliprects not updated (tests/manywin) + */ + if (intel_context(dPriv->driContextPriv) != intel) + DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); + + + if (dPriv && dPriv->numClipRects) { + const int srcWidth = surf->width; + const int srcHeight = surf->height; + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; + const int cpp = intelScreen->front.cpp; + const int srcpitch = surf->stride / cpp; + int BR13, CMD; + int i; + + ASSERT(surf->buffer); + ASSERT(surf->cpp == cpp); + + DBG(SWAP, "screen pitch %d src surface pitch %d\n", + pitch, surf->stride); + + if (cpp == 2) { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + } + else { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + } + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + drm_clip_rect_t sbox; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->front.width || + pbox->y2 > intelScreen->front.height) { + /* invalid cliprect, skip it */ + continue; + } + + box = *pbox; + + if (rect) { + /* intersect cliprect with user-provided src rect */ + drm_clip_rect_t rrect; + + rrect.x1 = dPriv->x + rect->x1; + rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; + rrect.x2 = rect->x2 + rrect.x1; + rrect.y2 = rect->y2 + rrect.y1; + if (rrect.x1 > box.x1) + box.x1 = rrect.x1; + if (rrect.y1 > box.y1) + box.y1 = rrect.y1; + if (rrect.x2 < box.x2) + box.x2 = rrect.x2; + if (rrect.y2 < box.y2) + box.y2 = rrect.y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + /* restrict blit to size of actually rendered area */ + if (box.x2 - box.x1 > srcWidth) + box.x2 = srcWidth + box.x1; + if (box.y2 - box.y1 > srcHeight) + box.y2 = srcHeight + box.y1; + + DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", + box.x1, box.x2, box.y1, box.y2); + + sbox.x1 = box.x1 - dPriv->x; + sbox.y1 = box.y1 - dPriv->y; + + assert(box.x1 < box.x2); + assert(box.y1 < box.y2); + + /* XXX this could be done with pipe->surface_copy() */ + /* XXX should have its own batch buffer */ + if (!BEGIN_BATCH(8, 2)) { + /* + * Since we share this batch buffer with a context + * we can't flush it since that risks a GPU lockup + */ + assert(0); + continue; + } + + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((box.y1 << 16) | box.x1); + OUT_BATCH((box.y2 << 16) | box.x2); + + OUT_RELOC(intelScreen->front.buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + OUT_BATCH((sbox.y1 << 16) | sbox.x1); + OUT_BATCH((srcpitch * cpp) & 0xffff); + OUT_RELOC(dri_bo(surf->buffer), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + } + + if (intel->first_swap_fence) + driFenceUnReference(&intel->first_swap_fence); + intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); + } + + UNLOCK_HARDWARE(intel); + + if (intel->lastStamp != dPriv->lastStamp) { + intelUpdateWindowSize(dPriv); + intel->lastStamp = dPriv->lastStamp; + } +} + + + +/** + * This will be called whenever the currently bound window is moved/resized. + */ +void +intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) +{ + struct intel_framebuffer *intelfb = intel_framebuffer(dPriv); + assert(intelfb->stfb); + st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); +} + + + +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + st_notify_swapbuffers(intel_fb->stfb); + intelDisplaySurface(dPriv, back_surf, NULL); + st_notify_swapbuffers_complete(intel_fb->stfb); + } +} + + +/** + * Called via glXCopySubBufferMESA() to copy a subrect of the back + * buffer to the front buffer/screen. + */ +void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ + struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + drm_clip_rect_t rect; + rect.x1 = x; + rect.y1 = y; + rect.x2 = w; + rect.y2 = h; + + st_notify_swapbuffers(intel_fb->stfb); + intelDisplaySurface(dPriv, back_surf, &rect); + } +} diff --git a/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.h b/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.h new file mode 100644 index 0000000000..46c9bab3af --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2006 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. + * + **************************************************************************/ + +#ifndef INTEL_SWAPBUFFERS_H +#define INTEL_SWAPBUFFERS_H + + +struct pipe_surface; + + +extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, + struct pipe_surface *surf, + const drm_clip_rect_t * rect); + +extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, + int x, int y, int w, int h); + +extern void intelUpdateWindowSize(__DRIdrawablePrivate *dPriv); + + +#endif /* INTEL_SWAPBUFFERS_H */ diff --git a/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c b/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c new file mode 100644 index 0000000000..0d98d16cf1 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c @@ -0,0 +1,82 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include "intel_context.h" +#include "intel_winsys_softpipe.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_format.h" +#include "softpipe/sp_winsys.h" + + +struct intel_softpipe_winsys { + struct softpipe_winsys sws; + struct intel_context *intel; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean +intel_is_format_supported(struct softpipe_winsys *sws, + enum pipe_format format) +{ + switch(format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: + return TRUE; + default: + return FALSE; + } +} + + +/** + * Create rendering context which uses software rendering. + */ +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ) +{ + struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); + struct pipe_screen *screen = softpipe_create_screen(winsys); + + /* Fill in this struct with callbacks that softpipe will need to + * communicate with the window system, buffer manager, etc. + */ + isws->sws.is_format_supported = intel_is_format_supported; + isws->intel = intel; + + /* Create the softpipe context: + */ + return softpipe_create( screen, winsys, &isws->sws ); +} diff --git a/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.h b/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.h new file mode 100644 index 0000000000..5fa14cb749 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.h @@ -0,0 +1,39 @@ +/************************************************************************** + * + * Copyright 2006 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. + * + **************************************************************************/ + +#ifndef INTEL_SOFTPIPE_H +#define INTEL_SOFTPIPE_H + +struct pipe_winsys; +struct pipe_context; +struct intel_context; + +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ); + +#endif diff --git a/src/gallium/winsys/drm/intel/dri/server/i830_common.h b/src/gallium/winsys/drm/intel/dri/server/i830_common.h new file mode 100644 index 0000000000..3452ddb3c9 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/server/i830_common.h @@ -0,0 +1,255 @@ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. +Copyright 2002 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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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. + +**************************************************************************/ + + +#ifndef _I830_COMMON_H_ +#define _I830_COMMON_H_ + + +#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ +#define I830_LOG_MIN_TEX_REGION_SIZE 14 + + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_I830_INIT 0x00 +#define DRM_I830_FLUSH 0x01 +#define DRM_I830_FLIP 0x02 +#define DRM_I830_BATCHBUFFER 0x03 +#define DRM_I830_IRQ_EMIT 0x04 +#define DRM_I830_IRQ_WAIT 0x05 +#define DRM_I830_GETPARAM 0x06 +#define DRM_I830_SETPARAM 0x07 +#define DRM_I830_ALLOC 0x08 +#define DRM_I830_FREE 0x09 +#define DRM_I830_INIT_HEAP 0x0a +#define DRM_I830_CMDBUFFER 0x0b +#define DRM_I830_DESTROY_HEAP 0x0c +#define DRM_I830_SET_VBLANK_PIPE 0x0d +#define DRM_I830_GET_VBLANK_PIPE 0x0e +#define DRM_I830_MMIO 0x10 + +typedef struct { + enum { + I830_INIT_DMA = 0x01, + I830_CLEANUP_DMA = 0x02, + I830_RESUME_DMA = 0x03 + } func; + unsigned int mmio_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; + unsigned int back_pitch; + unsigned int depth_pitch; + unsigned int cpp; + unsigned int chipset; +} drmI830Init; + +typedef struct { + drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; + int last_upload; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int ctxOwner; /* last context to upload state */ + /** Last context that used the buffer manager. */ + int texAge; + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + int perf_boxes; /* performance boxes to be displayed */ + int width, height; /* screen size in pixels */ + + drm_handle_t front_handle; + int front_offset; + int front_size; + + drm_handle_t back_handle; + int back_offset; + int back_size; + + drm_handle_t depth_handle; + int depth_offset; + int depth_size; + + drm_handle_t tex_handle; + int tex_offset; + int tex_size; + int log_tex_granularity; + int pitch; + int rotation; /* 0, 90, 180 or 270 */ + int rotated_offset; + int rotated_size; + int rotated_pitch; + int virtualX, virtualY; + + unsigned int front_tiled; + unsigned int back_tiled; + unsigned int depth_tiled; + unsigned int rotated_tiled; + unsigned int rotated2_tiled; + + int planeA_x; + int planeA_y; + int planeA_w; + int planeA_h; + int planeB_x; + int planeB_y; + int planeB_w; + int planeB_h; + + /* Triple buffering */ + drm_handle_t third_handle; + int third_offset; + int third_size; + unsigned int third_tiled; + + /* buffer object handles for the static buffers. May change + * over the lifetime of the client, though it doesn't in our current + * implementation. + */ + unsigned int front_bo_handle; + unsigned int back_bo_handle; + unsigned int third_bo_handle; + unsigned int depth_bo_handle; +} drmI830Sarea; + +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + + +typedef struct { + int start; /* agp offset */ + int used; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830BatchBuffer; + +typedef struct { + char *buf; /* agp offset */ + int sz; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830CmdBuffer; + +typedef struct { + int *irq_seq; +} drmI830IrqEmit; + +typedef struct { + int irq_seq; +} drmI830IrqWait; + +typedef struct { + int param; + int *value; +} drmI830GetParam; + +#define I830_PARAM_IRQ_ACTIVE 1 +#define I830_PARAM_ALLOW_BATCHBUFFER 2 + +typedef struct { + int param; + int value; +} drmI830SetParam; + +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 +#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 +#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 + + +/* A memory manager for regions of shared memory: + */ +#define I830_MEM_REGION_AGP 1 + +typedef struct { + int region; + int alignment; + int size; + int *region_offset; /* offset from start of fb or agp */ +} drmI830MemAlloc; + +typedef struct { + int region; + int region_offset; +} drmI830MemFree; + +typedef struct { + int region; + int size; + int start; +} drmI830MemInitHeap; + +typedef struct { + int region; +} drmI830MemDestroyHeap; + +#define DRM_I830_VBLANK_PIPE_A 1 +#define DRM_I830_VBLANK_PIPE_B 2 + +typedef struct { + int pipe; +} drmI830VBlankPipe; + +#define MMIO_READ 0 +#define MMIO_WRITE 1 + +#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 +#define MMIO_REGS_IA_VERTICES_COUNT 1 +#define MMIO_REGS_VS_INVOCATION_COUNT 2 +#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 +#define MMIO_REGS_GS_INVOCATION_COUNT 4 +#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 +#define MMIO_REGS_CL_INVOCATION_COUNT 6 +#define MMIO_REGS_PS_INVOCATION_COUNT 7 +#define MMIO_REGS_PS_DEPTH_COUNT 8 + +typedef struct { + unsigned int read_write:1; + unsigned int reg:31; + void __user *data; +} drmI830MMIO; + +#endif /* _I830_DRM_H_ */ diff --git a/src/gallium/winsys/drm/intel/dri/server/i830_dri.h b/src/gallium/winsys/drm/intel/dri/server/i830_dri.h new file mode 100644 index 0000000000..0d514b6c38 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/server/i830_dri.h @@ -0,0 +1,62 @@ + +#ifndef _I830_DRI_H +#define _I830_DRI_H + +#include "xf86drm.h" +#include "i830_common.h" + +#define I830_MAX_DRAWABLES 256 + +#define I830_MAJOR_VERSION 1 +#define I830_MINOR_VERSION 7 +#define I830_PATCHLEVEL 2 + +#define I830_REG_SIZE 0x80000 + +typedef struct _I830DRIRec { + drm_handle_t regs; + drmSize regsSize; + + drmSize unused1; /* backbufferSize */ + drm_handle_t unused2; /* backbuffer */ + + drmSize unused3; /* depthbufferSize */ + drm_handle_t unused4; /* depthbuffer */ + + drmSize unused5; /* rotatedSize */ + drm_handle_t unused6; /* rotatedbuffer */ + + drm_handle_t unused7; /* textures */ + int unused8; /* textureSize */ + + drm_handle_t unused9; /* agp_buffers */ + drmSize unused10; /* agp_buf_size */ + + int deviceID; + int width; + int height; + int mem; + int cpp; + int bitsPerPixel; + + int unused11[8]; /* was front/back/depth/rotated offset/pitch */ + + int unused12; /* logTextureGranularity */ + int unused13; /* textureOffset */ + + int irq; + int sarea_priv_offset; +} I830DRIRec, *I830DRIPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830ConfigPrivRec, *I830ConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830DRIContextRec, *I830DRIContextPtr; + + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile new file mode 100644 index 0000000000..f0b5a44389 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/Makefile @@ -0,0 +1,28 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +LIBNAME = EGL_i915.so + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ + ../common/libinteldrm.a + +DRIVER_SOURCES = \ + intel_swapbuffers.c \ + intel_context.c \ + intel_device.c \ + intel_egl.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +DRIVER_DEFINES = -I../common $(shell pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") + +include ../../Makefile.template + +symlinks: diff --git a/src/gallium/winsys/drm/intel/egl/SConscript b/src/gallium/winsys/drm/intel/egl/SConscript new file mode 100644 index 0000000000..0ad19d42a8 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/SConscript @@ -0,0 +1,39 @@ +Import('*') + +env = drienv.Clone() + +env.Append(CPPPATH = [ + '../intel', + 'server' +]) + +#MINIGLX_SOURCES = server/intel_dri.c + +DRIVER_SOURCES = [ + 'intel_winsys_pipe.c', + 'intel_winsys_softpipe.c', + 'intel_winsys_i915.c', + 'intel_batchbuffer.c', + 'intel_swapbuffers.c', + 'intel_context.c', + 'intel_lock.c', + 'intel_screen.c', + 'intel_batchpool.c', +] + +sources = \ + COMMON_GALLIUM_SOURCES + \ + COMMON_BM_SOURCES + \ + DRIVER_SOURCES + +drivers = [ + softpipe, + i915simple +] + +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions +env.SharedLibrary( + target ='i915tex_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], +) \ No newline at end of file diff --git a/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h b/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h new file mode 100644 index 0000000000..3e95326168 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h @@ -0,0 +1,24 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "intel_be_batchbuffer.h" + +/* + * Need to redefine the BATCH defines + */ + +#undef BEGIN_BATCH +#define BEGIN_BATCH(dwords, relocs) \ + (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) + +#undef OUT_BATCH +#define OUT_BATCH(d) \ + i915_batchbuffer_dword(&intel->base.batch->base, d) + +#undef OUT_RELOC +#define OUT_RELOC(buf,flags,mask,delta) do { \ + assert((delta) >= 0); \ + intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ +} while (0) + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_context.c b/src/gallium/winsys/drm/intel/egl/intel_context.c new file mode 100644 index 0000000000..927addb834 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_context.c @@ -0,0 +1,242 @@ +/************************************************************************** + * + * 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 "i915simple/i915_screen.h" + +#include "intel_device.h" +#include "intel_context.h" +#include "intel_batchbuffer.h" + +#include "state_tracker/st_public.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "intel_egl.h" +#include "utils.h" + +#ifdef DEBUG +int __intel_debug = 0; +#endif + + +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_NV_vertex_program +#include "extension_helper.h" + + +/** + * Extension strings exported by the intel driver. + * + * \note + * It appears that ARB_texture_env_crossbar has "disappeared" compared to the + * old i830-specific driver. + */ +const struct dri_extension card_extensions[] = { + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, + {"GL_SGIS_generate_mipmap", NULL }, + {NULL, NULL} +}; + + +/* + * Hardware lock functions. + * Doesn't do anything in EGL + */ + +static void +intel_lock_hardware(struct intel_be_context *context) +{ + (void)context; +} + +static void +intel_unlock_hardware(struct intel_be_context *context) +{ + (void)context; +} + +static boolean +intel_locked_hardware(struct intel_be_context *context) +{ + (void)context; + return FALSE; +} + + +/* + * Misc functions. + */ + +int +intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) +{ + struct intel_context *intel = CALLOC_STRUCT(intel_context); + struct intel_device *device = (struct intel_device *)egl_context->device->priv; + struct pipe_context *pipe; + struct st_context *st_share = NULL; + + egl_context->priv = intel; + + intel->intel_device = device; + intel->egl_context = egl_context; + intel->egl_device = egl_context->device; + + intel->base.hardware_lock = intel_lock_hardware; + intel->base.hardware_unlock = intel_unlock_hardware; + intel->base.hardware_locked = intel_locked_hardware; + + intel_be_init_context(&intel->base, &device->base); + +#if 0 + pipe = intel_create_softpipe(intel, screen->winsys); +#else + pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base); +#endif + + pipe->priv = intel; + + intel->st = st_create_context(pipe, visual, st_share); + + device->dummy = intel; + + return TRUE; +} + +int +intel_destroy_context(struct egl_drm_context *egl_context) +{ + struct intel_context *intel = egl_context->priv; + + if (intel->intel_device->dummy == intel) + intel->intel_device->dummy = NULL; + + st_destroy_context(intel->st); + intel_be_destroy_context(&intel->base); + free(intel); + return TRUE; +} + +void +intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read) +{ + if (context) { + struct intel_context *intel = (struct intel_context *)context->priv; + struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; + struct intel_framebuffer *read_fb = (struct intel_framebuffer *)read->priv; + + assert(draw_fb->stfb); + assert(read_fb->stfb); + + st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); + + intel->egl_drawable = draw; + + st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); + + if (draw != read) + st_resize_framebuffer(read_fb->stfb, read->w, read->h); + + } else { + st_make_current(NULL, NULL, NULL); + } +} + +void +intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) +{ + struct intel_device *device = (struct intel_device *)draw->device->priv; + struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; + + if (draw_fb->front_buffer) + driBOUnReference(draw_fb->front_buffer); + + draw_fb->front_buffer = NULL; + draw_fb->front = NULL; + + /* to unbind just call this function with front == NULL */ + if (!front) + return; + + draw_fb->front = front; + + driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); + driBOSetReferenced(draw_fb->front_buffer, front->handle); + + st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); +} diff --git a/src/gallium/winsys/drm/intel/egl/intel_context.h b/src/gallium/winsys/drm/intel/egl/intel_context.h new file mode 100644 index 0000000000..477fdec7f7 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_context.h @@ -0,0 +1,118 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef INTEL_CONTEXT_H +#define INTEL_CONTEXT_H + +#include "pipe/p_debug.h" +#include "intel_be_context.h" + + +struct st_context; +struct egl_drm_device; +struct egl_drm_context; +struct egl_drm_frontbuffer; + + +/** + * Intel rendering context, contains a state tracker and intel-specific info. + */ +struct intel_context +{ + struct intel_be_context base; + + struct st_context *st; + + struct intel_device *intel_device; + + /* new egl stuff */ + struct egl_drm_device *egl_device; + struct egl_drm_context *egl_context; + struct egl_drm_drawable *egl_drawable; +}; + + + +/** + * Intel framebuffer. + */ +struct intel_framebuffer +{ + struct st_framebuffer *stfb; + + struct intel_device *device; + struct _DriBufferObject *front_buffer; + struct egl_drm_frontbuffer *front; +}; + + + + +/* These are functions now: + */ +void LOCK_HARDWARE( struct intel_context *intel ); +void UNLOCK_HARDWARE( struct intel_context *intel ); + +extern char *__progname; + + + +/* ================================================================ + * Debugging: + */ +#ifdef DEBUG +extern int __intel_debug; + +#define DEBUG_SWAP 0x1 +#define DEBUG_LOCK 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BATCH 0x8 + +#define DBG(flag, ...) do { \ + if (__intel_debug & (DEBUG_##flag)) \ + printf(__VA_ARGS__); \ +} while(0) + +#else +#define DBG(flag, ...) +#endif + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_Q33_G 0x29D2 + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_device.c b/src/gallium/winsys/drm/intel/egl/intel_device.c new file mode 100644 index 0000000000..b9649cbec7 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_device.c @@ -0,0 +1,137 @@ +/************************************************************************** + * + * 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 "utils.h" + +#include "state_tracker/st_public.h" +#include "i915simple/i915_screen.h" + +#include "intel_context.h" +#include "intel_device.h" +#include "intel_batchbuffer.h" +#include "intel_egl.h" + + +extern const struct dri_extension card_extensions[]; + + +int +intel_create_device(struct egl_drm_device *device) +{ + struct intel_device *intel_device; + + /* Allocate the private area */ + intel_device = CALLOC_STRUCT(intel_device); + if (!intel_device) + return FALSE; + + device->priv = (void *)intel_device; + intel_device->device = device; + + intel_device->deviceID = device->deviceID; + + intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID); + + intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID); + + /* hack */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + + return TRUE; +} + +int +intel_destroy_device(struct egl_drm_device *device) +{ + struct intel_device *intel_device = (struct intel_device *)device->priv; + + intel_be_destroy_device(&intel_device->base); + + free(intel_device); + device->priv = NULL; + + return TRUE; +} + +int +intel_create_drawable(struct egl_drm_drawable *drawable, + const __GLcontextModes * visual) +{ + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + + if (!intelfb) + return GL_FALSE; + + intelfb->device = drawable->device->priv; + + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + drawable->w, + drawable->h, + (void*) intelfb); + + if (!intelfb->stfb) { + free(intelfb); + return GL_FALSE; + } + + drawable->priv = (void *) intelfb; + return GL_TRUE; +} + +int +intel_destroy_drawable(struct egl_drm_drawable *drawable) +{ + struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; + drawable->priv = NULL; + + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); + return TRUE; +} diff --git a/src/gallium/winsys/drm/intel/egl/intel_device.h b/src/gallium/winsys/drm/intel/egl/intel_device.h new file mode 100644 index 0000000000..323a7c2aef --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_device.h @@ -0,0 +1,50 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef _INTEL_SCREEN_H_ +#define _INTEL_SCREEN_H_ + +#include "intel_be_device.h" + +#include "pipe/p_compiler.h" + +struct pipe_screen; +struct egl_drm_device; +struct intel_context; + +struct intel_device +{ + struct intel_be_device base; + struct pipe_screen *pipe; + + int deviceID; + struct egl_drm_device *device; + + struct intel_context *dummy; +}; + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_egl.c b/src/gallium/winsys/drm/intel/egl/intel_egl.c new file mode 100644 index 0000000000..b89c5c508a --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_egl.c @@ -0,0 +1,796 @@ + +#include +#include +#include +#include +#include + +#include "eglconfig.h" +#include "eglcontext.h" +#include "egldisplay.h" +#include "egldriver.h" +#include "eglglobals.h" +#include "eglmode.h" +#include "eglscreen.h" +#include "eglsurface.h" +#include "egllog.h" + +#include "intel_egl.h" + +#include "xf86drm.h" +#include "xf86drmMode.h" + +#include "intel_context.h" + +#include "state_tracker/st_public.h" + +#define MAX_SCREENS 16 + +static void +drm_get_device_id(struct egl_drm_device *device) +{ + char path[512]; + FILE *file; + + /* TODO get the real minor */ + int minor = 0; + + snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor); + file = fopen(path, "r"); + if (!file) { + _eglLog(_EGL_WARNING, "Could not retrive device ID\n"); + return; + } + + fgets(path, sizeof( path ), file); + sscanf(path, "%x", &device->deviceID); + fclose(file); +} + +static struct egl_drm_device* +egl_drm_create_device(int drmFD) +{ + struct egl_drm_device *device = malloc(sizeof(*device)); + memset(device, 0, sizeof(*device)); + device->drmFD = drmFD; + + device->version = drmGetVersion(device->drmFD); + + drm_get_device_id(device); + + if (!intel_create_device(device)) { + free(device); + return NULL; + } + + return device; +} + +static void +_egl_context_modes_destroy(__GLcontextModes *modes) +{ + _eglLog(_EGL_DEBUG, "%s", __FUNCTION__); + + while (modes) { + __GLcontextModes * const next = modes->next; + free(modes); + modes = next; + } +} +/** + * Create a linked list of 'count' GLcontextModes. + * These are used during the client/server visual negotiation phase, + * then discarded. + */ +static __GLcontextModes * +_egl_context_modes_create(unsigned count, size_t minimum_size) +{ + /* This code copied from libGLX, and modified */ + const size_t size = (minimum_size > sizeof(__GLcontextModes)) + ? minimum_size : sizeof(__GLcontextModes); + __GLcontextModes * head = NULL; + __GLcontextModes ** next; + unsigned i; + + _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size); + + next = & head; + for (i = 0 ; i < count ; i++) { + *next = (__GLcontextModes *) calloc(1, size); + if (*next == NULL) { + _egl_context_modes_destroy(head); + head = NULL; + break; + } + + (*next)->doubleBufferMode = 1; + (*next)->visualID = GLX_DONT_CARE; + (*next)->visualType = GLX_DONT_CARE; + (*next)->visualRating = GLX_NONE; + (*next)->transparentPixel = GLX_NONE; + (*next)->transparentRed = GLX_DONT_CARE; + (*next)->transparentGreen = GLX_DONT_CARE; + (*next)->transparentBlue = GLX_DONT_CARE; + (*next)->transparentAlpha = GLX_DONT_CARE; + (*next)->transparentIndex = GLX_DONT_CARE; + (*next)->xRenderable = GLX_DONT_CARE; + (*next)->fbconfigID = GLX_DONT_CARE; + (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; + (*next)->bindToTextureRgb = GLX_DONT_CARE; + (*next)->bindToTextureRgba = GLX_DONT_CARE; + (*next)->bindToMipmapTexture = GLX_DONT_CARE; + (*next)->bindToTextureTargets = 0; + (*next)->yInverted = GLX_DONT_CARE; + + next = & ((*next)->next); + } + + return head; +} + +struct drm_screen; + +struct drm_driver +{ + _EGLDriver base; /* base class/object */ + + drmModeResPtr res; + + struct drm_screen *screens[MAX_SCREENS]; + size_t count_screens; + + struct egl_drm_device *device; +}; + +struct drm_surface +{ + _EGLSurface base; /* base class/object */ + + struct egl_drm_drawable *drawable; +}; + +struct drm_context +{ + _EGLContext base; /* base class/object */ + + struct egl_drm_context *context; +}; + +struct drm_screen +{ + _EGLScreen base; + + /* currently only support one connector */ + drmModeConnectorPtr connector; + + /* Has this screen been shown */ + int shown; + + /* Surface that is currently attached to this screen */ + struct drm_surface *surf; + + /* backing buffer */ + drmBO buffer; + + /* framebuffer */ + drmModeFBPtr fb; + uint32_t fbID; + + /* crtc and mode used */ + drmModeCrtcPtr crtc; + uint32_t crtcID; + + struct drm_mode_modeinfo *mode; + + /* geometry of the screen */ + struct egl_drm_frontbuffer front; +}; + +static void +drm_update_res(struct drm_driver *drm_drv) +{ + drmModeFreeResources(drm_drv->res); + drm_drv->res = drmModeGetResources(drm_drv->device->drmFD); +} + +static void +drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) +{ + struct drm_mode_modeinfo *m; + int i; + + for (i = 0; i < connector->count_modes; i++) { + m = &connector->modes[i]; + _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name); + } +} + + +static EGLBoolean +drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) +{ + _EGLDisplay *disp = _eglLookupDisplay(dpy); + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_screen *screen = NULL; + drmModeConnectorPtr connector = NULL; + drmModeResPtr res = NULL; + unsigned count_connectors = 0; + int num_screens = 0; + + EGLint i; + int fd; + + fd = drmOpen("i915", NULL); + if (fd < 0) { + return EGL_FALSE; + } + + drm_drv->device = egl_drm_create_device(fd); + if (!drm_drv->device) { + drmClose(fd); + return EGL_FALSE; + } + + drm_update_res(drm_drv); + res = drm_drv->res; + if (res) + count_connectors = res->count_connectors; + + for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { + connector = drmModeGetConnector(fd, res->connectors[i]); + + if (!connector) + continue; + + if (connector->connection != DRM_MODE_CONNECTED) { + drmModeFreeConnector(connector); + continue; + } + + screen = malloc(sizeof(struct drm_screen)); + memset(screen, 0, sizeof(*screen)); + screen->connector = connector; + _eglInitScreen(&screen->base); + _eglAddScreen(disp, &screen->base); + drm_add_modes_from_connector(&screen->base, connector); + drm_drv->screens[num_screens++] = screen; + } + drm_drv->count_screens = num_screens; + + /* for now we only have one config */ + _EGLConfig *config = calloc(1, sizeof(*config)); + memset(config, 1, sizeof(*config)); + _eglInitConfig(config, 1); + _eglSetConfigAttrib(config, EGL_RED_SIZE, 8); + _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); + _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); + _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); + _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); + _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24); + _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); + _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); + _eglAddConfig(disp, config); + + drv->Initialized = EGL_TRUE; + + *major = 1; + *minor = 4; + + return EGL_TRUE; +} + +static void +drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + unsigned int i; + + intel_bind_frontbuffer(screen->surf->drawable, NULL); + screen->surf = NULL; + + for (i = 0; i < drm_drv->res->count_crtcs; i++) { + drmModeSetCrtc( + drm_drv->device->drmFD, + drm_drv->res->crtcs[i], + 0, // FD + 0, 0, + NULL, 0, // List of output ids + NULL); + } + + drmModeRmFB(drm_drv->device->drmFD, screen->fbID); + drmModeFreeFB(screen->fb); + screen->fb = NULL; + + drmBOUnreference(drm_drv->device->drmFD, &screen->buffer); + + screen->shown = 0; +} + +static EGLBoolean +drm_terminate(_EGLDriver *drv, EGLDisplay dpy) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_screen *screen; + int i = 0; + + intel_destroy_device(drm_drv->device); + drmFreeVersion(drm_drv->device->version); + + for (i = 0; i < drm_drv->count_screens; i++) { + screen = drm_drv->screens[i]; + + if (screen->shown) + drm_takedown_shown_screen(drv, screen); + + drmModeFreeConnector(screen->connector); + _eglDestroyScreen(&screen->base); + drm_drv->screens[i] = NULL; + } + + drmClose(drm_drv->device->drmFD); + + free(drm_drv->device); + + _eglCleanupDisplay(_eglLookupDisplay(dpy)); + free(drm_drv); + + return EGL_TRUE; +} + + +static struct drm_context * +lookup_drm_context(EGLContext context) +{ + _EGLContext *c = _eglLookupContext(context); + return (struct drm_context *) c; +} + + +static struct drm_surface * +lookup_drm_surface(EGLSurface surface) +{ + _EGLSurface *s = _eglLookupSurface(surface); + return (struct drm_surface *) s; +} + +static struct drm_screen * +lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen) +{ + _EGLScreen *s = _eglLookupScreen(dpy, screen); + return (struct drm_screen *) s; +} + +static __GLcontextModes* +visual_from_config(_EGLConfig *conf) +{ + __GLcontextModes *visual; + (void)conf; + + visual = _egl_context_modes_create(1, sizeof(*visual)); + visual->redBits = 8; + visual->greenBits = 8; + visual->blueBits = 8; + visual->alphaBits = 8; + + visual->rgbBits = 32; + visual->doubleBufferMode = 1; + + visual->depthBits = 24; + visual->haveDepthBuffer = visual->depthBits > 0; + visual->stencilBits = 8; + visual->haveStencilBuffer = visual->stencilBits > 0; + + return visual; +} + + + +static EGLContext +drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_context *c; + struct drm_egl_context *share = NULL; + _EGLConfig *conf; + int i; + int ret; + __GLcontextModes *visual; + struct egl_drm_context *context; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreateContext"); + return EGL_NO_CONTEXT; + } + + for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { + switch (attrib_list[i]) { + /* no attribs defined for now */ + default: + _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); + return EGL_NO_CONTEXT; + } + } + + c = (struct drm_context *) calloc(1, sizeof(struct drm_context)); + if (!c) + return EGL_NO_CONTEXT; + + _eglInitContext(drv, dpy, &c->base, config, attrib_list); + + context = malloc(sizeof(*context)); + memset(context, 0, sizeof(*context)); + + if (!context) + goto err_c; + + context->device = drm_drv->device; + visual = visual_from_config(conf); + + ret = intel_create_context(context, visual, share); + free(visual); + + if (!ret) + goto err_gl; + + c->context = context; + + /* generate handle and insert into hash table */ + _eglSaveContext(&c->base); + assert(_eglGetContextHandle(&c->base)); + + return _eglGetContextHandle(&c->base); +err_gl: + free(context); +err_c: + free(c); + return EGL_NO_CONTEXT; +} + +static EGLBoolean +drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) +{ + struct drm_context *fc = lookup_drm_context(context); + _eglRemoveContext(&fc->base); + if (fc->base.IsBound) { + fc->base.DeletePending = EGL_TRUE; + } else { + intel_destroy_context(fc->context); + free(fc->context); + free(fc); + } + return EGL_TRUE; +} + + +static EGLSurface +drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) +{ + return EGL_NO_SURFACE; +} + + +static EGLSurface +drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) +{ + return EGL_NO_SURFACE; +} + + +static EGLSurface +drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + const EGLint *attrib_list) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + int i; + int ret; + int width = -1; + int height = -1; + struct drm_surface *surf = NULL; + struct egl_drm_drawable *drawable = NULL; + __GLcontextModes *visual; + _EGLConfig *conf; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface"); + return EGL_NO_CONTEXT; + } + + for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { + switch (attrib_list[i]) { + case EGL_WIDTH: + width = attrib_list[++i]; + break; + case EGL_HEIGHT: + height = attrib_list[++i]; + break; + default: + _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); + return EGL_NO_SURFACE; + } + } + + if (width < 1 || height < 1) { + _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); + return EGL_NO_SURFACE; + } + + surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface)); + if (!surf) + goto err; + + if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list)) + goto err_surf; + + drawable = malloc(sizeof(*drawable)); + memset(drawable, 0, sizeof(*drawable)); + + drawable->w = width; + drawable->h = height; + + visual = visual_from_config(conf); + + drawable->device = drm_drv->device; + ret = intel_create_drawable(drawable, visual); + free(visual); + + if (!ret) + goto err_draw; + + surf->drawable = drawable; + + _eglSaveSurface(&surf->base); + return surf->base.Handle; + +err_draw: + free(drawable); +err_surf: + free(surf); +err: + return EGL_NO_SURFACE; +} + +static EGLSurface +drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, + const EGLint *attrib_list) +{ + EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list); + + return surf; +} + +static struct drm_mode_modeinfo * +drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) +{ + int i; + struct drm_mode_modeinfo *m; + + for (i = 0; i < connector->count_modes; i++) { + m = &connector->modes[i]; + if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) + break; + m = NULL; + } + + return m; +} +static void +draw(size_t x, size_t y, size_t w, size_t h, size_t pitch, size_t v, unsigned int *ptr) +{ + int i, j; + + for (i = x; i < x + w; i++) + for(j = y; j < y + h; j++) + ptr[(i * pitch / 4) + j] = v; + +} + +static void +prettyColors(int fd, unsigned int handle, size_t pitch) +{ + drmBO bo; + unsigned int *ptr; + void *p; + int i; + + drmBOReference(fd, handle, &bo); + drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &p); + ptr = (unsigned int*)p; + + for (i = 0; i < (bo.size / 4); i++) + ptr[i] = 0xFFFFFFFF; + + for (i = 0; i < 4; i++) + draw(i * 40, i * 40, 40, 40, pitch, 0, ptr); + + + draw(200, 100, 40, 40, pitch, 0xff00ff, ptr); + draw(100, 200, 40, 40, pitch, 0xff00ff, ptr); + + drmBOUnmap(fd, &bo); +} + +static EGLBoolean +drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, + EGLScreenMESA screen, + EGLSurface surface, EGLModeMESA m) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_surface *surf = lookup_drm_surface(surface); + struct drm_screen *scrn = lookup_drm_screen(dpy, screen); + _EGLMode *mode = _eglLookupMode(dpy, m); + size_t pitch = mode->Width * 4; + size_t size = mode->Height * pitch; + int ret; + unsigned int i,j,k; + + if (scrn->shown) + drm_takedown_shown_screen(drv, scrn); + + ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_NO_EVICT, + DRM_BO_HINT_DONT_FENCE, &scrn->buffer); + + if (ret) + return EGL_FALSE; + + prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); + + ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height, + 32, 32, pitch, + scrn->buffer.handle, + &scrn->fbID); + + if (ret) + goto err_bo; + + scrn->fb = drmModeGetFB(drm_drv->device->drmFD, scrn->fbID); + if (!scrn->fb) + goto err_bo; + + scrn->mode = drm_find_mode(scrn->connector, mode); + if (!scrn->mode) + goto err_fb; + + for (j = 0; j < drm_drv->res->count_connectors; j++) { + drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]); + for (k = 0; k < con->count_encoders; k++) { + drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]); + for (i = 0; i < drm_drv->res->count_crtcs; i++) { + if (enc->possible_crtcs & (1<device->drmFD, + drm_drv->res->crtcs[i], + scrn->fbID, + 0, 0, + &drm_drv->res->connectors[j], 1, + scrn->mode); + /* skip the other crtcs now */ + i = drm_drv->res->count_crtcs; + } + } + } + } + + scrn->front.handle = scrn->buffer.handle; + scrn->front.pitch = pitch; + scrn->front.width = mode->Width; + scrn->front.height = mode->Height; + + scrn->surf = surf; + intel_bind_frontbuffer(surf->drawable, &scrn->front); + + scrn->shown = 1; + + return EGL_TRUE; + +err_fb: + /* TODO remove fb */ + +err_bo: + drmBOUnreference(drm_drv->device->drmFD, &scrn->buffer); + return EGL_FALSE; +} + +static EGLBoolean +drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +{ + struct drm_surface *fs = lookup_drm_surface(surface); + _eglRemoveSurface(&fs->base); + if (fs->base.IsBound) { + fs->base.DeletePending = EGL_TRUE; + } else { + intel_bind_frontbuffer(fs->drawable, NULL); + intel_destroy_drawable(fs->drawable); + free(fs->drawable); + free(fs); + } + return EGL_TRUE; +} + + +static EGLBoolean +drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) +{ + struct drm_surface *readSurf = lookup_drm_surface(read); + struct drm_surface *drawSurf = lookup_drm_surface(draw); + struct drm_context *ctx = lookup_drm_context(context); + EGLBoolean b; + + b = _eglMakeCurrent(drv, dpy, draw, read, context); + if (!b) + return EGL_FALSE; + + if (ctx) { + if (!drawSurf || !readSurf) + return EGL_FALSE; + + intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); + } else { + intel_make_current(NULL, NULL, NULL); + } + + return EGL_TRUE; +} + +static EGLBoolean +drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) +{ + struct drm_surface *surf = lookup_drm_surface(draw); + if (!surf) + return EGL_FALSE; + + /* error checking */ + if (!_eglSwapBuffers(drv, dpy, draw)) + return EGL_FALSE; + + intel_swap_buffers(surf->drawable); + return EGL_TRUE; +} + + +/** + * The bootstrap function. Return a new drm_driver object and + * plug in API functions. + */ +_EGLDriver * +_eglMain(_EGLDisplay *dpy, const char *args) +{ + struct drm_driver *drm; + + drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); + if (!drm) { + return NULL; + } + + /* First fill in the dispatch table with defaults */ + _eglInitDriverFallbacks(&drm->base); + /* then plug in our Drm-specific functions */ + drm->base.API.Initialize = drm_initialize; + drm->base.API.Terminate = drm_terminate; + drm->base.API.CreateContext = drm_create_context; + drm->base.API.MakeCurrent = drm_make_current; + drm->base.API.CreateWindowSurface = drm_create_window_surface; + drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface; + drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface; + drm->base.API.DestroySurface = drm_destroy_surface; + drm->base.API.DestroyContext = drm_destroy_context; + drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa; + drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; + drm->base.API.SwapBuffers = drm_swap_buffers; + + drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; + drm->base.Name = "DRM/Gallium"; + + /* enable supported extensions */ + drm->base.Extensions.MESA_screen_surface = EGL_TRUE; + drm->base.Extensions.MESA_copy_context = EGL_TRUE; + + return &drm->base; +} diff --git a/src/gallium/winsys/drm/intel/egl/intel_egl.h b/src/gallium/winsys/drm/intel/egl/intel_egl.h new file mode 100644 index 0000000000..1ee27e0847 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_egl.h @@ -0,0 +1,53 @@ + +#ifndef _INTEL_EGL_H_ +#define _INTEL_EGL_H_ + +#include + +struct egl_drm_device +{ + void *priv; + int drmFD; + + drmVersionPtr version; + int deviceID; +}; + +struct egl_drm_context +{ + void *priv; + struct egl_drm_device *device; +}; + +struct egl_drm_drawable +{ + void *priv; + struct egl_drm_device *device; + size_t h; + size_t w; +}; + +struct egl_drm_frontbuffer +{ + uint32_t handle; + uint32_t pitch; + uint32_t width; + uint32_t height; +}; + +#include "GL/internal/glcore.h" + +int intel_create_device(struct egl_drm_device *device); +int intel_destroy_device(struct egl_drm_device *device); + +int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate); +int intel_destroy_context(struct egl_drm_context *context); + +int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual); +int intel_destroy_drawable(struct egl_drm_drawable *drawable); + +void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read); +void intel_swap_buffers(struct egl_drm_drawable *draw); +void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front); + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_reg.h b/src/gallium/winsys/drm/intel/egl/intel_reg.h new file mode 100644 index 0000000000..4f33bee438 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_reg.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + + +#ifndef _INTEL_REG_H_ +#define _INTEL_REG_H_ + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) + +#define MI_BATCH_BUFFER_END (0xA<<23) + + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c b/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c new file mode 100644 index 0000000000..2edcbc79ff --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c @@ -0,0 +1,111 @@ +/************************************************************************** + * + * 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 "intel_device.h" +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_reg.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 "intel_egl.h" + + +static void +intel_display_surface(struct egl_drm_drawable *draw, + struct pipe_surface *surf); + +void intel_swap_buffers(struct egl_drm_drawable *draw) +{ + struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, ST_SURFACE_BACK_LEFT); + if (back_surf) { + st_notify_swapbuffers(intel_fb->stfb); + if (intel_fb->front) + intel_display_surface(draw, back_surf); + st_notify_swapbuffers_complete(intel_fb->stfb); + } +} + +static void +intel_display_surface(struct egl_drm_drawable *draw, + struct pipe_surface *surf) +{ + struct intel_context *intel = NULL; + struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; + struct _DriFenceObject *fence; + + //const int srcWidth = surf->width; + //const int srcHeight = surf->height; + + intel = intel_fb->device->dummy; + if (!intel) { + printf("No dummy context\n"); + return; + } + + const int dstWidth = intel_fb->front->width; + const int dstHeight = intel_fb->front->height; + const int dstPitch = intel_fb->front->pitch / 4;//draw->front.cpp; + + const int cpp = 4;//intel_fb->front->cpp; + const int srcPitch = surf->stride / cpp; + + int BR13, CMD; + //int i; + + BR13 = (dstPitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + + BEGIN_BATCH(8, 2); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((0 << 16) | 0); + OUT_BATCH((dstHeight << 16) | dstWidth); + + OUT_RELOC(intel_fb->front_buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + + OUT_BATCH((0 << 16) | 0); + OUT_BATCH((srcPitch * cpp) & 0xffff); + OUT_RELOC(dri_bo(surf->buffer), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + fence = intel_be_batchbuffer_flush(intel->base.batch); + driFenceUnReference(&fence); + intel_be_batchbuffer_finish(intel->base.batch); +} diff --git a/src/gallium/winsys/egl_drm/Makefile b/src/gallium/winsys/egl_drm/Makefile deleted file mode 100644 index 4139d9e71f..0000000000 --- a/src/gallium/winsys/egl_drm/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# src/mesa/drivers/egl_drm/Makefile - -TOP = ../../../.. - -include $(TOP)/configs/current - - - -default: $(TOP)/$(LIB_DIR) subdirs - - -$(TOP)/$(LIB_DIR): - -mkdir $(TOP)/$(LIB_DIR) - - -subdirs: - @for dir in $(DRI_DIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE)) || exit 1 ; \ - fi \ - done - - -install: - @for dir in $(DRI_DIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE) install) || exit 1 ; \ - fi \ - done - - -clean: - @for dir in $(DRI_DIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE) clean) ; \ - fi \ - done - -rm -f common/*.o diff --git a/src/gallium/winsys/egl_drm/Makefile.template b/src/gallium/winsys/egl_drm/Makefile.template deleted file mode 100644 index 07abfa53f3..0000000000 --- a/src/gallium/winsys/egl_drm/Makefile.template +++ /dev/null @@ -1,117 +0,0 @@ -# -*-makefile-*- - -MESA_MODULES = \ - $(TOP)/src/mesa/libmesa.a \ - $(GALLIUM_AUXILIARIES) - -COMMON_GALLIUM_SOURCES = \ - $(TOP)/src/mesa/drivers/dri/common/utils.c \ - $(TOP)/src/mesa/drivers/dri/common/vblank.c \ - $(TOP)/src/mesa/drivers/dri/common/dri_util.c \ - $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c - -COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ - $(TOP)/src/mesa/drivers/common/driverfuncs.c \ - $(TOP)/src/mesa/drivers/dri/common/texmem.c \ - $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c - -COMMON_BM_SOURCES = \ - $(TOP)/src/mesa/drivers/dri/common/dri_bufmgr.c \ - $(TOP)/src/mesa/drivers/dri/common/dri_drmpool.c - - -ifeq ($(WINDOW_SYSTEM),dri) -WINOBJ= -WINLIB= -INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) - -OBJECTS = \ - $(C_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) - -else -# miniglx -WINOBJ= -WINLIB=-L$(MESA)/src/glx/mini -MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini -INCLUDES = $(MINIGLX_INCLUDES) \ - $(SHARED_INCLUDES) \ - $(PCIACCESS_CFLAGS) - -OBJECTS = $(C_SOURCES:.c=.o) \ - $(MINIGLX_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) -endif - - -### Include directories -SHARED_INCLUDES = \ - -I. \ - -I$(TOP)/src/mesa/drivers/dri/common \ - -Iserver \ - -I$(TOP)/include \ - -I$(TOP)/include/GL/internal \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/gallium/winsys/common \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/main \ - -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/mesa/math \ - -I$(TOP)/src/mesa/transform \ - -I$(TOP)/src/mesa/shader \ - -I$(TOP)/src/mesa/swrast \ - -I$(TOP)/src/mesa/swrast_setup \ - -I$(TOP)/src/egl/main \ - -I$(TOP)/src/egl/drivers/dri \ - $(LIBDRM_CFLAGS) - - -##### RULES ##### - -.c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - - -##### TARGETS ##### - -default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) - - -$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template - $(TOP)/bin/mklib -noprefix -o $@ \ - $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) - - -$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) - $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) - - -depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \ - $(ASM_SOURCES) 2> /dev/null - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` `find ../include` - - -# Remove .o and backup files -clean: - -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) - -rm -f depend depend.bak - - -install: $(LIBNAME) - $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) - $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) - - -include depend diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile deleted file mode 100644 index e67b49f3ad..0000000000 --- a/src/gallium/winsys/egl_drm/intel/Makefile +++ /dev/null @@ -1,29 +0,0 @@ - -TOP = ../../../../.. -include $(TOP)/configs/current - -LIBNAME = EGL_i915.so - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ - $(TOP)/src/gallium/winsys/common/intel_drm/libinteldrm.a - -DRIVER_SOURCES = \ - intel_swapbuffers.c \ - intel_context.c \ - intel_device.c \ - intel_egl.c - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - -DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ - && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") - -include ../Makefile.template - -symlinks: diff --git a/src/gallium/winsys/egl_drm/intel/SConscript b/src/gallium/winsys/egl_drm/intel/SConscript deleted file mode 100644 index 0ad19d42a8..0000000000 --- a/src/gallium/winsys/egl_drm/intel/SConscript +++ /dev/null @@ -1,39 +0,0 @@ -Import('*') - -env = drienv.Clone() - -env.Append(CPPPATH = [ - '../intel', - 'server' -]) - -#MINIGLX_SOURCES = server/intel_dri.c - -DRIVER_SOURCES = [ - 'intel_winsys_pipe.c', - 'intel_winsys_softpipe.c', - 'intel_winsys_i915.c', - 'intel_batchbuffer.c', - 'intel_swapbuffers.c', - 'intel_context.c', - 'intel_lock.c', - 'intel_screen.c', - 'intel_batchpool.c', -] - -sources = \ - COMMON_GALLIUM_SOURCES + \ - COMMON_BM_SOURCES + \ - DRIVER_SOURCES - -drivers = [ - softpipe, - i915simple -] - -# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -env.SharedLibrary( - target ='i915tex_dri.so', - source = sources, - LIBS = drivers + mesa + auxiliaries + env['LIBS'], -) \ No newline at end of file diff --git a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h deleted file mode 100644 index 1fa2719845..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef INTEL_BATCHBUFFER_H -#define INTEL_BATCHBUFFER_H - -#include "intel_drm/intel_be_batchbuffer.h" - -/* - * Need to redefine the BATCH defines - */ - -#undef BEGIN_BATCH -#define BEGIN_BATCH(dwords, relocs) \ - (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) - -#undef OUT_BATCH -#define OUT_BATCH(d) \ - i915_batchbuffer_dword(&intel->base.batch->base, d) - -#undef OUT_RELOC -#define OUT_RELOC(buf,flags,mask,delta) do { \ - assert((delta) >= 0); \ - intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ -} while (0) - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c deleted file mode 100644 index 927addb834..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ /dev/null @@ -1,242 +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 "i915simple/i915_screen.h" - -#include "intel_device.h" -#include "intel_context.h" -#include "intel_batchbuffer.h" - -#include "state_tracker/st_public.h" -#include "pipe/p_defines.h" -#include "pipe/p_context.h" -#include "intel_egl.h" -#include "utils.h" - -#ifdef DEBUG -int __intel_debug = 0; -#endif - - -#define need_GL_ARB_multisample -#define need_GL_ARB_point_parameters -#define need_GL_ARB_texture_compression -#define need_GL_ARB_vertex_buffer_object -#define need_GL_ARB_vertex_program -#define need_GL_ARB_window_pos -#define need_GL_EXT_blend_color -#define need_GL_EXT_blend_equation_separate -#define need_GL_EXT_blend_func_separate -#define need_GL_EXT_blend_minmax -#define need_GL_EXT_cull_vertex -#define need_GL_EXT_fog_coord -#define need_GL_EXT_framebuffer_object -#define need_GL_EXT_multi_draw_arrays -#define need_GL_EXT_secondary_color -#define need_GL_NV_vertex_program -#include "extension_helper.h" - - -/** - * Extension strings exported by the intel driver. - * - * \note - * It appears that ARB_texture_env_crossbar has "disappeared" compared to the - * old i830-specific driver. - */ -const struct dri_extension card_extensions[] = { - {"GL_ARB_multisample", GL_ARB_multisample_functions}, - {"GL_ARB_multitexture", NULL}, - {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, - {"GL_ARB_texture_border_clamp", NULL}, - {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, - {"GL_ARB_texture_cube_map", NULL}, - {"GL_ARB_texture_env_add", NULL}, - {"GL_ARB_texture_env_combine", NULL}, - {"GL_ARB_texture_env_dot3", NULL}, - {"GL_ARB_texture_mirrored_repeat", NULL}, - {"GL_ARB_texture_rectangle", NULL}, - {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, - {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, - {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, - {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, - {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, - {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, - {"GL_EXT_blend_subtract", NULL}, - {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, - {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, - {"GL_EXT_packed_depth_stencil", NULL}, - {"GL_EXT_pixel_buffer_object", NULL}, - {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, - {"GL_EXT_stencil_wrap", NULL}, - {"GL_EXT_texture_edge_clamp", NULL}, - {"GL_EXT_texture_env_combine", NULL}, - {"GL_EXT_texture_env_dot3", NULL}, - {"GL_EXT_texture_filter_anisotropic", NULL}, - {"GL_EXT_texture_lod_bias", NULL}, - {"GL_3DFX_texture_compression_FXT1", NULL}, - {"GL_APPLE_client_storage", NULL}, - {"GL_MESA_pack_invert", NULL}, - {"GL_MESA_ycbcr_texture", NULL}, - {"GL_NV_blend_square", NULL}, - {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, - {"GL_NV_vertex_program1_1", NULL}, - {"GL_SGIS_generate_mipmap", NULL }, - {NULL, NULL} -}; - - -/* - * Hardware lock functions. - * Doesn't do anything in EGL - */ - -static void -intel_lock_hardware(struct intel_be_context *context) -{ - (void)context; -} - -static void -intel_unlock_hardware(struct intel_be_context *context) -{ - (void)context; -} - -static boolean -intel_locked_hardware(struct intel_be_context *context) -{ - (void)context; - return FALSE; -} - - -/* - * Misc functions. - */ - -int -intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) -{ - struct intel_context *intel = CALLOC_STRUCT(intel_context); - struct intel_device *device = (struct intel_device *)egl_context->device->priv; - struct pipe_context *pipe; - struct st_context *st_share = NULL; - - egl_context->priv = intel; - - intel->intel_device = device; - intel->egl_context = egl_context; - intel->egl_device = egl_context->device; - - intel->base.hardware_lock = intel_lock_hardware; - intel->base.hardware_unlock = intel_unlock_hardware; - intel->base.hardware_locked = intel_locked_hardware; - - intel_be_init_context(&intel->base, &device->base); - -#if 0 - pipe = intel_create_softpipe(intel, screen->winsys); -#else - pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base); -#endif - - pipe->priv = intel; - - intel->st = st_create_context(pipe, visual, st_share); - - device->dummy = intel; - - return TRUE; -} - -int -intel_destroy_context(struct egl_drm_context *egl_context) -{ - struct intel_context *intel = egl_context->priv; - - if (intel->intel_device->dummy == intel) - intel->intel_device->dummy = NULL; - - st_destroy_context(intel->st); - intel_be_destroy_context(&intel->base); - free(intel); - return TRUE; -} - -void -intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read) -{ - if (context) { - struct intel_context *intel = (struct intel_context *)context->priv; - struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; - struct intel_framebuffer *read_fb = (struct intel_framebuffer *)read->priv; - - assert(draw_fb->stfb); - assert(read_fb->stfb); - - st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); - - intel->egl_drawable = draw; - - st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); - - if (draw != read) - st_resize_framebuffer(read_fb->stfb, read->w, read->h); - - } else { - st_make_current(NULL, NULL, NULL); - } -} - -void -intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) -{ - struct intel_device *device = (struct intel_device *)draw->device->priv; - struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; - - if (draw_fb->front_buffer) - driBOUnReference(draw_fb->front_buffer); - - draw_fb->front_buffer = NULL; - draw_fb->front = NULL; - - /* to unbind just call this function with front == NULL */ - if (!front) - return; - - draw_fb->front = front; - - driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); - driBOSetReferenced(draw_fb->front_buffer, front->handle); - - st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); -} diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h deleted file mode 100644 index dfa4720b08..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_context.h +++ /dev/null @@ -1,118 +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. - * - **************************************************************************/ - -#ifndef INTEL_CONTEXT_H -#define INTEL_CONTEXT_H - -#include "pipe/p_debug.h" -#include "intel_drm/intel_be_context.h" - - -struct st_context; -struct egl_drm_device; -struct egl_drm_context; -struct egl_drm_frontbuffer; - - -/** - * Intel rendering context, contains a state tracker and intel-specific info. - */ -struct intel_context -{ - struct intel_be_context base; - - struct st_context *st; - - struct intel_device *intel_device; - - /* new egl stuff */ - struct egl_drm_device *egl_device; - struct egl_drm_context *egl_context; - struct egl_drm_drawable *egl_drawable; -}; - - - -/** - * Intel framebuffer. - */ -struct intel_framebuffer -{ - struct st_framebuffer *stfb; - - struct intel_device *device; - struct _DriBufferObject *front_buffer; - struct egl_drm_frontbuffer *front; -}; - - - - -/* These are functions now: - */ -void LOCK_HARDWARE( struct intel_context *intel ); -void UNLOCK_HARDWARE( struct intel_context *intel ); - -extern char *__progname; - - - -/* ================================================================ - * Debugging: - */ -#ifdef DEBUG -extern int __intel_debug; - -#define DEBUG_SWAP 0x1 -#define DEBUG_LOCK 0x2 -#define DEBUG_IOCTL 0x4 -#define DEBUG_BATCH 0x8 - -#define DBG(flag, ...) do { \ - if (__intel_debug & (DEBUG_##flag)) \ - printf(__VA_ARGS__); \ -} while(0) - -#else -#define DBG(flag, ...) -#endif - - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GME 0x27AE -#define PCI_CHIP_G33_G 0x29C2 -#define PCI_CHIP_Q35_G 0x29B2 -#define PCI_CHIP_Q33_G 0x29D2 - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_device.c b/src/gallium/winsys/egl_drm/intel/intel_device.c deleted file mode 100644 index b9649cbec7..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_device.c +++ /dev/null @@ -1,137 +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 "utils.h" - -#include "state_tracker/st_public.h" -#include "i915simple/i915_screen.h" - -#include "intel_context.h" -#include "intel_device.h" -#include "intel_batchbuffer.h" -#include "intel_egl.h" - - -extern const struct dri_extension card_extensions[]; - - -int -intel_create_device(struct egl_drm_device *device) -{ - struct intel_device *intel_device; - - /* Allocate the private area */ - intel_device = CALLOC_STRUCT(intel_device); - if (!intel_device) - return FALSE; - - device->priv = (void *)intel_device; - intel_device->device = device; - - intel_device->deviceID = device->deviceID; - - intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID); - - intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID); - - /* hack */ - driInitExtensions(NULL, card_extensions, GL_FALSE); - - return TRUE; -} - -int -intel_destroy_device(struct egl_drm_device *device) -{ - struct intel_device *intel_device = (struct intel_device *)device->priv; - - intel_be_destroy_device(&intel_device->base); - - free(intel_device); - device->priv = NULL; - - return TRUE; -} - -int -intel_create_drawable(struct egl_drm_drawable *drawable, - const __GLcontextModes * visual) -{ - enum pipe_format colorFormat, depthFormat, stencilFormat; - struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); - - if (!intelfb) - return GL_FALSE; - - intelfb->device = drawable->device->priv; - - if (visual->redBits == 5) - colorFormat = PIPE_FORMAT_R5G6B5_UNORM; - else - colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; - - if (visual->depthBits == 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (visual->depthBits == 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_NONE; - - if (visual->stencilBits == 8) - stencilFormat = PIPE_FORMAT_S8Z24_UNORM; - else - stencilFormat = PIPE_FORMAT_NONE; - - intelfb->stfb = st_create_framebuffer(visual, - colorFormat, - depthFormat, - stencilFormat, - drawable->w, - drawable->h, - (void*) intelfb); - - if (!intelfb->stfb) { - free(intelfb); - return GL_FALSE; - } - - drawable->priv = (void *) intelfb; - return GL_TRUE; -} - -int -intel_destroy_drawable(struct egl_drm_drawable *drawable) -{ - struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; - drawable->priv = NULL; - - assert(intelfb->stfb); - st_unreference_framebuffer(&intelfb->stfb); - free(intelfb); - return TRUE; -} diff --git a/src/gallium/winsys/egl_drm/intel/intel_device.h b/src/gallium/winsys/egl_drm/intel/intel_device.h deleted file mode 100644 index 2f9d4f887e..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_device.h +++ /dev/null @@ -1,50 +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. - * - **************************************************************************/ - -#ifndef _INTEL_SCREEN_H_ -#define _INTEL_SCREEN_H_ - -#include "intel_drm/intel_be_device.h" - -#include "pipe/p_compiler.h" - -struct pipe_screen; -struct egl_drm_device; -struct intel_context; - -struct intel_device -{ - struct intel_be_device base; - struct pipe_screen *pipe; - - int deviceID; - struct egl_drm_device *device; - - struct intel_context *dummy; -}; - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c deleted file mode 100644 index 1851babaf6..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ /dev/null @@ -1,796 +0,0 @@ - -#include -#include -#include -#include -#include - -#include "eglconfig.h" -#include "eglcontext.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "eglmode.h" -#include "eglscreen.h" -#include "eglsurface.h" -#include "egllog.h" - -#include "intel_egl.h" - -#include "xf86drm.h" -#include "xf86drmMode.h" - -#include "intel_context.h" - -#include "state_tracker/st_public.h" - -#define MAX_SCREENS 16 - -static void -drm_get_device_id(struct egl_drm_device *device) -{ - char path[512]; - FILE *file; - - /* TODO get the real minor */ - int minor = 0; - - snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor); - file = fopen(path, "r"); - if (!file) { - _eglLog(_EGL_WARNING, "Could not retrive device ID\n"); - return; - } - - fgets(path, sizeof( path ), file); - sscanf(path, "%x", &device->deviceID); - fclose(file); -} - -static struct egl_drm_device* -egl_drm_create_device(int drmFD) -{ - struct egl_drm_device *device = malloc(sizeof(*device)); - memset(device, 0, sizeof(*device)); - device->drmFD = drmFD; - - device->version = drmGetVersion(device->drmFD); - - drm_get_device_id(device); - - if (!intel_create_device(device)) { - free(device); - return NULL; - } - - return device; -} - -static void -_egl_context_modes_destroy(__GLcontextModes *modes) -{ - _eglLog(_EGL_DEBUG, "%s", __FUNCTION__); - - while (modes) { - __GLcontextModes * const next = modes->next; - free(modes); - modes = next; - } -} -/** - * Create a linked list of 'count' GLcontextModes. - * These are used during the client/server visual negotiation phase, - * then discarded. - */ -static __GLcontextModes * -_egl_context_modes_create(unsigned count, size_t minimum_size) -{ - /* This code copied from libGLX, and modified */ - const size_t size = (minimum_size > sizeof(__GLcontextModes)) - ? minimum_size : sizeof(__GLcontextModes); - __GLcontextModes * head = NULL; - __GLcontextModes ** next; - unsigned i; - - _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size); - - next = & head; - for (i = 0 ; i < count ; i++) { - *next = (__GLcontextModes *) calloc(1, size); - if (*next == NULL) { - _egl_context_modes_destroy(head); - head = NULL; - break; - } - - (*next)->doubleBufferMode = 1; - (*next)->visualID = GLX_DONT_CARE; - (*next)->visualType = GLX_DONT_CARE; - (*next)->visualRating = GLX_NONE; - (*next)->transparentPixel = GLX_NONE; - (*next)->transparentRed = GLX_DONT_CARE; - (*next)->transparentGreen = GLX_DONT_CARE; - (*next)->transparentBlue = GLX_DONT_CARE; - (*next)->transparentAlpha = GLX_DONT_CARE; - (*next)->transparentIndex = GLX_DONT_CARE; - (*next)->xRenderable = GLX_DONT_CARE; - (*next)->fbconfigID = GLX_DONT_CARE; - (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; - (*next)->bindToTextureRgb = GLX_DONT_CARE; - (*next)->bindToTextureRgba = GLX_DONT_CARE; - (*next)->bindToMipmapTexture = GLX_DONT_CARE; - (*next)->bindToTextureTargets = 0; - (*next)->yInverted = GLX_DONT_CARE; - - next = & ((*next)->next); - } - - return head; -} - -struct drm_screen; - -struct drm_driver -{ - _EGLDriver base; /* base class/object */ - - drmModeResPtr res; - - struct drm_screen *screens[MAX_SCREENS]; - size_t count_screens; - - struct egl_drm_device *device; -}; - -struct drm_surface -{ - _EGLSurface base; /* base class/object */ - - struct egl_drm_drawable *drawable; -}; - -struct drm_context -{ - _EGLContext base; /* base class/object */ - - struct egl_drm_context *context; -}; - -struct drm_screen -{ - _EGLScreen base; - - /* currently only support one connector */ - drmModeConnectorPtr connector; - - /* Has this screen been shown */ - int shown; - - /* Surface that is currently attached to this screen */ - struct drm_surface *surf; - - /* backing buffer */ - drmBO buffer; - - /* framebuffer */ - drmModeFBPtr fb; - uint32_t fbID; - - /* crtc and mode used */ - drmModeCrtcPtr crtc; - uint32_t crtcID; - - struct drm_mode_modeinfo *mode; - - /* geometry of the screen */ - struct egl_drm_frontbuffer front; -}; - -static void -drm_update_res(struct drm_driver *drm_drv) -{ - drmModeFreeResources(drm_drv->res); - drm_drv->res = drmModeGetResources(drm_drv->device->drmFD); -} - -static void -drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) -{ - struct drm_mode_modeinfo *m; - int i; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name); - } -} - - -static EGLBoolean -drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) -{ - _EGLDisplay *disp = _eglLookupDisplay(dpy); - struct drm_driver *drm_drv = (struct drm_driver *)drv; - struct drm_screen *screen = NULL; - drmModeConnectorPtr connector = NULL; - drmModeResPtr res = NULL; - unsigned count_connectors = 0; - int num_screens = 0; - - EGLint i; - int fd; - - fd = drmOpen("i915", NULL); - if (fd < 0) { - return EGL_FALSE; - } - - drm_drv->device = egl_drm_create_device(fd); - if (!drm_drv->device) { - drmClose(fd); - return EGL_FALSE; - } - - drm_update_res(drm_drv); - res = drm_drv->res; - if (res) - count_connectors = res->count_connectors; - - for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { - connector = drmModeGetConnector(fd, res->connectors[i]); - - if (!connector) - continue; - - if (connector->connection != DRM_MODE_CONNECTED) { - drmModeFreeConnector(connector); - continue; - } - - screen = malloc(sizeof(struct drm_screen)); - memset(screen, 0, sizeof(*screen)); - screen->connector = connector; - _eglInitScreen(&screen->base); - _eglAddScreen(disp, &screen->base); - drm_add_modes_from_connector(&screen->base, connector); - drm_drv->screens[num_screens++] = screen; - } - drm_drv->count_screens = num_screens; - - /* for now we only have one config */ - _EGLConfig *config = calloc(1, sizeof(*config)); - memset(config, 1, sizeof(*config)); - _eglInitConfig(config, 1); - _eglSetConfigAttrib(config, EGL_RED_SIZE, 8); - _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); - _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); - _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24); - _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); - _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); - _eglAddConfig(disp, config); - - drv->Initialized = EGL_TRUE; - - *major = 1; - *minor = 4; - - return EGL_TRUE; -} - -static void -drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - unsigned int i; - - intel_bind_frontbuffer(screen->surf->drawable, NULL); - screen->surf = NULL; - - for (i = 0; i < drm_drv->res->count_crtcs; i++) { - drmModeSetCrtc( - drm_drv->device->drmFD, - drm_drv->res->crtcs[i], - 0, // FD - 0, 0, - NULL, 0, // List of output ids - NULL); - } - - drmModeRmFB(drm_drv->device->drmFD, screen->fbID); - drmModeFreeFB(screen->fb); - screen->fb = NULL; - - drmBOUnreference(drm_drv->device->drmFD, &screen->buffer); - - screen->shown = 0; -} - -static EGLBoolean -drm_terminate(_EGLDriver *drv, EGLDisplay dpy) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - struct drm_screen *screen; - int i = 0; - - intel_destroy_device(drm_drv->device); - drmFreeVersion(drm_drv->device->version); - - for (i = 0; i < drm_drv->count_screens; i++) { - screen = drm_drv->screens[i]; - - if (screen->shown) - drm_takedown_shown_screen(drv, screen); - - drmModeFreeConnector(screen->connector); - _eglDestroyScreen(&screen->base); - drm_drv->screens[i] = NULL; - } - - drmClose(drm_drv->device->drmFD); - - free(drm_drv->device); - - _eglCleanupDisplay(_eglLookupDisplay(dpy)); - free(drm_drv); - - return EGL_TRUE; -} - - -static struct drm_context * -lookup_drm_context(EGLContext context) -{ - _EGLContext *c = _eglLookupContext(context); - return (struct drm_context *) c; -} - - -static struct drm_surface * -lookup_drm_surface(EGLSurface surface) -{ - _EGLSurface *s = _eglLookupSurface(surface); - return (struct drm_surface *) s; -} - -static struct drm_screen * -lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen) -{ - _EGLScreen *s = _eglLookupScreen(dpy, screen); - return (struct drm_screen *) s; -} - -static __GLcontextModes* -visual_from_config(_EGLConfig *conf) -{ - __GLcontextModes *visual; - (void)conf; - - visual = _gl_context_modes_create(1, sizeof(*visual)); - visual->redBits = 8; - visual->greenBits = 8; - visual->blueBits = 8; - visual->alphaBits = 8; - - visual->rgbBits = 32; - visual->doubleBufferMode = 1; - - visual->depthBits = 24; - visual->haveDepthBuffer = visual->depthBits > 0; - visual->stencilBits = 8; - visual->haveStencilBuffer = visual->stencilBits > 0; - - return visual; -} - - - -static EGLContext -drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - struct drm_context *c; - struct drm_egl_context *share = NULL; - _EGLConfig *conf; - int i; - int ret; - __GLcontextModes *visual; - struct egl_drm_context *context; - - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs defined for now */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - } - - c = (struct drm_context *) calloc(1, sizeof(struct drm_context)); - if (!c) - return EGL_NO_CONTEXT; - - _eglInitContext(drv, dpy, &c->base, config, attrib_list); - - context = malloc(sizeof(*context)); - memset(context, 0, sizeof(*context)); - - if (!context) - goto err_c; - - context->device = drm_drv->device; - visual = visual_from_config(conf); - - ret = intel_create_context(context, visual, share); - free(visual); - - if (!ret) - goto err_gl; - - c->context = context; - - /* generate handle and insert into hash table */ - _eglSaveContext(&c->base); - assert(_eglGetContextHandle(&c->base)); - - return _eglGetContextHandle(&c->base); -err_gl: - free(context); -err_c: - free(c); - return EGL_NO_CONTEXT; -} - -static EGLBoolean -drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) -{ - struct drm_context *fc = lookup_drm_context(context); - _eglRemoveContext(&fc->base); - if (fc->base.IsBound) { - fc->base.DeletePending = EGL_TRUE; - } else { - intel_destroy_context(fc->context); - free(fc->context); - free(fc); - } - return EGL_TRUE; -} - - -static EGLSurface -drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) -{ - return EGL_NO_SURFACE; -} - - -static EGLSurface -drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) -{ - return EGL_NO_SURFACE; -} - - -static EGLSurface -drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, - const EGLint *attrib_list) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - int i; - int ret; - int width = -1; - int height = -1; - struct drm_surface *surf = NULL; - struct egl_drm_drawable *drawable = NULL; - __GLcontextModes *visual; - _EGLConfig *conf; - - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface"); - return EGL_NO_CONTEXT; - } - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - case EGL_WIDTH: - width = attrib_list[++i]; - break; - case EGL_HEIGHT: - height = attrib_list[++i]; - break; - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); - return EGL_NO_SURFACE; - } - } - - if (width < 1 || height < 1) { - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); - return EGL_NO_SURFACE; - } - - surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface)); - if (!surf) - goto err; - - if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list)) - goto err_surf; - - drawable = malloc(sizeof(*drawable)); - memset(drawable, 0, sizeof(*drawable)); - - drawable->w = width; - drawable->h = height; - - visual = visual_from_config(conf); - - drawable->device = drm_drv->device; - ret = intel_create_drawable(drawable, visual); - free(visual); - - if (!ret) - goto err_draw; - - surf->drawable = drawable; - - _eglSaveSurface(&surf->base); - return surf->base.Handle; - -err_draw: - free(drawable); -err_surf: - free(surf); -err: - return EGL_NO_SURFACE; -} - -static EGLSurface -drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, - const EGLint *attrib_list) -{ - EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list); - - return surf; -} - -static struct drm_mode_modeinfo * -drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) -{ - int i; - struct drm_mode_modeinfo *m; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) - break; - m = NULL; - } - - return m; -} -static void -draw(size_t x, size_t y, size_t w, size_t h, size_t pitch, size_t v, unsigned int *ptr) -{ - int i, j; - - for (i = x; i < x + w; i++) - for(j = y; j < y + h; j++) - ptr[(i * pitch / 4) + j] = v; - -} - -static void -prettyColors(int fd, unsigned int handle, size_t pitch) -{ - drmBO bo; - unsigned int *ptr; - void *p; - int i; - - drmBOReference(fd, handle, &bo); - drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &p); - ptr = (unsigned int*)p; - - for (i = 0; i < (bo.size / 4); i++) - ptr[i] = 0xFFFFFFFF; - - for (i = 0; i < 4; i++) - draw(i * 40, i * 40, 40, 40, pitch, 0, ptr); - - - draw(200, 100, 40, 40, pitch, 0xff00ff, ptr); - draw(100, 200, 40, 40, pitch, 0xff00ff, ptr); - - drmBOUnmap(fd, &bo); -} - -static EGLBoolean -drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, - EGLScreenMESA screen, - EGLSurface surface, EGLModeMESA m) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - struct drm_surface *surf = lookup_drm_surface(surface); - struct drm_screen *scrn = lookup_drm_screen(dpy, screen); - _EGLMode *mode = _eglLookupMode(dpy, m); - size_t pitch = mode->Width * 4; - size_t size = mode->Height * pitch; - int ret; - unsigned int i,j,k; - - if (scrn->shown) - drm_takedown_shown_screen(drv, scrn); - - ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_NO_EVICT, - DRM_BO_HINT_DONT_FENCE, &scrn->buffer); - - if (ret) - return EGL_FALSE; - - prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); - - ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height, - 32, 32, pitch, - scrn->buffer.handle, - &scrn->fbID); - - if (ret) - goto err_bo; - - scrn->fb = drmModeGetFB(drm_drv->device->drmFD, scrn->fbID); - if (!scrn->fb) - goto err_bo; - - scrn->mode = drm_find_mode(scrn->connector, mode); - if (!scrn->mode) - goto err_fb; - - for (j = 0; j < drm_drv->res->count_connectors; j++) { - drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]); - for (k = 0; k < con->count_encoders; k++) { - drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]); - for (i = 0; i < drm_drv->res->count_crtcs; i++) { - if (enc->possible_crtcs & (1<device->drmFD, - drm_drv->res->crtcs[i], - scrn->fbID, - 0, 0, - &drm_drv->res->connectors[j], 1, - scrn->mode); - /* skip the other crtcs now */ - i = drm_drv->res->count_crtcs; - } - } - } - } - - scrn->front.handle = scrn->buffer.handle; - scrn->front.pitch = pitch; - scrn->front.width = mode->Width; - scrn->front.height = mode->Height; - - scrn->surf = surf; - intel_bind_frontbuffer(surf->drawable, &scrn->front); - - scrn->shown = 1; - - return EGL_TRUE; - -err_fb: - /* TODO remove fb */ - -err_bo: - drmBOUnreference(drm_drv->device->drmFD, &scrn->buffer); - return EGL_FALSE; -} - -static EGLBoolean -drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) -{ - struct drm_surface *fs = lookup_drm_surface(surface); - _eglRemoveSurface(&fs->base); - if (fs->base.IsBound) { - fs->base.DeletePending = EGL_TRUE; - } else { - intel_bind_frontbuffer(fs->drawable, NULL); - intel_destroy_drawable(fs->drawable); - free(fs->drawable); - free(fs); - } - return EGL_TRUE; -} - - -static EGLBoolean -drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) -{ - struct drm_surface *readSurf = lookup_drm_surface(read); - struct drm_surface *drawSurf = lookup_drm_surface(draw); - struct drm_context *ctx = lookup_drm_context(context); - EGLBoolean b; - - b = _eglMakeCurrent(drv, dpy, draw, read, context); - if (!b) - return EGL_FALSE; - - if (ctx) { - if (!drawSurf || !readSurf) - return EGL_FALSE; - - intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); - } else { - intel_make_current(NULL, NULL, NULL); - } - - return EGL_TRUE; -} - -static EGLBoolean -drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) -{ - struct drm_surface *surf = lookup_drm_surface(draw); - if (!surf) - return EGL_FALSE; - - /* error checking */ - if (!_eglSwapBuffers(drv, dpy, draw)) - return EGL_FALSE; - - intel_swap_buffers(surf->drawable); - return EGL_TRUE; -} - - -/** - * The bootstrap function. Return a new drm_driver object and - * plug in API functions. - */ -_EGLDriver * -_eglMain(_EGLDisplay *dpy, const char *args) -{ - struct drm_driver *drm; - - drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); - if (!drm) { - return NULL; - } - - /* First fill in the dispatch table with defaults */ - _eglInitDriverFallbacks(&drm->base); - /* then plug in our Drm-specific functions */ - drm->base.API.Initialize = drm_initialize; - drm->base.API.Terminate = drm_terminate; - drm->base.API.CreateContext = drm_create_context; - drm->base.API.MakeCurrent = drm_make_current; - drm->base.API.CreateWindowSurface = drm_create_window_surface; - drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface; - drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface; - drm->base.API.DestroySurface = drm_destroy_surface; - drm->base.API.DestroyContext = drm_destroy_context; - drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa; - drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; - drm->base.API.SwapBuffers = drm_swap_buffers; - - drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; - drm->base.Name = "DRM/Gallium"; - - /* enable supported extensions */ - drm->base.Extensions.MESA_screen_surface = EGL_TRUE; - drm->base.Extensions.MESA_copy_context = EGL_TRUE; - - return &drm->base; -} diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h deleted file mode 100644 index 1ee27e0847..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.h +++ /dev/null @@ -1,53 +0,0 @@ - -#ifndef _INTEL_EGL_H_ -#define _INTEL_EGL_H_ - -#include - -struct egl_drm_device -{ - void *priv; - int drmFD; - - drmVersionPtr version; - int deviceID; -}; - -struct egl_drm_context -{ - void *priv; - struct egl_drm_device *device; -}; - -struct egl_drm_drawable -{ - void *priv; - struct egl_drm_device *device; - size_t h; - size_t w; -}; - -struct egl_drm_frontbuffer -{ - uint32_t handle; - uint32_t pitch; - uint32_t width; - uint32_t height; -}; - -#include "GL/internal/glcore.h" - -int intel_create_device(struct egl_drm_device *device); -int intel_destroy_device(struct egl_drm_device *device); - -int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate); -int intel_destroy_context(struct egl_drm_context *context); - -int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual); -int intel_destroy_drawable(struct egl_drm_drawable *drawable); - -void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read); -void intel_swap_buffers(struct egl_drm_drawable *draw); -void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front); - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_reg.h b/src/gallium/winsys/egl_drm/intel/intel_reg.h deleted file mode 100644 index 4f33bee438..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_reg.h +++ /dev/null @@ -1,53 +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. - * - **************************************************************************/ - - -#ifndef _INTEL_REG_H_ -#define _INTEL_REG_H_ - - -#define BR00_BITBLT_CLIENT 0x40000000 -#define BR00_OP_COLOR_BLT 0x10000000 -#define BR00_OP_SRC_COPY_BLT 0x10C00000 -#define BR13_SOLID_PATTERN 0x80000000 - -#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) -#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) -#define XY_COLOR_BLT_WRITE_RGB (1<<20) - -#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) -#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) -#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) - -#define MI_WAIT_FOR_EVENT ((0x3<<23)) -#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) -#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) - -#define MI_BATCH_BUFFER_END (0xA<<23) - - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c deleted file mode 100644 index 2edcbc79ff..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c +++ /dev/null @@ -1,111 +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 "intel_device.h" -#include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_reg.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 "intel_egl.h" - - -static void -intel_display_surface(struct egl_drm_drawable *draw, - struct pipe_surface *surf); - -void intel_swap_buffers(struct egl_drm_drawable *draw) -{ - struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; - struct pipe_surface *back_surf; - - assert(intel_fb); - assert(intel_fb->stfb); - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, ST_SURFACE_BACK_LEFT); - if (back_surf) { - st_notify_swapbuffers(intel_fb->stfb); - if (intel_fb->front) - intel_display_surface(draw, back_surf); - st_notify_swapbuffers_complete(intel_fb->stfb); - } -} - -static void -intel_display_surface(struct egl_drm_drawable *draw, - struct pipe_surface *surf) -{ - struct intel_context *intel = NULL; - struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; - struct _DriFenceObject *fence; - - //const int srcWidth = surf->width; - //const int srcHeight = surf->height; - - intel = intel_fb->device->dummy; - if (!intel) { - printf("No dummy context\n"); - return; - } - - const int dstWidth = intel_fb->front->width; - const int dstHeight = intel_fb->front->height; - const int dstPitch = intel_fb->front->pitch / 4;//draw->front.cpp; - - const int cpp = 4;//intel_fb->front->cpp; - const int srcPitch = surf->stride / cpp; - - int BR13, CMD; - //int i; - - BR13 = (dstPitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - - BEGIN_BATCH(8, 2); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((0 << 16) | 0); - OUT_BATCH((dstHeight << 16) | dstWidth); - - OUT_RELOC(intel_fb->front_buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); - - OUT_BATCH((0 << 16) | 0); - OUT_BATCH((srcPitch * cpp) & 0xffff); - OUT_RELOC(dri_bo(surf->buffer), - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - - fence = intel_be_batchbuffer_flush(intel->base.batch); - driFenceUnReference(&fence); - intel_be_batchbuffer_finish(intel->base.batch); -} diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c index 86b085ab84..ff52ceb8c4 100644 --- a/src/gallium/winsys/gdi/wmesa.c +++ b/src/gallium/winsys/gdi/wmesa.c @@ -118,48 +118,6 @@ static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC) } } - -/** - * Create DIB for back buffer. - * We write into this memory with the span routines and then blit it - * to the window on a buffer swap. - */ -BOOL wmCreateBackingStore(WMesaFramebuffer pwfb, long lxSize, long lySize) -{ - HDC hdc = pwfb->hDC; - BITMAPINFO bmi; - LPBITMAPINFO pbmi = &bmi; - HDC hic; - - pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pbmi->bmiHeader.biWidth = lxSize; - pbmi->bmiHeader.biHeight= -lySize; - pbmi->bmiHeader.biPlanes = 1; - pbmi->bmiHeader.biBitCount = pwfb->cColorBits; - pbmi->bmiHeader.biCompression = BI_RGB; - pbmi->bmiHeader.biSizeImage = 0; - pbmi->bmiHeader.biXPelsPerMeter = 0; - pbmi->bmiHeader.biYPelsPerMeter = 0; - pbmi->bmiHeader.biClrUsed = 0; - pbmi->bmiHeader.biClrImportant = 0; - - hic = CreateIC("display", NULL, NULL, NULL); - pwfb->dib_hDC = CreateCompatibleDC(hic); - - pwfb->hbmDIB = CreateDIBSection(hic, - pbmi, - DIB_RGB_COLORS, - (void **)&(pwfb->pbPixels), - 0, - 0); - pwfb->hOldBitmap = SelectObject(pwfb->dib_hDC, pwfb->hbmDIB); - - DeleteDC(hic); - - wmSetPixelFormat(pwfb, pwfb->hDC); - return TRUE; -} - /** * Create a new WMesaFramebuffer object which will correspond to the * given HDC (Window handle). @@ -201,10 +159,6 @@ wmesa_new_framebuffer(HDC hdc, GLvisual *visual, GLuint width, GLuint height) pwfb->cColorBits = GetDeviceCaps(hdc, BITSPIXEL); -#if 0 - wmCreateBackingStore(pwfb, width, height); -#endif - pwfb->hDC = hdc; /* insert at head of list */ pwfb->next = FirstFramebuffer; @@ -266,16 +220,6 @@ static WMesaContext wmesa_context(const GLcontext *ctx) return (WMesaContext) ctx; } -static wmDeleteBackingStore(WMesaFramebuffer pwfb) -{ - if (pwfb->hbmDIB) { - SelectObject(pwfb->dib_hDC, pwfb->hOldBitmap); - DeleteDC(pwfb->dib_hDC); - DeleteObject(pwfb->hbmDIB); - } -} - - /** * Find the width and height of the window named by hdc. */ @@ -383,11 +327,6 @@ wm_flush_frontbuffer(struct pipe_winsys *pws, struct wm_buffer *wm_buf; BITMAPINFO bmi, *pbmi; -#if 0 - if (pwfb) - BitBlt(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, - pwfb->dib_hDC, 0, 0, SRCCOPY); -#else wm_buf = wm_buffer(surf->buffer); pbmi = &bmi; @@ -405,7 +344,6 @@ wm_flush_frontbuffer(struct pipe_winsys *pws, pbmi->bmiHeader.biClrImportant = 0; StretchDIBits(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, wm_buf->data, pbmi, 0, SRCCOPY); -#endif } @@ -706,9 +644,6 @@ void WMesaDestroyContext( WMesaContext pwc ) /* clean up frame buffer resources */ pwfb = wmesa_lookup_framebuffer(pwc->hDC); if (pwfb) { -#if 0 - wmDeleteBackingStore(pwfb); -#endif wmesa_free_framebuffer(pwc->hDC); } @@ -779,10 +714,6 @@ void WMesaSwapBuffers( HDC hdc ) */ st_notify_swapbuffers(pwfb->stfb); -#if 0 - BitBlt(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, - pwfb->dib_hDC, 0, 0, SRCCOPY); -#else surf = st_get_framebuffer_surface(pwfb->stfb, ST_SURFACE_BACK_LEFT); wm_buf = wm_buffer(surf->buffer); @@ -809,7 +740,6 @@ void WMesaSwapBuffers( HDC hdc ) st_resize_framebuffer(pwfb->stfb, width, height); } -#endif } /* This is hopefully a temporary hack to define some needed dispatch -- cgit v1.2.3 From 9bbc55116f36a357ee75d2766b0adb039eaca806 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Sun, 17 Aug 2008 21:55:37 +0100 Subject: if we can't find a mode, return first. At least we should see the top left portion if we've got larger screens on other CRTC's --- src/gallium/winsys/drm/intel/egl/intel_egl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/egl/intel_egl.c b/src/gallium/winsys/drm/intel/egl/intel_egl.c index b89c5c508a..3204ed3131 100644 --- a/src/gallium/winsys/drm/intel/egl/intel_egl.c +++ b/src/gallium/winsys/drm/intel/egl/intel_egl.c @@ -571,7 +571,7 @@ drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) m = &connector->modes[i]; if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) break; - m = NULL; + m = &connector->modes[0]; /* if we can't find one, return first */ } return m; @@ -654,12 +654,12 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, if (!scrn->fb) goto err_bo; - scrn->mode = drm_find_mode(scrn->connector, mode); - if (!scrn->mode) - goto err_fb; - for (j = 0; j < drm_drv->res->count_connectors; j++) { drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]); + scrn->mode = drm_find_mode(con, mode); + if (!scrn->mode) + goto err_fb; + for (k = 0; k < con->count_encoders; k++) { drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]); for (i = 0; i < drm_drv->res->count_crtcs; i++) { -- cgit v1.2.3 From 7f100d04ddacf9f6517c9aff1e2de5257eb77fb0 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 18 Aug 2008 00:04:29 -0400 Subject: g3dvl: Use rotating buffers to avoid waiting for map(). --- src/gallium/winsys/g3dvl/nouveau/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 2861bd7db4..7fa29d2f5f 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -9,7 +9,7 @@ OBJECTS = nouveau_bo.o nouveau_fence.o nouveau_swapbuffers.o nouveau_channel.o nouveau_pushbuf.o nouveau_resource.o nouveau_screen.o nv04_surface.o \ nv50_surface.o #nouveau_winsys_softpipe.o -CFLAGS += -g -Wall -Werror -fPIC \ +CFLAGS += -g -Wall -fPIC \ -I${GALLIUMDIR}/include \ -I${GALLIUMDIR}/winsys/g3dvl \ -I${DRMDIR}/include \ -- cgit v1.2.3 From 6fdc057887bd5e1e5f5ae2781529df050b3a31c6 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 18 Aug 2008 14:40:02 +0200 Subject: scons: Fix build. --- src/gallium/winsys/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index ddab9efc86..30c3378dff 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -1,6 +1,6 @@ Import('*') -if env['drm']: +if env['dri']: SConscript([ 'drm/SConscript', ]) -- cgit v1.2.3 From f9e14e0daca3b2f3662a68413c2fa71c05375b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Aug 2008 00:18:19 +0100 Subject: xlib: Revert destroying pipe_screen (temporary). --- src/gallium/winsys/xlib/xm_api.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index d2f92a0875..7256340420 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -847,7 +847,10 @@ void XMesaDestroyContext( XMesaContext c ) { struct pipe_screen *screen = c->st->pipe->screen; st_destroy_context(c->st); + /* FIXME: We should destroy the screen here, but if we do so, surfaces may + * outlive it, causing segfaults screen->destroy(screen); + */ _mesa_free(c); } -- cgit v1.2.3 From 4f25420bdd834e81a3e22733304efc5261c2998a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 24 Aug 2008 17:48:55 -0600 Subject: gallium: refactor/replace p_util.h with util/u_memory.h and util/u_math.h Also, rename p_tile.[ch] to u_tile.[ch] --- src/gallium/winsys/drm/intel/common/intel_be_device.c | 2 +- src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c | 2 +- src/gallium/winsys/egl_xlib/egl_xlib.c | 2 +- src/gallium/winsys/egl_xlib/sw_winsys.c | 3 ++- src/gallium/winsys/gdi/wmesa.c | 2 +- src/gallium/winsys/xlib/brw_aub.c | 1 - src/gallium/winsys/xlib/xm_winsys.c | 3 ++- src/gallium/winsys/xlib/xm_winsys_aub.c | 2 +- 8 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/common/intel_be_device.c b/src/gallium/winsys/drm/intel/common/intel_be_device.c index 8db0329615..019ee5cbd2 100644 --- a/src/gallium/winsys/drm/intel/common/intel_be_device.c +++ b/src/gallium/winsys/drm/intel/common/intel_be_device.c @@ -13,8 +13,8 @@ #include "pipe/p_winsys.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "util/u_memory.h" #include "i915simple/i915_screen.h" diff --git a/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c b/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c index 0d98d16cf1..20920a2052 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c +++ b/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c @@ -32,8 +32,8 @@ #include "intel_context.h" #include "intel_winsys_softpipe.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_format.h" +#include "util/u_memory.h" #include "softpipe/sp_winsys.h" diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 829732eea8..e9f821d276 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -38,8 +38,8 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "pipe/p_winsys.h" +#include "util/u_memory.h" #include "softpipe/sp_winsys.h" #include "eglconfig.h" diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index f4199e6f89..ae81d7f801 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -37,8 +37,9 @@ #include "pipe/p_winsys.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "sw_winsys.h" diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c index ff52ceb8c4..730fb1b541 100644 --- a/src/gallium/winsys/gdi/wmesa.c +++ b/src/gallium/winsys/gdi/wmesa.c @@ -12,8 +12,8 @@ #include "pipe/p_winsys.h" #include "pipe/p_format.h" #include "pipe/p_context.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "util/u_memory.h" #include "softpipe/sp_winsys.h" #include "glapi/glapi.h" #include "colors.h" diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c index 6e814ce5d1..f319802962 100644 --- a/src/gallium/winsys/xlib/brw_aub.c +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -34,7 +34,6 @@ #include "brw_aub.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "pipe/p_debug.h" diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 4b4dc56e84..68ead7f528 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -42,8 +42,9 @@ #include "pipe/p_winsys.h" #include "pipe/p_format.h" #include "pipe/p_context.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "softpipe/sp_winsys.h" #ifdef GALLIUM_CELL diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index 7fc9debdd5..3439367636 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -37,7 +37,7 @@ #include "xmesaP.h" #include "pipe/p_winsys.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "i965simple/brw_winsys.h" #include "i965simple/brw_screen.h" -- cgit v1.2.3 From 6fd2feaad7029a2f6d02bcf7039cbe72f53c615c Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 24 Aug 2008 18:10:50 -0600 Subject: gallium: include u_memory.h, u_math.h --- src/gallium/winsys/xlib/brw_aub.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c index f319802962..9e96efaa53 100644 --- a/src/gallium/winsys/xlib/brw_aub.c +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -35,6 +35,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "pipe/p_debug.h" +#include "util/u_memory.h" struct brw_aubfile { -- cgit v1.2.3 From 85813e36f2646e00ac163fb6e6e78e1d2f73eb34 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 25 Aug 2008 08:32:50 -0600 Subject: gallium: include u_math.h --- src/gallium/winsys/xlib/xm_winsys_aub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index 3439367636..35c4ebc4ba 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -37,8 +37,9 @@ #include "xmesaP.h" #include "pipe/p_winsys.h" -#include "util/u_memory.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "i965simple/brw_winsys.h" #include "i965simple/brw_screen.h" #include "brw_aub.h" -- cgit v1.2.3 From 0bb852fa49e7f9a31036089ea4f5dfbd312a4a3a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 26 Aug 2008 16:35:12 -0600 Subject: gallium: thread wrapper clean-up In p_thread.h replace _glthread_* functions with new pipe_* functions. Remove other old cruft. --- .../winsys/drm/intel/common/ws_dri_bufmgr.c | 102 ++++++++++----------- .../winsys/drm/intel/common/ws_dri_bufpool.h | 8 +- .../winsys/drm/intel/common/ws_dri_drmpool.c | 4 +- .../winsys/drm/intel/common/ws_dri_fencemgr.c | 66 ++++++------- .../winsys/drm/intel/common/ws_dri_mallocpool.c | 6 +- .../winsys/drm/intel/common/ws_dri_slabpool.c | 66 ++++++------- src/gallium/winsys/drm/intel/dri/intel_lock.c | 8 +- src/gallium/winsys/xlib/glxapi.c | 26 +----- src/gallium/winsys/xlib/xm_api.c | 9 +- src/gallium/winsys/xlib/xmesaP.h | 3 +- 10 files changed, 140 insertions(+), 158 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c b/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c index b6d901f85e..499f7bef8f 100644 --- a/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c +++ b/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c @@ -33,7 +33,7 @@ #include #include #include -#include "glthread.h" +#include "pipe/p_thread.h" #include "errno.h" #include "ws_dri_bufmgr.h" #include "string.h" @@ -51,8 +51,8 @@ * driBufferObject mutex - > this rw lock. */ -_glthread_DECLARE_STATIC_MUTEX(bmMutex); -_glthread_DECLARE_STATIC_COND(bmCond); +pipe_static_mutex(bmMutex); +pipe_static_condvar(bmCond); static int kernelReaders = 0; static int num_buffers = 0; @@ -241,29 +241,29 @@ static int drmBOResetList(drmBOList *list) void driWriteLockKernelBO(void) { - _glthread_LOCK_MUTEX(bmMutex); + pipe_mutex_lock(bmMutex); while(kernelReaders != 0) - _glthread_COND_WAIT(bmCond, bmMutex); + pipe_condvar_wait(bmCond, bmMutex); } void driWriteUnlockKernelBO(void) { - _glthread_UNLOCK_MUTEX(bmMutex); + pipe_mutex_unlock(bmMutex); } void driReadLockKernelBO(void) { - _glthread_LOCK_MUTEX(bmMutex); + pipe_mutex_lock(bmMutex); kernelReaders++; - _glthread_UNLOCK_MUTEX(bmMutex); + pipe_mutex_unlock(bmMutex); } void driReadUnlockKernelBO(void) { - _glthread_LOCK_MUTEX(bmMutex); + pipe_mutex_lock(bmMutex); if (--kernelReaders == 0) - _glthread_COND_BROADCAST(bmCond); - _glthread_UNLOCK_MUTEX(bmMutex); + pipe_condvar_broadcast(bmCond); + pipe_mutex_unlock(bmMutex); } @@ -277,7 +277,7 @@ void driReadUnlockKernelBO(void) typedef struct _DriBufferObject { DriBufferPool *pool; - _glthread_Mutex mutex; + pipe_mutx mutex; int refCount; const char *name; uint64_t flags; @@ -318,12 +318,12 @@ driBOKernel(struct _DriBufferObject *buf) drmBO *ret; driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); assert(buf->private != NULL); ret = buf->pool->kernel(buf->pool, buf->private); if (!ret) BM_CKFATAL(-EINVAL); - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); driReadUnlockKernelBO(); return ret; @@ -338,9 +338,9 @@ driBOWaitIdle(struct _DriBufferObject *buf, int lazy) * that time?? */ - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); } void * @@ -353,11 +353,11 @@ driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) return buf->userData; } - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); assert(buf->private != NULL); retval = buf->pool->map(buf->pool, buf->private, flags, hint, &buf->mutex, &virtual); - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); return retval == 0 ? virtual : NULL; } @@ -369,9 +369,9 @@ driBOUnmap(struct _DriBufferObject *buf) return; assert(buf->private != NULL); - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); } unsigned long @@ -381,9 +381,9 @@ driBOOffset(struct _DriBufferObject *buf) assert(buf->private != NULL); - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); ret = buf->pool->offset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); return ret; } @@ -394,9 +394,9 @@ driBOPoolOffset(struct _DriBufferObject *buf) assert(buf->private != NULL); - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); ret = buf->pool->poolOffset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); return ret; } @@ -408,9 +408,9 @@ driBOFlags(struct _DriBufferObject *buf) assert(buf->private != NULL); driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); ret = buf->pool->flags(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); driReadUnlockKernelBO(); return ret; } @@ -418,12 +418,12 @@ driBOFlags(struct _DriBufferObject *buf) struct _DriBufferObject * driBOReference(struct _DriBufferObject *buf) { - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); if (++buf->refCount == 1) { - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); BM_CKFATAL(-EINVAL); } - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); return buf; } @@ -435,10 +435,10 @@ driBOUnReference(struct _DriBufferObject *buf) if (!buf) return; - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); tmp = --buf->refCount; if (!tmp) { - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); if (buf->private) { if (buf->createdByReference) buf->pool->unreference(buf->pool, buf->private); @@ -451,7 +451,7 @@ driBOUnReference(struct _DriBufferObject *buf) num_buffers--; free(buf); } else - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); } @@ -469,7 +469,7 @@ driBOData(struct _DriBufferObject *buf, assert(!buf->userBuffer); /* XXX just do a memcpy? */ - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); pool = buf->pool; if (pool == NULL && newPool != NULL) { @@ -556,7 +556,7 @@ driBOData(struct _DriBufferObject *buf, } out: - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); return retval; } @@ -569,7 +569,7 @@ driBOSubData(struct _DriBufferObject *buf, assert(!buf->userBuffer); /* XXX just do a memcpy? */ - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); if (size && data) { BM_CKFATAL(buf->pool->map(buf->pool, buf->private, DRM_BO_FLAG_WRITE, 0, &buf->mutex, @@ -577,7 +577,7 @@ driBOSubData(struct _DriBufferObject *buf, memcpy((unsigned char *) virtual + offset, data, size); BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); } - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); } void @@ -588,21 +588,21 @@ driBOGetSubData(struct _DriBufferObject *buf, assert(!buf->userBuffer); /* XXX just do a memcpy? */ - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); if (size && data) { BM_CKFATAL(buf->pool->map(buf->pool, buf->private, DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); memcpy(data, (unsigned char *) virtual + offset, size); BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); } - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); } void driBOSetReferenced(struct _DriBufferObject *buf, unsigned long handle) { - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); if (buf->private != NULL) { assert((size_t)"Invalid buffer for setReferenced\n" & 0); BM_CKFATAL(-EINVAL); @@ -619,7 +619,7 @@ driBOSetReferenced(struct _DriBufferObject *buf, } buf->createdByReference = TRUE; buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); } int @@ -644,8 +644,8 @@ driGenBuffers(struct _DriBufferPool *pool, if (!buf) return -ENOMEM; - _glthread_INIT_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_init(buf->mutex); + pipe_mutex_lock(buf->mutex); buf->refCount = 1; buf->flags = flags; buf->hint = hint; @@ -653,7 +653,7 @@ driGenBuffers(struct _DriBufferPool *pool, buf->alignment = alignment; buf->pool = pool; buf->createdByReference = 0; - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); buffers[i] = buf; } return 0; @@ -818,7 +818,7 @@ driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, { int newItem; - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); BM_CKFATAL(driAddValidateItem(&list->drmBuffers, buf->pool->kernel(buf->pool, buf->private), flags, mask, itemLoc, node)); @@ -827,7 +827,7 @@ driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, if (newItem) buf->refCount++; - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); } drmBOList *driGetdrmBOList(struct _DriBufferList *list) @@ -845,10 +845,10 @@ void driPutdrmBOList(struct _DriBufferList *list) void driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) { - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); if (buf->pool->fence) BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); } @@ -908,10 +908,10 @@ driBOValidateUserList(struct _DriBufferList * list) while (curBuf) { buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); if (buf->pool->validate) BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); curBuf = drmBOListNext(&list->driBuffers, curBuf); } } @@ -929,9 +929,9 @@ driBOSize(struct _DriBufferObject *buf) { unsigned long size; - _glthread_LOCK_MUTEX(buf->mutex); + pipe_mutex_lock(buf->mutex); size = buf->pool->size(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); + pipe_mutex_unlock(buf->mutex); return size; diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_bufpool.h b/src/gallium/winsys/drm/intel/common/ws_dri_bufpool.h index bf60798924..ad3b6f3931 100644 --- a/src/gallium/winsys/drm/intel/common/ws_dri_bufpool.h +++ b/src/gallium/winsys/drm/intel/common/ws_dri_bufpool.h @@ -33,14 +33,14 @@ #define _PSB_BUFPOOL_H_ #include -#include +#include "pipe/p_thread.h" struct _DriFenceObject; typedef struct _DriBufferPool { int fd; int (*map) (struct _DriBufferPool * pool, void *private, - unsigned flags, int hint, _glthread_Mutex *mutex, + unsigned flags, int hint, pipe_mutex *mutex, void **virtual); int (*unmap) (struct _DriBufferPool * pool, void *private); int (*destroy) (struct _DriBufferPool * pool, void *private); @@ -55,8 +55,8 @@ typedef struct _DriBufferPool int (*fence) (struct _DriBufferPool * pool, void *private, struct _DriFenceObject * fence); drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); - int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); - int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int (*validate) (struct _DriBufferPool * pool, void *private, pipe_mutex *mutex); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, pipe_mutex *mutex, int lazy); int (*setStatus) (struct _DriBufferPool *pool, void *private, uint64_t flag_diff, uint64_t old_flags); diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_drmpool.c b/src/gallium/winsys/drm/intel/common/ws_dri_drmpool.c index 40929efa2f..54618b1c82 100644 --- a/src/gallium/winsys/drm/intel/common/ws_dri_drmpool.c +++ b/src/gallium/winsys/drm/intel/common/ws_dri_drmpool.c @@ -113,7 +113,7 @@ pool_unreference(struct _DriBufferPool *pool, void *private) static int pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) + int hint, pipe_mutex *mutex, void **virtual) { drmBO *buf = (drmBO *) private; int ret; @@ -202,7 +202,7 @@ pool_kernel(struct _DriBufferPool *pool, void *private) } static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, +pool_waitIdle(struct _DriBufferPool *pool, void *private, pipe_mutex *mutex, int lazy) { drmBO *buf = (drmBO *) private; diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.c b/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.c index b56bc269da..831c75d30c 100644 --- a/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.c +++ b/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.c @@ -1,5 +1,5 @@ #include "ws_dri_fencemgr.h" -#include "glthread.h" +#include "pipe/p_thread.h" #include #include #include @@ -20,7 +20,7 @@ struct _DriFenceMgr { /* * These members are protected by this->mutex */ - _glthread_Mutex mutex; + pipe_mutex mutex; int refCount; drmMMListHead *heads; int num_fences; @@ -44,7 +44,7 @@ struct _DriFenceObject { /* * These members are protected by this->mutex. */ - _glthread_Mutex mutex; + pipe_mutex mutex; uint32_t signaled_type; void *private; }; @@ -65,8 +65,8 @@ driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) if (!tmp) return NULL; - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); + pipe_mutex_init(tmp->mutex); + pipe_mutex_lock(tmp->mutex); tmp->refCount = 1; tmp->info = *info; tmp->num_fences = 0; @@ -77,7 +77,7 @@ driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) for (i=0; iinfo.num_classes; ++i) { DRMINITLISTHEAD(&tmp->heads[i]); } - _glthread_UNLOCK_MUTEX(tmp->mutex); + pipe_mutex_unlock(tmp->mutex); return tmp; out_err: @@ -95,13 +95,13 @@ driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) if (--mgr->refCount == 0) free(mgr); else - _glthread_UNLOCK_MUTEX(mgr->mutex); + pipe_mutex_unlock(mgr->mutex); } void driFenceMgrUnReference(struct _DriFenceMgr **pMgr) { - _glthread_LOCK_MUTEX((*pMgr)->mutex); + pipe_mutex_lock((*pMgr)->mutex); driFenceMgrUnrefUnlock(pMgr); } @@ -143,9 +143,9 @@ driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, */ ++entry->refCount; - _glthread_UNLOCK_MUTEX(mgr->mutex); - _glthread_LOCK_MUTEX(entry->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); + pipe_mutex_unlock(mgr->mutex); + pipe_mutex_lock(entry->mutex); + pipe_mutex_lock(mgr->mutex); prev = list->prev; @@ -157,7 +157,7 @@ driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, * Somebody else removed the entry from the list. */ - _glthread_UNLOCK_MUTEX(entry->mutex); + pipe_mutex_unlock(entry->mutex); driFenceUnReferenceLocked(&entry); return; } @@ -167,7 +167,7 @@ driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, DRMLISTDELINIT(list); mgr->info.unreference(mgr, &entry->private); } - _glthread_UNLOCK_MUTEX(entry->mutex); + pipe_mutex_unlock(entry->mutex); driFenceUnReferenceLocked(&entry); list = prev; } @@ -181,7 +181,7 @@ driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, struct _DriFenceMgr *mgr = fence->mgr; int ret = 0; - _glthread_LOCK_MUTEX(fence->mutex); + pipe_mutex_lock(fence->mutex); if ((fence->signaled_type & fence_type) == fence_type) goto out0; @@ -190,16 +190,16 @@ driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, if (ret) goto out0; - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); + pipe_mutex_lock(mgr->mutex); + pipe_mutex_unlock(fence->mutex); driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, fence_type); - _glthread_UNLOCK_MUTEX(mgr->mutex); + pipe_mutex_unlock(mgr->mutex); return 0; out0: - _glthread_UNLOCK_MUTEX(fence->mutex); + pipe_mutex_unlock(fence->mutex); return ret; } @@ -207,9 +207,9 @@ uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) { uint32_t ret; - _glthread_LOCK_MUTEX(fence->mutex); + pipe_mutex_lock(fence->mutex); ret = fence->signaled_type; - _glthread_UNLOCK_MUTEX(fence->mutex); + pipe_mutex_unlock(fence->mutex); return ret; } @@ -221,7 +221,7 @@ driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, int ret = 0; struct _DriFenceMgr *mgr; - _glthread_LOCK_MUTEX(fence->mutex); + pipe_mutex_lock(fence->mutex); mgr = fence->mgr; *signaled = fence->signaled_type; if ((fence->signaled_type & flush_type) == flush_type) @@ -236,25 +236,25 @@ driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, if ((fence->signaled_type | *signaled) == fence->signaled_type) goto out0; - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); + pipe_mutex_lock(mgr->mutex); + pipe_mutex_unlock(fence->mutex); driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, *signaled); - _glthread_UNLOCK_MUTEX(mgr->mutex); + pipe_mutex_unlock(mgr->mutex); return 0; out0: - _glthread_UNLOCK_MUTEX(fence->mutex); + pipe_mutex_unlock(fence->mutex); return ret; } struct _DriFenceObject * driFenceReference(struct _DriFenceObject *fence) { - _glthread_LOCK_MUTEX(fence->mgr->mutex); + pipe_mutex_lock(fence->mgr->mutex); ++fence->refCount; - _glthread_UNLOCK_MUTEX(fence->mgr->mutex); + pipe_mutex_unlock(fence->mgr->mutex); return fence; } @@ -267,7 +267,7 @@ driFenceUnReference(struct _DriFenceObject **pFence) return; mgr = (*pFence)->mgr; - _glthread_LOCK_MUTEX(mgr->mutex); + pipe_mutex_lock(mgr->mutex); ++mgr->refCount; driFenceUnReferenceLocked(pFence); driFenceMgrUnrefUnlock(&mgr); @@ -294,15 +294,15 @@ struct _DriFenceObject return NULL; } - _glthread_INIT_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); + pipe_mutex_init(fence->mutex); + pipe_mutex_lock(fence->mutex); + pipe_mutex_lock(mgr->mutex); fence->refCount = 1; DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); fence->mgr = mgr; ++mgr->refCount; ++mgr->num_fences; - _glthread_UNLOCK_MUTEX(mgr->mutex); + pipe_mutex_unlock(mgr->mutex); fence->fence_class = fence_class; fence->fence_type = fence_type; fence->signaled_type = 0; @@ -312,7 +312,7 @@ struct _DriFenceObject memcpy(fence->private, private, private_size); } - _glthread_UNLOCK_MUTEX(fence->mutex); + pipe_mutex_unlock(fence->mutex); return fence; } diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_mallocpool.c b/src/gallium/winsys/drm/intel/common/ws_dri_mallocpool.c index a80555c9c7..60924eac9e 100644 --- a/src/gallium/winsys/drm/intel/common/ws_dri_mallocpool.c +++ b/src/gallium/winsys/drm/intel/common/ws_dri_mallocpool.c @@ -33,7 +33,7 @@ #include #include #include "pipe/p_debug.h" -#include "glthread.h" +#include "pipe/p_thread.h" #include "ws_dri_bufpool.h" #include "ws_dri_bufmgr.h" @@ -60,14 +60,14 @@ pool_destroy(struct _DriBufferPool *pool, void *private) static int pool_waitIdle(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex, int lazy) + pipe_mutex *mutex, int lazy) { return 0; } static int pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) + int hint, pipe_mutex *mutex, void **virtual) { *virtual = (void *)((unsigned long *)private + 2); return 0; diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_slabpool.c b/src/gallium/winsys/drm/intel/common/ws_dri_slabpool.c index dfcf6d6b19..391cea50a7 100644 --- a/src/gallium/winsys/drm/intel/common/ws_dri_slabpool.c +++ b/src/gallium/winsys/drm/intel/common/ws_dri_slabpool.c @@ -37,7 +37,7 @@ #include "ws_dri_bufpool.h" #include "ws_dri_fencemgr.h" #include "ws_dri_bufmgr.h" -#include "glthread.h" +#include "pipe/p_thread.h" #define DRI_SLABPOOL_ALLOC_RETRIES 100 @@ -53,7 +53,7 @@ struct _DriSlabBuffer { uint32_t start; uint32_t fenceType; int unFenced; - _glthread_Cond event; + pipe_condvar event; }; struct _DriKernelBO { @@ -84,7 +84,7 @@ struct _DriSlabSizeHeader { uint32_t numDelayed; struct _DriSlabPool *slabPool; uint32_t bufSize; - _glthread_Mutex mutex; + pipe_mutex mutex; }; struct _DriFreeSlabManager { @@ -94,7 +94,7 @@ struct _DriFreeSlabManager { drmMMListHead timeoutList; drmMMListHead unCached; drmMMListHead cached; - _glthread_Mutex mutex; + pipe_mutex mutex; }; @@ -196,7 +196,7 @@ driSetKernelBOFree(struct _DriFreeSlabManager *fMan, { struct timeval time; - _glthread_LOCK_MUTEX(fMan->mutex); + pipe_mutex_lock(fMan->mutex); gettimeofday(&time, NULL); driTimeAdd(&time, &fMan->slabTimeout); @@ -210,7 +210,7 @@ driSetKernelBOFree(struct _DriFreeSlabManager *fMan, DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); driFreeTimeoutKBOsLocked(fMan, &time); - _glthread_UNLOCK_MUTEX(fMan->mutex); + pipe_mutex_unlock(fMan->mutex); } /* @@ -237,7 +237,7 @@ driAllocKernelBO(struct _DriSlabSizeHeader *header) size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); - _glthread_LOCK_MUTEX(fMan->mutex); + pipe_mutex_lock(fMan->mutex); kbo = NULL; @@ -269,7 +269,7 @@ driAllocKernelBO(struct _DriSlabSizeHeader *header) DRMLISTDELINIT(&kbo->timeoutHead); } - _glthread_UNLOCK_MUTEX(fMan->mutex); + pipe_mutex_unlock(fMan->mutex); if (kbo) { uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; @@ -360,7 +360,7 @@ driAllocSlab(struct _DriSlabSizeHeader *header) buf->start = i* header->bufSize; buf->mapCount = 0; buf->isSlabBuffer = 1; - _glthread_INIT_COND(buf->event); + pipe_condvar_init(buf->event); DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); slab->numFree++; buf++; @@ -494,23 +494,23 @@ driSlabAllocBuffer(struct _DriSlabSizeHeader *header) drmMMListHead *list; int count = DRI_SLABPOOL_ALLOC_RETRIES; - _glthread_LOCK_MUTEX(header->mutex); + pipe_mutex_lock(header->mutex); while(header->slabs.next == &header->slabs && count > 0) { driSlabCheckFreeLocked(header, 0); if (header->slabs.next != &header->slabs) break; - _glthread_UNLOCK_MUTEX(header->mutex); + pipe_mutex_unlock(header->mutex); if (count != DRI_SLABPOOL_ALLOC_RETRIES) usleep(1); - _glthread_LOCK_MUTEX(header->mutex); + pipe_mutex_lock(header->mutex); (void) driAllocSlab(header); count--; } list = header->slabs.next; if (list == &header->slabs) { - _glthread_UNLOCK_MUTEX(header->mutex); + pipe_mutex_unlock(header->mutex); return NULL; } slab = DRMLISTENTRY(struct _DriSlab, list, head); @@ -520,7 +520,7 @@ driSlabAllocBuffer(struct _DriSlabSizeHeader *header) list = slab->freeBuffers.next; DRMLISTDELINIT(list); - _glthread_UNLOCK_MUTEX(header->mutex); + pipe_mutex_unlock(header->mutex); buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); return buf; } @@ -618,7 +618,7 @@ pool_destroy(struct _DriBufferPool *driPool, void *private) slab = buf->parent; header = slab->header; - _glthread_LOCK_MUTEX(header->mutex); + pipe_mutex_lock(header->mutex); buf->unFenced = 0; buf->mapCount = 0; @@ -631,18 +631,18 @@ pool_destroy(struct _DriBufferPool *driPool, void *private) driSlabFreeBufferLocked(buf); } - _glthread_UNLOCK_MUTEX(header->mutex); + pipe_mutex_unlock(header->mutex); return 0; } static int pool_waitIdle(struct _DriBufferPool *driPool, void *private, - _glthread_Mutex *mutex, int lazy) + pipe_mutex *mutex, int lazy) { struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; while(buf->unFenced) - _glthread_COND_WAIT(buf->event, *mutex); + pipe_condvar_wait(buf->event, *mutex); if (!buf->fence) return 0; @@ -655,7 +655,7 @@ pool_waitIdle(struct _DriBufferPool *driPool, void *private, static int pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) + int hint, pipe_mutex *mutex, void **virtual) { struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; int busy; @@ -689,7 +689,7 @@ pool_unmap(struct _DriBufferPool *pool, void *private) --buf->mapCount; if (buf->mapCount == 0 && buf->isSlabBuffer) - _glthread_COND_BROADCAST(buf->event); + pipe_condvar_broadcast(buf->event); return 0; } @@ -760,7 +760,7 @@ pool_fence(struct _DriBufferPool *pool, void *private, buf->fenceType = bo->fenceFlags; buf->unFenced = 0; - _glthread_COND_BROADCAST(buf->event); + pipe_condvar_broadcast(buf->event); return 0; } @@ -775,7 +775,7 @@ pool_kernel(struct _DriBufferPool *pool, void *private) static int pool_validate(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex) + pipe_mutex *mutex) { struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; @@ -783,7 +783,7 @@ pool_validate(struct _DriBufferPool *pool, void *private, return 0; while(buf->mapCount != 0) - _glthread_COND_WAIT(buf->event, *mutex); + pipe_condvar_wait(buf->event, *mutex); buf->unFenced = 1; return 0; @@ -799,8 +799,8 @@ driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) if (!tmp) return NULL; - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); + pipe_mutex_init(tmp->mutex); + pipe_mutex_lock(tmp->mutex); tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; @@ -814,7 +814,7 @@ driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) DRMINITLISTHEAD(&tmp->timeoutList); DRMINITLISTHEAD(&tmp->unCached); DRMINITLISTHEAD(&tmp->cached); - _glthread_UNLOCK_MUTEX(tmp->mutex); + pipe_mutex_unlock(tmp->mutex); return tmp; } @@ -827,9 +827,9 @@ driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) time = fMan->nextCheck; driTimeAdd(&time, &fMan->checkInterval); - _glthread_LOCK_MUTEX(fMan->mutex); + pipe_mutex_lock(fMan->mutex); driFreeTimeoutKBOsLocked(fMan, &time); - _glthread_UNLOCK_MUTEX(fMan->mutex); + pipe_mutex_unlock(fMan->mutex); assert(fMan->timeoutList.next == &fMan->timeoutList); assert(fMan->unCached.next == &fMan->unCached); @@ -842,8 +842,8 @@ static void driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, struct _DriSlabSizeHeader *header) { - _glthread_INIT_MUTEX(header->mutex); - _glthread_LOCK_MUTEX(header->mutex); + pipe_mutex_init(header->mutex); + pipe_mutex_lock(header->mutex); DRMINITLISTHEAD(&header->slabs); DRMINITLISTHEAD(&header->freeSlabs); @@ -853,7 +853,7 @@ driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, header->slabPool = pool; header->bufSize = size; - _glthread_UNLOCK_MUTEX(header->mutex); + pipe_mutex_unlock(header->mutex); } static void @@ -862,7 +862,7 @@ driFinishSizeHeader(struct _DriSlabSizeHeader *header) drmMMListHead *list, *next; struct _DriSlabBuffer *buf; - _glthread_LOCK_MUTEX(header->mutex); + pipe_mutex_lock(header->mutex); for (list = header->delayedBuffers.next, next = list->next; list != &header->delayedBuffers; list = next, next = list->next) { @@ -875,7 +875,7 @@ driFinishSizeHeader(struct _DriSlabSizeHeader *header) header->numDelayed--; driSlabFreeBufferLocked(buf); } - _glthread_UNLOCK_MUTEX(header->mutex); + pipe_mutex_unlock(header->mutex); } static void diff --git a/src/gallium/winsys/drm/intel/dri/intel_lock.c b/src/gallium/winsys/drm/intel/dri/intel_lock.c index 406284c98f..18c7bba0d5 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_lock.c +++ b/src/gallium/winsys/drm/intel/dri/intel_lock.c @@ -27,7 +27,7 @@ #include "main/glheader.h" -#include "glapi/glthread.h" +#include "pipe/p_lthread.h" #include #include "state_tracker/st_public.h" #include "intel_context.h" @@ -35,7 +35,7 @@ -_glthread_DECLARE_STATIC_MUTEX( lockMutex ); +pipe_static_mutex( lockMutex ); static void @@ -72,7 +72,7 @@ void LOCK_HARDWARE( struct intel_context *intel ) { char __ret = 0; - _glthread_LOCK_MUTEX(lockMutex); + pipe_mutex_lock(lockMutex); assert(!intel->locked); DRM_CAS(intel->driHwLock, intel->hHWContext, @@ -96,7 +96,7 @@ void UNLOCK_HARDWARE( struct intel_context *intel ) DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); - _glthread_UNLOCK_MUTEX(lockMutex); + pipe_mutex_unlock(lockMutex); DBG(LOCK, "%s - unlocked\n", __progname); } diff --git a/src/gallium/winsys/xlib/glxapi.c b/src/gallium/winsys/xlib/glxapi.c index c2ccce6f52..c059fc3edb 100644 --- a/src/gallium/winsys/xlib/glxapi.c +++ b/src/gallium/winsys/xlib/glxapi.c @@ -37,6 +37,7 @@ #include "main/glheader.h" #include "glapi/glapi.h" #include "glxapi.h" +#include "pipe/p_thread.h" extern struct _glxapi_table *_real_GetGLXDispatchTable(void); @@ -127,26 +128,13 @@ get_dispatch(Display *dpy) /** * GLX API current context. */ -#if defined(GLX_USE_TLS) -PUBLIC __thread void * CurrentContext - __attribute__((tls_model("initial-exec"))); -#elif defined(THREADS) -static _glthread_TSD ContextTSD; /**< Per-thread context pointer */ -#else -static GLXContext CurrentContext = 0; -#endif +pipe_tsd ContextTSD; static void SetCurrentContext(GLXContext c) { -#if defined(GLX_USE_TLS) - CurrentContext = c; -#elif defined(THREADS) - _glthread_SetTSD(&ContextTSD, c); -#else - CurrentContext = c; -#endif + pipe_tsd_set(&ContextTSD, c); } @@ -238,13 +226,7 @@ glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value) GLXContext PUBLIC glXGetCurrentContext(void) { -#if defined(GLX_USE_TLS) - return CurrentContext; -#elif defined(THREADS) - return (GLXContext) _glthread_GetTSD(&ContextTSD); -#else - return CurrentContext; -#endif + return (GLXContext) pipe_tsd_get(&ContextTSD); } diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 7256340420..edcadff9c5 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -62,7 +62,6 @@ #include "xmesaP.h" #include "main/context.h" #include "main/framebuffer.h" -#include "glapi/glthread.h" #include "state_tracker/st_public.h" #include "state_tracker/st_context.h" @@ -75,7 +74,7 @@ /** * Global X driver lock */ -_glthread_Mutex _xmesa_lock; +pipe_mutex _xmesa_lock; int xmesa_mode; @@ -245,10 +244,10 @@ xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b, #else Status stat; - _glthread_LOCK_MUTEX(_xmesa_lock); + pipe_mutex_lock(_xmesa_lock); XSync(b->xm_visual->display, 0); /* added for Chromium */ stat = get_drawable_size(dpy, b->drawable, width, height); - _glthread_UNLOCK_MUTEX(_xmesa_lock); + pipe_mutex_unlock(_xmesa_lock); if (!stat) { /* probably querying a window that's recently been destroyed */ @@ -779,7 +778,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) uint pf; if (firstTime) { - _glthread_INIT_MUTEX(_xmesa_lock); + pipe_mutex_init(_xmesa_lock); firstTime = GL_FALSE; } diff --git a/src/gallium/winsys/xlib/xmesaP.h b/src/gallium/winsys/xlib/xmesaP.h index 9b15b2ddf9..fcaeee52bc 100644 --- a/src/gallium/winsys/xlib/xmesaP.h +++ b/src/gallium/winsys/xlib/xmesaP.h @@ -35,9 +35,10 @@ #include "state_tracker/st_context.h" #include "state_tracker/st_public.h" +#include "pipe/p_thread.h" -extern _glthread_Mutex _xmesa_lock; +extern pipe_mutex _xmesa_lock; extern XMesaBuffer XMesaBufferList; -- cgit v1.2.3 From 6f33b778ae3130571d17a110187379ec0beecbd8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 27 Aug 2008 11:29:26 -0600 Subject: gallium: call st_finish() in XMesaFlush() --- src/gallium/winsys/xlib/xm_api.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index edcadff9c5..b010513107 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -1298,6 +1298,7 @@ void XMesaFlush( XMesaContext c ) #ifdef XFree86Server /* NOT_NEEDED */ #else + st_finish(c->st); XSync( c->xm_visual->display, False ); #endif } -- cgit v1.2.3 From 28b4090922f45e90804a21f83c04ec8b781cdf96 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 1 Sep 2008 15:32:40 -0600 Subject: gallium: remove glthread.h file (not used) --- src/gallium/winsys/drm/intel/common/glthread.h | 359 ------------------------- 1 file changed, 359 deletions(-) delete mode 100644 src/gallium/winsys/drm/intel/common/glthread.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/common/glthread.h b/src/gallium/winsys/drm/intel/common/glthread.h deleted file mode 100644 index b8e9d5f59b..0000000000 --- a/src/gallium/winsys/drm/intel/common/glthread.h +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 1999-2006 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - - -/* - * Thread support for gl dispatch. - * - * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) - * and Christoph Poliwoda (poliwoda@volumegraphics.com) - * Revised by Keith Whitwell - * Adapted for new gl dispatcher by Brian Paul - * - * - * - * DOCUMENTATION - * - * This thread module exports the following types: - * _glthread_TSD Thread-specific data area - * _glthread_Thread Thread datatype - * _glthread_Mutex Mutual exclusion lock - * - * Macros: - * _glthread_DECLARE_STATIC_MUTEX(name) Declare a non-local mutex - * _glthread_INIT_MUTEX(name) Initialize a mutex - * _glthread_LOCK_MUTEX(name) Lock a mutex - * _glthread_UNLOCK_MUTEX(name) Unlock a mutex - * - * Functions: - * _glthread_GetID(v) Get integer thread ID - * _glthread_InitTSD() Initialize thread-specific data - * _glthread_GetTSD() Get thread-specific data - * _glthread_SetTSD() Set thread-specific data - * - */ - -/* - * If this file is accidentally included by a non-threaded build, - * it should not cause the build to fail, or otherwise cause problems. - * In general, it should only be included when needed however. - */ - -#ifndef GLTHREAD_H -#define GLTHREAD_H - - -#if defined(USE_MGL_NAMESPACE) -#define _glapi_Dispatch _mglapi_Dispatch -#endif - - - -#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\ - defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \ - && !defined(THREADS) -# define THREADS -#endif - -#ifdef VMS -#include -#endif - -/* - * POSIX threads. This should be your choice in the Unix world - * whenever possible. When building with POSIX threads, be sure - * to enable any compiler flags which will cause the MT-safe - * libc (if one exists) to be used when linking, as well as any - * header macros for MT-safe errno, etc. For Solaris, this is the -mt - * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable - * proper compiling for MT-safe libc etc. - */ -#if defined(PTHREADS) -#include /* POSIX threads headers */ - -typedef struct { - pthread_key_t key; - int initMagic; -} _glthread_TSD; - -typedef pthread_t _glthread_Thread; - -typedef pthread_mutex_t _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) \ - static _glthread_Mutex name = PTHREAD_MUTEX_INITIALIZER - -#define _glthread_INIT_MUTEX(name) \ - pthread_mutex_init(&(name), NULL) - -#define _glthread_DESTROY_MUTEX(name) \ - pthread_mutex_destroy(&(name)) - -#define _glthread_LOCK_MUTEX(name) \ - (void) pthread_mutex_lock(&(name)) - -#define _glthread_UNLOCK_MUTEX(name) \ - (void) pthread_mutex_unlock(&(name)) - -typedef pthread_cond_t _glthread_Cond; - -#define _glthread_DECLARE_STATIC_COND(name) \ - static _glthread_Cond name = PTHREAD_COND_INITIALIZER - -#define _glthread_INIT_COND(cond) \ - pthread_cond_init(&(cond), NULL) - -#define _glthread_DESTROY_COND(name) \ - pthread_cond_destroy(&(name)) - -#define _glthread_COND_WAIT(cond, mutex) \ - pthread_cond_wait(&(cond), &(mutex)) - -#define _glthread_COND_SIGNAL(cond) \ - pthread_cond_signal(&(cond)) - -#define _glthread_COND_BROADCAST(cond) \ - pthread_cond_broadcast(&(cond)) - - -#else /* PTHREADS */ - -typedef unsigned int _glthread_Cond; -#define _glthread_DECLARE_STATIC_COND(name) \ -// #warning Condition variables not implemented. - -#define _glthread_INIT_COND(cond) \ - abort(); - -#define _glthread_DESTROY_COND(name) \ - abort(); - -#define _glthread_COND_WAIT(cond, mutex) \ - abort(); - -#define _glthread_COND_SIGNAL(cond) \ - abort(); - -#define _glthread_COND_BROADCAST(cond) \ - abort(); - -#endif - - -/* - * Solaris threads. Use only up to Solaris 2.4. - * Solaris 2.5 and higher provide POSIX threads. - * Be sure to compile with -mt on the Solaris compilers, or - * use -D_REENTRANT if using gcc. - */ -#ifdef SOLARIS_THREADS -#include - -typedef struct { - thread_key_t key; - mutex_t keylock; - int initMagic; -} _glthread_TSD; - -typedef thread_t _glthread_Thread; - -typedef mutex_t _glthread_Mutex; - -/* XXX need to really implement mutex-related macros */ -#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 -#define _glthread_INIT_MUTEX(name) (void) name -#define _glthread_DESTROY_MUTEX(name) (void) name -#define _glthread_LOCK_MUTEX(name) (void) name -#define _glthread_UNLOCK_MUTEX(name) (void) name - -#endif /* SOLARIS_THREADS */ - - - - -/* - * Windows threads. Should work with Windows NT and 95. - * IMPORTANT: Link with multithreaded runtime library when THREADS are - * used! - */ -#ifdef WIN32_THREADS -#include - -typedef struct { - DWORD key; - int initMagic; -} _glthread_TSD; - -typedef HANDLE _glthread_Thread; - -typedef CRITICAL_SECTION _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) /*static*/ _glthread_Mutex name = {0,0,0,0,0,0} -#define _glthread_INIT_MUTEX(name) InitializeCriticalSection(&name) -#define _glthread_DESTROY_MUTEX(name) DeleteCriticalSection(&name) -#define _glthread_LOCK_MUTEX(name) EnterCriticalSection(&name) -#define _glthread_UNLOCK_MUTEX(name) LeaveCriticalSection(&name) - -#endif /* WIN32_THREADS */ - - - - -/* - * XFree86 has its own thread wrapper, Xthreads.h - * We wrap it again for GL. - */ -#ifdef USE_XTHREADS -#include - -typedef struct { - xthread_key_t key; - int initMagic; -} _glthread_TSD; - -typedef xthread_t _glthread_Thread; - -typedef xmutex_rec _glthread_Mutex; - -#ifdef XMUTEX_INITIALIZER -#define _glthread_DECLARE_STATIC_MUTEX(name) \ - static _glthread_Mutex name = XMUTEX_INITIALIZER -#else -#define _glthread_DECLARE_STATIC_MUTEX(name) \ - static _glthread_Mutex name -#endif - -#define _glthread_INIT_MUTEX(name) \ - xmutex_init(&(name)) - -#define _glthread_DESTROY_MUTEX(name) \ - xmutex_clear(&(name)) - -#define _glthread_LOCK_MUTEX(name) \ - (void) xmutex_lock(&(name)) - -#define _glthread_UNLOCK_MUTEX(name) \ - (void) xmutex_unlock(&(name)) - -#endif /* USE_XTHREADS */ - - - -/* - * BeOS threads. R5.x required. - */ -#ifdef BEOS_THREADS - -#include -#include - -typedef struct { - int32 key; - int initMagic; -} _glthread_TSD; - -typedef thread_id _glthread_Thread; - -/* Use Benaphore, aka speeder semaphore */ -typedef struct { - int32 lock; - sem_id sem; -} benaphore; -typedef benaphore _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = { 0, 0 } -#define _glthread_INIT_MUTEX(name) name.sem = create_sem(0, #name"_benaphore"), name.lock = 0 -#define _glthread_DESTROY_MUTEX(name) delete_sem(name.sem), name.lock = 0 -#define _glthread_LOCK_MUTEX(name) if (name.sem == 0) _glthread_INIT_MUTEX(name); \ - if (atomic_add(&(name.lock), 1) >= 1) acquire_sem(name.sem) -#define _glthread_UNLOCK_MUTEX(name) if (atomic_add(&(name.lock), -1) > 1) release_sem(name.sem) - -#endif /* BEOS_THREADS */ - - - -#ifndef THREADS - -/* - * THREADS not defined - */ - -typedef GLuint _glthread_TSD; - -typedef GLuint _glthread_Thread; - -typedef GLuint _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 - -#define _glthread_INIT_MUTEX(name) (void) name - -#define _glthread_DESTROY_MUTEX(name) (void) name - -#define _glthread_LOCK_MUTEX(name) (void) name - -#define _glthread_UNLOCK_MUTEX(name) (void) name - -#endif /* THREADS */ - - - -/* - * Platform independent thread specific data API. - */ - -extern unsigned long -_glthread_GetID(void); - - -extern void -_glthread_InitTSD(_glthread_TSD *); - - -extern void * -_glthread_GetTSD(_glthread_TSD *); - - -extern void -_glthread_SetTSD(_glthread_TSD *, void *); - -#if defined(GLX_USE_TLS) - -extern __thread struct _glapi_table * _glapi_tls_Dispatch - __attribute__((tls_model("initial-exec"))); - -#define GET_DISPATCH() _glapi_tls_Dispatch - -#elif !defined(GL_CALL) -# if defined(THREADS) -# define GET_DISPATCH() \ - ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ - ? _glapi_Dispatch : _glapi_get_dispatch()) -# else -# define GET_DISPATCH() _glapi_Dispatch -# endif /* defined(THREADS) */ -#endif /* ndef GL_CALL */ - - -#endif /* THREADS_H */ -- cgit v1.2.3 From 2774b09d4e6957e202ece37337ae6201f7aa8eb7 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 2 Sep 2008 17:29:19 +0200 Subject: i915: Fix typo in ws_dri_bufmgr.c --- src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c b/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c index 499f7bef8f..517a97b3ee 100644 --- a/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c +++ b/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c @@ -277,7 +277,7 @@ void driReadUnlockKernelBO(void) typedef struct _DriBufferObject { DriBufferPool *pool; - pipe_mutx mutex; + pipe_mutex mutex; int refCount; const char *name; uint64_t flags; -- cgit v1.2.3 From 72b90b7894afbcb39f72dc4d76cdea0678bf4bc3 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 1 Sep 2008 22:21:08 +0200 Subject: Intialize swizzled_surface object --- src/gallium/winsys/dri/nouveau/nv04_surface.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index 0085b1c345..8fa3d106c8 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -276,6 +276,10 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) } BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); + OUT_RING (chan, nvc->channel->vram->handle); if (chipset < 0x10) { class = NV04_SCALED_IMAGE_FROM_MEMORY; -- cgit v1.2.3 From f637a96e85a51a66f2c53b91118a6815bb61d6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 3 Sep 2008 11:48:05 +0900 Subject: gallium: Have pipe_buffer_* receive a pipe_screen instead of a pipe_context. We want to use the pipe_buffer_* inlines everywhere, but a pipe context is not always available nor is it needed. --- src/gallium/winsys/drm/intel/dri/intel_screen.c | 2 +- src/gallium/winsys/egl_xlib/sw_winsys.c | 2 +- src/gallium/winsys/gdi/wmesa.c | 2 +- src/gallium/winsys/xlib/xm_winsys.c | 2 +- src/gallium/winsys/xlib/xm_winsys_aub.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/dri/intel_screen.c b/src/gallium/winsys/drm/intel/dri/intel_screen.c index 46d4861e77..3a486481f5 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_screen.c +++ b/src/gallium/winsys/drm/intel/dri/intel_screen.c @@ -83,7 +83,7 @@ intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, buffer); /* Unref the buffer we don't need it anyways */ - pipe_buffer_reference(screen->winsys, &buffer, NULL); + pipe_buffer_reference(screen, &buffer, NULL); surface = screen->get_tex_surface(screen, texture, diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index ae81d7f801..2fd190da52 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -216,7 +216,7 @@ surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) surf->refcount--; if (surf->refcount == 0) { if (surf->buffer) - pipe_buffer_reference(winsys, &surf->buffer, NULL); + winsys_buffer_reference(winsys, &surf->buffer, NULL); free(surf); } *s = NULL; diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c index 730fb1b541..ed3dd2b927 100644 --- a/src/gallium/winsys/gdi/wmesa.c +++ b/src/gallium/winsys/gdi/wmesa.c @@ -463,7 +463,7 @@ wm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) surf->refcount--; if (surf->refcount == 0) { if (surf->buffer) - pipe_buffer_reference(winsys, &surf->buffer, NULL); + winsys_buffer_reference(winsys, &surf->buffer, NULL); free(surf); } *s = NULL; diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 68ead7f528..70f01e0ef8 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -543,7 +543,7 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) surf->refcount--; if (surf->refcount == 0) { if (surf->buffer) - pipe_buffer_reference(winsys, &surf->buffer, NULL); + winsys_buffer_reference(winsys, &surf->buffer, NULL); free(surf); } *s = NULL; diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index 35c4ebc4ba..b7c10b6bca 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -308,7 +308,7 @@ aub_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) surf->refcount--; if (surf->refcount == 0) { if (surf->buffer) - pipe_buffer_reference(winsys, &surf->buffer, NULL); + winsys_buffer_reference(winsys, &surf->buffer, NULL); free(surf); } *s = NULL; -- cgit v1.2.3 From ab93aa774e2fc09b5f579eb13ce94cf22796902b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 3 Sep 2008 09:08:19 -0600 Subject: Cell: added linux-cell-debug config linux-cell is now the optimized configuration. Remove some Cell-specific stuff from winsys/xlib/Makefile. --- src/gallium/winsys/xlib/Makefile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index ec92c79068..11c7632411 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -33,10 +33,7 @@ XLIB_WINSYS_SOURCES = \ XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o) -ifeq ($(CONFIG_NAME), linux-cell) -# The SPU code is in a separate .a file, unfortunately -CELL_SPU_LIB = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a -endif +# Note: CELL_SPU_LIB is only defined for cell configs LIBS = \ $(GALLIUM_DRIVERS) \ -- cgit v1.2.3 From 1d5ad2c244f4b66ca1ac40c545482009ab46607c Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 3 Sep 2008 15:01:19 +0200 Subject: i915: Fix typo in intel_lock.c --- src/gallium/winsys/drm/intel/dri/intel_lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/dri/intel_lock.c b/src/gallium/winsys/drm/intel/dri/intel_lock.c index 18c7bba0d5..ad1c202429 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_lock.c +++ b/src/gallium/winsys/drm/intel/dri/intel_lock.c @@ -27,7 +27,7 @@ #include "main/glheader.h" -#include "pipe/p_lthread.h" +#include "pipe/p_thread.h" #include #include "state_tracker/st_public.h" #include "intel_context.h" -- cgit v1.2.3 From 2ab394a3b4557f1d79d38f24f899508d7b13cd35 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 3 Sep 2008 10:26:38 -0600 Subject: cell: move misplaced assertions; put them after ximage is assigned. --- src/gallium/winsys/xlib/xm_winsys.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 70f01e0ef8..cc9f49a731 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -287,16 +287,16 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE; uint x, y; - /* check that the XImage has been previously initialized */ - assert(ximage->format); - assert(ximage->bitmap_unit); - if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { alloc_shm_ximage(xm_buf, b, TILE_SIZE, TILE_SIZE); } ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; + /* check that the XImage has been previously initialized */ + assert(ximage->format); + assert(ximage->bitmap_unit); + if (!XSHM_ENABLED(xm_buf)) { /* update XImage's fields */ ximage->width = TILE_SIZE; -- cgit v1.2.3 From 6ebf712d88e7d1da949e224b93ff12ef601f2742 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 3 Sep 2008 11:44:14 -0600 Subject: gallium: do image clipping in xmesa_display_surface_tiled() --- src/gallium/winsys/xlib/xm_winsys.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index cc9f49a731..5e9a1f92f1 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -306,11 +306,16 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) for (y = 0; y < surf->height; y += TILE_SIZE) { for (x = 0; x < surf->width; x += TILE_SIZE) { - int dx = x; - int dy = y; int tx = x / TILE_SIZE; int ty = y / TILE_SIZE; int offset = ty * tilesPerRow + tx; + int w = TILE_SIZE; + int h = TILE_SIZE; + + if (y + h > surf->height) + h = surf->height - y; + if (x + w > surf->width) + w = surf->width - x; offset *= 4 * TILE_SIZE * TILE_SIZE; @@ -319,11 +324,12 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) if (XSHM_ENABLED(xm_buf)) { #if defined(USE_XSHM) && !defined(XFree86Server) XShmPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, x, y, TILE_SIZE, TILE_SIZE, False); + ximage, 0, 0, x, y, w, h, False); #endif - } else { + } + else { XPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, dx, dy, TILE_SIZE, TILE_SIZE); + ximage, 0, 0, x, y, w, h); } } } -- cgit v1.2.3 From 52c2dd1f73e17c8352fe976e2ee4cdf049f81957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 8 Sep 2008 07:54:15 +0900 Subject: scons: Install libGL.so and respective symlinks. --- src/gallium/winsys/xlib/SConscript | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 8650f595a7..324fbef306 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -36,8 +36,10 @@ if env['platform'] == 'linux' \ drivers += [trace] # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions - env.SharedLibrary( + libgl = env.SharedLibrary( target ='GL', source = sources, LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], ) + + env.InstallSharedLibrary(libgl, version=(1, 5)) -- cgit v1.2.3 From f302fca5eb63e4bca8af5b35c585451486143e6a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 11 Sep 2008 06:41:18 +1000 Subject: nouveau: gallium directory structure changed again.. --- src/gallium/winsys/dri/nouveau/Makefile | 45 -- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 470 --------------------- src/gallium/winsys/dri/nouveau/nouveau_channel.c | 126 ------ src/gallium/winsys/dri/nouveau/nouveau_context.c | 346 --------------- src/gallium/winsys/dri/nouveau/nouveau_context.h | 113 ----- src/gallium/winsys/dri/nouveau/nouveau_device.c | 159 ------- src/gallium/winsys/dri/nouveau/nouveau_dma.c | 219 ---------- src/gallium/winsys/dri/nouveau/nouveau_dma.h | 143 ------- src/gallium/winsys/dri/nouveau/nouveau_dri.h | 28 -- src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 310 -------------- src/gallium/winsys/dri/nouveau/nouveau_fence.c | 214 ---------- src/gallium/winsys/dri/nouveau/nouveau_grobj.c | 107 ----- src/gallium/winsys/dri/nouveau/nouveau_local.h | 117 ----- src/gallium/winsys/dri/nouveau/nouveau_lock.c | 94 ----- src/gallium/winsys/dri/nouveau/nouveau_notifier.c | 137 ------ src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 271 ------------ src/gallium/winsys/dri/nouveau/nouveau_resource.c | 116 ----- src/gallium/winsys/dri/nouveau/nouveau_screen.c | 310 -------------- src/gallium/winsys/dri/nouveau/nouveau_screen.h | 20 - .../winsys/dri/nouveau/nouveau_swapbuffers.c | 86 ---- .../winsys/dri/nouveau/nouveau_swapbuffers.h | 10 - src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 158 ------- .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 205 --------- .../winsys/dri/nouveau/nouveau_winsys_pipe.h | 34 -- .../winsys/dri/nouveau/nouveau_winsys_softpipe.c | 85 ---- src/gallium/winsys/dri/nouveau/nv04_surface.c | 314 -------------- src/gallium/winsys/dri/nouveau/nv50_surface.c | 194 --------- src/gallium/winsys/drm/nouveau/Makefile | 45 ++ src/gallium/winsys/drm/nouveau/nouveau_bo.c | 470 +++++++++++++++++++++ src/gallium/winsys/drm/nouveau/nouveau_channel.c | 126 ++++++ src/gallium/winsys/drm/nouveau/nouveau_context.c | 346 +++++++++++++++ src/gallium/winsys/drm/nouveau/nouveau_context.h | 113 +++++ src/gallium/winsys/drm/nouveau/nouveau_device.c | 159 +++++++ src/gallium/winsys/drm/nouveau/nouveau_dma.c | 219 ++++++++++ src/gallium/winsys/drm/nouveau/nouveau_dma.h | 143 +++++++ src/gallium/winsys/drm/nouveau/nouveau_dri.h | 28 ++ src/gallium/winsys/drm/nouveau/nouveau_drmif.h | 310 ++++++++++++++ src/gallium/winsys/drm/nouveau/nouveau_fence.c | 214 ++++++++++ src/gallium/winsys/drm/nouveau/nouveau_grobj.c | 107 +++++ src/gallium/winsys/drm/nouveau/nouveau_local.h | 117 +++++ src/gallium/winsys/drm/nouveau/nouveau_lock.c | 94 +++++ src/gallium/winsys/drm/nouveau/nouveau_notifier.c | 137 ++++++ src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c | 271 ++++++++++++ src/gallium/winsys/drm/nouveau/nouveau_resource.c | 116 +++++ src/gallium/winsys/drm/nouveau/nouveau_screen.c | 310 ++++++++++++++ src/gallium/winsys/drm/nouveau/nouveau_screen.h | 20 + .../winsys/drm/nouveau/nouveau_swapbuffers.c | 86 ++++ .../winsys/drm/nouveau/nouveau_swapbuffers.h | 10 + src/gallium/winsys/drm/nouveau/nouveau_winsys.c | 158 +++++++ .../winsys/drm/nouveau/nouveau_winsys_pipe.c | 206 +++++++++ .../winsys/drm/nouveau/nouveau_winsys_pipe.h | 34 ++ .../winsys/drm/nouveau/nouveau_winsys_softpipe.c | 85 ++++ src/gallium/winsys/drm/nouveau/nv04_surface.c | 314 ++++++++++++++ src/gallium/winsys/drm/nouveau/nv50_surface.c | 194 +++++++++ 54 files changed, 4432 insertions(+), 4431 deletions(-) delete mode 100644 src/gallium/winsys/dri/nouveau/Makefile delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_bo.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_channel.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_context.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_context.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_device.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_dma.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_dma.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_dri.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_drmif.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_fence.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_grobj.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_local.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_lock.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_notifier.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_resource.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_screen.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_screen.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c delete mode 100644 src/gallium/winsys/dri/nouveau/nv04_surface.c delete mode 100644 src/gallium/winsys/dri/nouveau/nv50_surface.c create mode 100644 src/gallium/winsys/drm/nouveau/Makefile create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_bo.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_channel.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_context.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_context.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_device.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_dma.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_dma.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_dri.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_drmif.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_fence.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_grobj.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_local.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_lock.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_notifier.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_resource.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_screen.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_screen.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_winsys.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c create mode 100644 src/gallium/winsys/drm/nouveau/nv04_surface.c create mode 100644 src/gallium/winsys/drm/nouveau/nv50_surface.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/dri/nouveau/Makefile b/src/gallium/winsys/dri/nouveau/Makefile deleted file mode 100644 index be630ff6d1..0000000000 --- a/src/gallium/winsys/dri/nouveau/Makefile +++ /dev/null @@ -1,45 +0,0 @@ - -TOP = ../../../../.. -include $(TOP)/configs/current - -LIBNAME = nouveau_dri.so - -MINIGLX_SOURCES = - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/nv04/libnv04.a \ - $(TOP)/src/gallium/drivers/nv10/libnv10.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_bo.c \ - nouveau_channel.c \ - nouveau_context.c \ - nouveau_device.c \ - nouveau_dma.c \ - nouveau_fence.c \ - nouveau_grobj.c \ - nouveau_lock.c \ - nouveau_notifier.c \ - nouveau_pushbuf.c \ - nouveau_resource.c \ - nouveau_screen.c \ - nouveau_swapbuffers.c \ - nouveau_winsys.c \ - nouveau_winsys_pipe.c \ - nouveau_winsys_softpipe.c \ - nv04_surface.c \ - nv50_surface.c - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - -include ../Makefile.template - -symlinks: diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c deleted file mode 100644 index b5942994d9..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" -#include "nouveau_local.h" - -static void -nouveau_mem_free(struct nouveau_device *dev, struct drm_nouveau_mem_alloc *ma, - void **map) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct drm_nouveau_mem_free mf; - - if (map && *map) { - drmUnmap(*map, ma->size); - *map = NULL; - } - - if (ma->size) { - mf.offset = ma->offset; - mf.flags = ma->flags; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_MEM_FREE, - &mf, sizeof(mf)); - ma->size = 0; - } -} - -static int -nouveau_mem_alloc(struct nouveau_device *dev, unsigned size, unsigned align, - uint32_t flags, struct drm_nouveau_mem_alloc *ma, void **map) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - int ret; - - ma->alignment = align; - ma->size = size; - ma->flags = flags; - if (map) - ma->flags |= NOUVEAU_MEM_MAPPED; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_MEM_ALLOC, ma, - sizeof(struct drm_nouveau_mem_alloc)); - if (ret) - return ret; - - if (map) { - ret = drmMap(nvdev->fd, ma->map_handle, ma->size, map); - if (ret) { - *map = NULL; - nouveau_mem_free(dev, ma, map); - return ret; - } - } - - return 0; -} - -static void -nouveau_bo_tmp_del(void *priv) -{ - struct nouveau_resource *r = priv; - - nouveau_fence_ref(NULL, (struct nouveau_fence **)&r->priv); - nouveau_resource_free(&r); -} - -static unsigned -nouveau_bo_tmp_max(struct nouveau_device_priv *nvdev) -{ - struct nouveau_resource *r = nvdev->sa_heap; - unsigned max = 0; - - while (r) { - if (r->in_use && !nouveau_fence(r->priv)->emitted) { - r = r->next; - continue; - } - - if (max < r->size) - max = r->size; - r = r->next; - } - - return max; -} - -static struct nouveau_resource * -nouveau_bo_tmp(struct nouveau_channel *chan, unsigned size, - struct nouveau_fence *fence) -{ - struct nouveau_device_priv *nvdev = nouveau_device(chan->device); - struct nouveau_resource *r = NULL; - struct nouveau_fence *ref = NULL; - - if (fence) - nouveau_fence_ref(fence, &ref); - else - nouveau_fence_new(chan, &ref); - assert(ref); - - while (nouveau_resource_alloc(nvdev->sa_heap, size, ref, &r)) { - if (nouveau_bo_tmp_max(nvdev) < size) { - nouveau_fence_ref(NULL, &ref); - return NULL; - } - - nouveau_fence_flush(chan); - } - nouveau_fence_signal_cb(ref, nouveau_bo_tmp_del, r); - - return r; -} - -int -nouveau_bo_init(struct nouveau_device *dev) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - int ret; - - ret = nouveau_mem_alloc(dev, 128*1024, 0, NOUVEAU_MEM_AGP | - NOUVEAU_MEM_PCI, &nvdev->sa, &nvdev->sa_map); - if (ret) - return ret; - - ret = nouveau_resource_init(&nvdev->sa_heap, 0, nvdev->sa.size); - if (ret) { - nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); - return ret; - } - - return 0; -} - -void -nouveau_bo_takedown(struct nouveau_device *dev) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); -} - -int -nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, - int size, struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo; - int ret; - - if (!dev || !bo || *bo) - return -EINVAL; - - nvbo = calloc(1, sizeof(struct nouveau_bo_priv)); - if (!nvbo) - return -ENOMEM; - nvbo->base.device = dev; - nvbo->base.size = size; - nvbo->base.handle = bo_to_ptr(nvbo); - nvbo->drm.alignment = align; - nvbo->refcount = 1; - - if (flags & NOUVEAU_BO_TILED) { - nvbo->tiled = 1; - if (flags & NOUVEAU_BO_ZTILE) - nvbo->tiled |= 2; - flags &= ~NOUVEAU_BO_TILED; - } - - ret = nouveau_bo_set_status(&nvbo->base, flags); - if (ret) { - free(nvbo); - return ret; - } - - *bo = &nvbo->base; - return 0; -} - -int -nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size, - struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo; - - if (!dev || !bo || *bo) - return -EINVAL; - - nvbo = calloc(1, sizeof(*nvbo)); - if (!nvbo) - return -ENOMEM; - nvbo->base.device = dev; - - nvbo->sysmem = ptr; - nvbo->user = 1; - - nvbo->base.size = size; - nvbo->base.offset = nvbo->drm.offset; - nvbo->base.handle = bo_to_ptr(nvbo); - nvbo->refcount = 1; - *bo = &nvbo->base; - return 0; -} - -int -nouveau_bo_ref(struct nouveau_device *dev, uint64_t handle, - struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo = ptr_to_bo(handle); - - if (!dev || !bo || *bo) - return -EINVAL; - - nvbo->refcount++; - *bo = &nvbo->base; - return 0; -} - -static void -nouveau_bo_del_cb(void *priv) -{ - struct nouveau_bo_priv *nvbo = priv; - - nouveau_fence_ref(NULL, &nvbo->fence); - nouveau_mem_free(nvbo->base.device, &nvbo->drm, &nvbo->map); - if (nvbo->sysmem && !nvbo->user) - free(nvbo->sysmem); - free(nvbo); -} - -void -nouveau_bo_del(struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo; - - if (!bo || !*bo) - return; - nvbo = nouveau_bo(*bo); - *bo = NULL; - - if (--nvbo->refcount) - return; - - if (nvbo->pending) - nouveau_pushbuf_flush(nvbo->pending->channel, 0); - - if (nvbo->fence) - nouveau_fence_signal_cb(nvbo->fence, nouveau_bo_del_cb, nvbo); - else - nouveau_bo_del_cb(nvbo); -} - -int -nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - - if (!nvbo) - return -EINVAL; - - if (nvbo->pending && - (nvbo->pending->flags & NOUVEAU_BO_WR || flags & NOUVEAU_BO_WR)) { - nouveau_pushbuf_flush(nvbo->pending->channel, 0); - } - - if (flags & NOUVEAU_BO_WR) - nouveau_fence_wait(&nvbo->fence); - else - nouveau_fence_wait(&nvbo->wr_fence); - - if (nvbo->sysmem) - bo->map = nvbo->sysmem; - else - bo->map = nvbo->map; - return 0; -} - -void -nouveau_bo_unmap(struct nouveau_bo *bo) -{ - bo->map = NULL; -} - -static int -nouveau_bo_upload(struct nouveau_bo_priv *nvbo) -{ - if (nvbo->fence) - nouveau_fence_wait(&nvbo->fence); - memcpy(nvbo->map, nvbo->sysmem, nvbo->drm.size); - return 0; -} - -int -nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct drm_nouveau_mem_alloc new; - void *new_map = NULL, *new_sysmem = NULL; - unsigned new_flags = 0, ret; - - assert(!bo->map); - - /* Check current memtype vs requested, if they match do nothing */ - if ((nvbo->drm.flags & NOUVEAU_MEM_FB) && (flags & NOUVEAU_BO_VRAM)) - return 0; - if ((nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) && - (flags & NOUVEAU_BO_GART)) - return 0; - if (nvbo->drm.size == 0 && nvbo->sysmem && (flags & NOUVEAU_BO_LOCAL)) - return 0; - - memset(&new, 0x00, sizeof(new)); - - /* Allocate new memory */ - if (flags & NOUVEAU_BO_VRAM) - new_flags |= NOUVEAU_MEM_FB; - else - if (flags & NOUVEAU_BO_GART) - new_flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI); - - if (nvbo->tiled && flags) { - new_flags |= NOUVEAU_MEM_TILE; - if (nvbo->tiled & 2) - new_flags |= NOUVEAU_MEM_TILE_ZETA; - } - - if (new_flags) { - ret = nouveau_mem_alloc(bo->device, bo->size, - nvbo->drm.alignment, new_flags, - &new, &new_map); - if (ret) - return ret; - } else - if (!nvbo->user) { - new_sysmem = malloc(bo->size); - } - - /* Copy old -> new */ - /*XXX: use M2MF */ - if (nvbo->sysmem || nvbo->map) { - struct nouveau_pushbuf_bo *pbo = nvbo->pending; - nvbo->pending = NULL; - nouveau_bo_map(bo, NOUVEAU_BO_RD); - memcpy(new_map, bo->map, bo->size); - nouveau_bo_unmap(bo); - nvbo->pending = pbo; - } - - /* Free old memory */ - if (nvbo->fence) - nouveau_fence_wait(&nvbo->fence); - nouveau_mem_free(bo->device, &nvbo->drm, &nvbo->map); - if (nvbo->sysmem && !nvbo->user) - free(nvbo->sysmem); - - nvbo->drm = new; - nvbo->map = new_map; - if (!nvbo->user) - nvbo->sysmem = new_sysmem; - bo->flags = flags; - bo->offset = nvbo->drm.offset; - return 0; -} - -static int -nouveau_bo_validate_user(struct nouveau_channel *chan, struct nouveau_bo *bo, - struct nouveau_fence *fence, uint32_t flags) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_device_priv *nvdev = nouveau_device(chan->device); - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_resource *r; - - if (nvchan->user_charge + bo->size > nvdev->sa.size) - return 1; - - if (!(flags & NOUVEAU_BO_GART)) - return 1; - - r = nouveau_bo_tmp(chan, bo->size, fence); - if (!r) - return 1; - nvchan->user_charge += bo->size; - - memcpy(nvdev->sa_map + r->start, nvbo->sysmem, bo->size); - - nvbo->offset = nvdev->sa.offset + r->start; - nvbo->flags = NOUVEAU_BO_GART; - return 0; -} - -static int -nouveau_bo_validate_bo(struct nouveau_channel *chan, struct nouveau_bo *bo, - struct nouveau_fence *fence, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - int ret; - - ret = nouveau_bo_set_status(bo, flags); - if (ret) { - nouveau_fence_flush(chan); - - ret = nouveau_bo_set_status(bo, flags); - if (ret) - return ret; - } - - if (nvbo->user) - nouveau_bo_upload(nvbo); - - nvbo->offset = nvbo->drm.offset; - if (nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) - nvbo->flags = NOUVEAU_BO_GART; - else - nvbo->flags = NOUVEAU_BO_VRAM; - - return 0; -} - -int -nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo, - uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_fence *fence = nouveau_pushbuf(chan->pushbuf)->fence; - int ret; - - assert(bo->map == NULL); - - if (nvbo->user) { - ret = nouveau_bo_validate_user(chan, bo, fence, flags); - if (ret) { - ret = nouveau_bo_validate_bo(chan, bo, fence, flags); - if (ret) - return ret; - } - } else { - ret = nouveau_bo_validate_bo(chan, bo, fence, flags); - if (ret) - return ret; - } - - if (flags & NOUVEAU_BO_WR) - nouveau_fence_ref(fence, &nvbo->wr_fence); - nouveau_fence_ref(fence, &nvbo->fence); - return 0; -} - diff --git a/src/gallium/winsys/dri/nouveau/nouveau_channel.c b/src/gallium/winsys/dri/nouveau/nouveau_channel.c deleted file mode 100644 index 3b4dcd1ecf..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_channel.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" - -int -nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, - uint32_t tt_ctxdma, struct nouveau_channel **chan) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct nouveau_channel_priv *nvchan; - int ret; - - if (!nvdev || !chan || *chan) - return -EINVAL; - - nvchan = calloc(1, sizeof(struct nouveau_channel_priv)); - if (!nvchan) - return -ENOMEM; - nvchan->base.device = dev; - - nvchan->drm.fb_ctxdma_handle = fb_ctxdma; - nvchan->drm.tt_ctxdma_handle = tt_ctxdma; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, - &nvchan->drm, sizeof(nvchan->drm)); - if (ret) { - free(nvchan); - return ret; - } - - nvchan->base.id = nvchan->drm.channel; - if (nouveau_grobj_ref(&nvchan->base, nvchan->drm.fb_ctxdma_handle, - &nvchan->base.vram) || - nouveau_grobj_ref(&nvchan->base, nvchan->drm.tt_ctxdma_handle, - &nvchan->base.gart)) { - nouveau_channel_free((void *)&nvchan); - return -EINVAL; - } - - ret = drmMap(nvdev->fd, nvchan->drm.ctrl, nvchan->drm.ctrl_size, - (void*)&nvchan->user); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - nvchan->put = &nvchan->user[0x40/4]; - nvchan->get = &nvchan->user[0x44/4]; - nvchan->ref_cnt = &nvchan->user[0x48/4]; - - ret = drmMap(nvdev->fd, nvchan->drm.notifier, nvchan->drm.notifier_size, - (drmAddressPtr)&nvchan->notifier_block); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - - ret = drmMap(nvdev->fd, nvchan->drm.cmdbuf, nvchan->drm.cmdbuf_size, - (void*)&nvchan->pushbuf); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - - ret = nouveau_grobj_alloc(&nvchan->base, 0x00000000, 0x0030, - &nvchan->base.nullobj); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - - nouveau_dma_channel_init(&nvchan->base); - nouveau_pushbuf_init(&nvchan->base); - - *chan = &nvchan->base; - return 0; -} - -void -nouveau_channel_free(struct nouveau_channel **chan) -{ - struct nouveau_channel_priv *nvchan; - struct nouveau_device_priv *nvdev; - struct drm_nouveau_channel_free cf; - - if (!chan || !*chan) - return; - nvchan = nouveau_channel(*chan); - *chan = NULL; - nvdev = nouveau_device(nvchan->base.device); - - FIRE_RING_CH(&nvchan->base); - - nouveau_grobj_free(&nvchan->base.vram); - nouveau_grobj_free(&nvchan->base.gart); - nouveau_grobj_free(&nvchan->base.nullobj); - - cf.channel = nvchan->drm.channel; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf)); - free(nvchan); -} - - diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c deleted file mode 100644 index 74413c408f..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ /dev/null @@ -1,346 +0,0 @@ -#include "main/glheader.h" -#include "glapi/glthread.h" -#include -#include "utils.h" - -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_context.h" -#include "pipe/p_screen.h" - -#include "nouveau_context.h" -#include "nouveau_dri.h" -#include "nouveau_local.h" -#include "nouveau_screen.h" -#include "nouveau_winsys_pipe.h" - -#ifdef DEBUG -static const struct dri_debug_control debug_control[] = { - { "bo", DEBUG_BO }, - { NULL, 0 } -}; -int __nouveau_debug = 0; -#endif - -static void -nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) -{ - nouveau_grobj_free(&nvc->NvCtxSurf2D); - nouveau_grobj_free(&nvc->NvImageBlit); - nouveau_grobj_free(&nvc->NvGdiRect); - nouveau_grobj_free(&nvc->NvM2MF); - nouveau_grobj_free(&nvc->Nv2D); - nouveau_grobj_free(&nvc->NvSwzSurf); - nouveau_grobj_free(&nvc->NvSIFM); - - nouveau_notifier_free(&nvc->sync_notifier); - - nouveau_channel_free(&nvc->channel); - - FREE(nvc); -} - -static struct nouveau_channel_context * -nouveau_channel_context_create(struct nouveau_device *dev) -{ - struct nouveau_channel_context *nvc; - int ret; - - nvc = CALLOC_STRUCT(nouveau_channel_context); - if (!nvc) - return NULL; - - if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002, - &nvc->channel))) { - NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); - nouveau_channel_context_destroy(nvc); - return NULL; - } - - nvc->next_handle = 0x80000000; - - if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, - &nvc->sync_notifier))) { - NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); - nouveau_channel_context_destroy(nvc); - return NULL; - } - - switch (dev->chipset & 0xf0) { - case 0x50: - case 0x80: - case 0x90: - ret = nouveau_surface_channel_create_nv50(nvc); - break; - default: - ret = nouveau_surface_channel_create_nv04(nvc); - break; - } - - if (ret) { - NOUVEAU_ERR("Error initialising surface objects: %d\n", ret); - nouveau_channel_context_destroy(nvc); - return NULL; - } - - return nvc; -} - -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 = CALLOC_STRUCT(nouveau_context); - struct pipe_context *pipe = NULL; - struct st_context *st_share = NULL; - struct nouveau_channel_context *nvc = NULL; - struct nouveau_device *dev = nv_screen->device; - int i; - - if (sharedContextPrivate) { - st_share = ((struct nouveau_context *)sharedContextPrivate)->st; - } - - switch (dev->chipset & 0xf0) { - case 0x10: - case 0x20: - /* NV10 */ - case 0x30: - /* NV30 */ - case 0x40: - case 0x60: - /* NV40 */ - case 0x50: - case 0x80: - case 0x90: - /* G80 */ - break; - default: - NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset); - return GL_FALSE; - } - - driContextPriv->driverPrivate = (void *)nv; - nv->nv_screen = nv_screen; - nv->dri_screen = driScrnPriv; - - { - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - nvdev->ctx = driContextPriv->hHWContext; - nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock; - } - - driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, - nv->dri_screen->myNum, "nouveau"); -#ifdef DEBUG - __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"), - debug_control); -#endif - - /*XXX: Hack up a fake region and buffer object for front buffer. - * This will go away with TTM, replaced with a simple reference - * of the front buffer handle passed to us by the DDX. - */ - { - struct pipe_surface *fb_surf; - struct nouveau_pipe_buffer *fb_buf; - struct nouveau_bo_priv *fb_bo; - - fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); - fb_bo->drm.offset = nv_screen->front_offset; - fb_bo->drm.flags = NOUVEAU_MEM_FB; - fb_bo->drm.size = nv_screen->front_pitch * - nv_screen->front_height; - fb_bo->refcount = 1; - fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; - fb_bo->base.offset = fb_bo->drm.offset; - fb_bo->base.handle = (unsigned long)fb_bo; - fb_bo->base.size = fb_bo->drm.size; - fb_bo->base.device = nv_screen->device; - - fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); - fb_buf->bo = &fb_bo->base; - - fb_surf = calloc(1, sizeof(struct pipe_surface)); - if (nv_screen->front_cpp == 2) - fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; - else - fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; - pf_get_block(fb_surf->format, &fb_surf->block); - fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; - fb_surf->height = nv_screen->front_height; - fb_surf->stride = fb_surf->width * fb_surf->block.size; - fb_surf->refcount = 1; - fb_surf->buffer = &fb_buf->base; - - nv->frontbuffer = fb_surf; - } - - /* Attempt to share a single channel between multiple contexts from - * a single process. - */ - nvc = nv_screen->nvc; - if (!nvc && st_share) { - struct nouveau_context *snv = st_share->pipe->priv; - if (snv) { - nvc = snv->nvc; - } - } - - /*XXX: temporary - disable multi-context/single-channel on pre-NV4x */ - switch (dev->chipset & 0xf0) { - case 0x40: - case 0x60: - /* NV40 class */ - case 0x50: - case 0x80: - case 0x90: - /* G80 class */ - break; - default: - nvc = NULL; - break; - } - - if (!nvc) { - nvc = nouveau_channel_context_create(dev); - if (!nvc) { - NOUVEAU_ERR("Failed initialising GPU context\n"); - return GL_FALSE; - } - nv_screen->nvc = nvc; - } - - nvc->refcount++; - nv->nvc = nvc; - - /* Find a free slot for a pipe context, allocate a new one if needed */ - nv->pctx_id = -1; - for (i = 0; i < nvc->nr_pctx; i++) { - if (nvc->pctx[i] == NULL) { - nv->pctx_id = i; - break; - } - } - - if (nv->pctx_id < 0) { - nv->pctx_id = nvc->nr_pctx++; - nvc->pctx = - realloc(nvc->pctx, - sizeof(struct pipe_context *) * nvc->nr_pctx); - } - - /* Create pipe */ - switch (dev->chipset & 0xf0) { - case 0x50: - case 0x80: - case 0x90: - if (nouveau_surface_init_nv50(nv)) - return GL_FALSE; - break; - default: - if (nouveau_surface_init_nv04(nv)) - return GL_FALSE; - break; - } - - if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { - struct pipe_screen *pscreen; - - pipe = nouveau_pipe_create(nv); - if (!pipe) - NOUVEAU_ERR("Couldn't create hw pipe\n"); - pscreen = nvc->pscreen; - - nv->cap.hw_vertex_buffer = - pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF); - nv->cap.hw_index_buffer = - pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF); - } - - if (!pipe) { - NOUVEAU_MSG("Using softpipe\n"); - pipe = nouveau_create_softpipe(nv); - if (!pipe) { - NOUVEAU_ERR("Error creating pipe, bailing\n"); - return GL_FALSE; - } - } - - pipe->priv = nv; - nv->st = st_create_context(pipe, glVis, st_share); - return GL_TRUE; -} - -void -nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) -{ - struct nouveau_context *nv = driContextPriv->driverPrivate; - struct nouveau_channel_context *nvc = nv->nvc; - - assert(nv); - - st_finish(nv->st); - st_destroy_context(nv->st); - - if (nv->pctx_id >= 0) { - nvc->pctx[nv->pctx_id] = NULL; - if (--nvc->refcount <= 0) { - nouveau_channel_context_destroy(nvc); - nv->nv_screen->nvc = NULL; - } - } - - 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/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h deleted file mode 100644 index 77e2147a2c..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef __NOUVEAU_CONTEXT_H__ -#define __NOUVEAU_CONTEXT_H__ - -#include "dri_util.h" -#include "xmlconfig.h" - -#include "nouveau/nouveau_winsys.h" -#include "nouveau_drmif.h" -#include "nouveau_dma.h" - -struct nouveau_framebuffer { - struct st_framebuffer *stfb; -}; - -struct nouveau_channel_context { - struct pipe_screen *pscreen; - int refcount; - - unsigned cur_pctx; - unsigned nr_pctx; - struct pipe_context **pctx; - - struct nouveau_channel *channel; - - struct nouveau_notifier *sync_notifier; - - /* Common */ - struct nouveau_grobj *NvM2MF; - /* NV04-NV40 */ - struct nouveau_grobj *NvCtxSurf2D; - struct nouveau_grobj *NvSwzSurf; - struct nouveau_grobj *NvImageBlit; - struct nouveau_grobj *NvGdiRect; - struct nouveau_grobj *NvSIFM; - /* G80 */ - struct nouveau_grobj *Nv2D; - - uint32_t next_handle; - uint32_t next_subchannel; - uint32_t next_sequence; -}; - -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; - GLboolean locked; - struct nouveau_screen *nv_screen; - struct pipe_surface *frontbuffer; - - struct { - int hw_vertex_buffer; - int hw_index_buffer; - } cap; - - /* Hardware context */ - struct nouveau_channel_context *nvc; - int pctx_id; - - /* pipe_surface accel */ - struct pipe_surface *surf_src, *surf_dst; - unsigned surf_src_offset, surf_dst_offset; - int (*surface_copy_prep)(struct nouveau_context *, - struct pipe_surface *dst, - struct pipe_surface *src); - void (*surface_copy)(struct nouveau_context *, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h); - void (*surface_copy_done)(struct nouveau_context *); - int (*surface_fill)(struct nouveau_context *, struct pipe_surface *, - unsigned, unsigned, unsigned, unsigned, unsigned); -}; - -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 *); - -#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 - -extern void LOCK_HARDWARE(struct nouveau_context *); -extern void UNLOCK_HARDWARE(struct nouveau_context *); - -extern int -nouveau_surface_channel_create_nv04(struct nouveau_channel_context *); -extern int -nouveau_surface_channel_create_nv50(struct nouveau_channel_context *); -extern int nouveau_surface_init_nv04(struct nouveau_context *); -extern int nouveau_surface_init_nv50(struct nouveau_context *); - -extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int); -extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *); - -#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_device.c b/src/gallium/winsys/dri/nouveau/nouveau_device.c deleted file mode 100644 index 0b452fcd02..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_device.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include - -#include "nouveau_drmif.h" - -int -nouveau_device_open_existing(struct nouveau_device **dev, int close, - int fd, drm_context_t ctx) -{ - struct nouveau_device_priv *nvdev; - int ret; - - if (!dev || *dev) - return -EINVAL; - - nvdev = calloc(1, sizeof(*nvdev)); - if (!nvdev) - return -ENOMEM; - nvdev->fd = fd; - nvdev->ctx = ctx; - nvdev->needs_close = close; - - drmCommandNone(nvdev->fd, DRM_NOUVEAU_CARD_INIT); - - if ((ret = nouveau_bo_init(&nvdev->base))) { - nouveau_device_close((void *)&nvdev); - return ret; - } - - { - uint64_t value; - - ret = nouveau_device_get_param(&nvdev->base, - NOUVEAU_GETPARAM_CHIPSET_ID, - &value); - if (ret) { - nouveau_device_close((void *)&nvdev); - return ret; - } - nvdev->base.chipset = value; - } - - *dev = &nvdev->base; - return 0; -} - -int -nouveau_device_open(struct nouveau_device **dev, const char *busid) -{ - drm_context_t ctx; - int fd, ret; - - if (!dev || *dev) - return -EINVAL; - - fd = drmOpen("nouveau", busid); - if (fd < 0) - return -EINVAL; - - ret = drmCreateContext(fd, &ctx); - if (ret) { - drmClose(fd); - return ret; - } - - ret = nouveau_device_open_existing(dev, 1, fd, ctx); - if (ret) { - drmDestroyContext(fd, ctx); - drmClose(fd); - return ret; - } - - return 0; -} - -void -nouveau_device_close(struct nouveau_device **dev) -{ - struct nouveau_device_priv *nvdev; - - if (dev || !*dev) - return; - nvdev = nouveau_device(*dev); - *dev = NULL; - - nouveau_bo_takedown(&nvdev->base); - - if (nvdev->needs_close) { - drmDestroyContext(nvdev->fd, nvdev->ctx); - drmClose(nvdev->fd); - } - free(nvdev); -} - -int -nouveau_device_get_param(struct nouveau_device *dev, - uint64_t param, uint64_t *value) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct drm_nouveau_getparam g; - int ret; - - if (!nvdev || !value) - return -EINVAL; - - g.param = param; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GETPARAM, - &g, sizeof(g)); - if (ret) - return ret; - - *value = g.value; - return 0; -} - -int -nouveau_device_set_param(struct nouveau_device *dev, - uint64_t param, uint64_t value) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct drm_nouveau_setparam s; - int ret; - - if (!nvdev) - return -EINVAL; - - s.param = param; - s.value = value; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_SETPARAM, - &s, sizeof(s)); - if (ret) - return ret; - - return 0; -} - diff --git a/src/gallium/winsys/dri/nouveau/nouveau_dma.c b/src/gallium/winsys/dri/nouveau/nouveau_dma.c deleted file mode 100644 index f8a8ba04f6..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_dma.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" -#include "nouveau_local.h" - -static inline uint32_t -READ_GET(struct nouveau_channel_priv *nvchan) -{ - return *nvchan->get; -} - -static inline void -WRITE_PUT(struct nouveau_channel_priv *nvchan, uint32_t val) -{ - uint32_t put = ((val << 2) + nvchan->dma->base); - volatile int dum; - - NOUVEAU_DMA_BARRIER; - dum = READ_GET(nvchan); - - *nvchan->put = put; - nvchan->dma->put = val; -#ifdef NOUVEAU_DMA_TRACE - NOUVEAU_MSG("WRITE_PUT %d/0x%08x\n", nvchan->drm.channel, put); -#endif - - NOUVEAU_DMA_BARRIER; -} - -static inline int -LOCAL_GET(struct nouveau_dma_priv *dma, uint32_t *val) -{ - uint32_t get = *val; - - if (get >= dma->base && get <= (dma->base + (dma->max << 2))) { - *val = (get - dma->base) >> 2; - return 1; - } - - return 0; -} - -void -nouveau_dma_channel_init(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - int i; - - nvchan->dma = &nvchan->dma_master; - nvchan->dma->base = nvchan->drm.put_base; - nvchan->dma->cur = nvchan->dma->put = 0; - nvchan->dma->max = (nvchan->drm.cmdbuf_size >> 2) - 2; - nvchan->dma->free = nvchan->dma->max - nvchan->dma->cur; - - RING_SPACE_CH(chan, RING_SKIPS); - for (i = 0; i < RING_SKIPS; i++) - OUT_RING_CH(chan, 0); -} - -#define CHECK_TIMEOUT() do { \ - if ((NOUVEAU_TIME_MSEC() - t_start) > NOUVEAU_DMA_TIMEOUT) \ - return - EBUSY; \ -} while(0) - -int -nouveau_dma_wait(struct nouveau_channel *chan, int size) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - uint32_t get, t_start; - - FIRE_RING_CH(chan); - - t_start = NOUVEAU_TIME_MSEC(); - while (dma->free < size) { - CHECK_TIMEOUT(); - - get = READ_GET(nvchan); - if (!LOCAL_GET(dma, &get)) - continue; - - if (dma->put >= get) { - dma->free = dma->max - dma->cur; - - if (dma->free < size) { -#ifdef NOUVEAU_DMA_DEBUG - dma->push_free = 1; -#endif - OUT_RING_CH(chan, 0x20000000 | dma->base); - if (get <= RING_SKIPS) { - /*corner case - will be idle*/ - if (dma->put <= RING_SKIPS) - WRITE_PUT(nvchan, - RING_SKIPS + 1); - - do { - CHECK_TIMEOUT(); - get = READ_GET(nvchan); - if (!LOCAL_GET(dma, &get)) - get = 0; - } while (get <= RING_SKIPS); - } - - WRITE_PUT(nvchan, RING_SKIPS); - dma->cur = dma->put = RING_SKIPS; - dma->free = get - (RING_SKIPS + 1); - } - } else { - dma->free = get - dma->cur - 1; - } - } - - return 0; -} - -#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF -static void -nouveau_dma_parse_pushbuf(struct nouveau_channel *chan, int get, int put) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - unsigned mthd_count = 0; - - while (get != put) { - uint32_t gpuget = (get << 2) + nvchan->drm.put_base; - uint32_t data; - - if (get < 0 || get >= nvchan->drm.cmdbuf_size) { - NOUVEAU_ERR("DMA_PT 0x%08x\n", gpuget); - assert(0); - } - data = nvchan->pushbuf[get++]; - - if (mthd_count) { - NOUVEAU_MSG("0x%08x 0x%08x\n", gpuget, data); - mthd_count--; - continue; - } - - switch (data & 0x60000000) { - case 0x00000000: - mthd_count = (data >> 18) & 0x7ff; - NOUVEAU_MSG("0x%08x 0x%08x MTHD " - "Sc %d Mthd 0x%04x Size %d\n", - gpuget, data, (data>>13) & 7, data & 0x1ffc, - mthd_count); - break; - case 0x20000000: - get = (data & 0x1ffffffc) >> 2; - NOUVEAU_MSG("0x%08x 0x%08x JUMP 0x%08x\n", - gpuget, data, data & 0x1ffffffc); - continue; - case 0x40000000: - mthd_count = (data >> 18) & 0x7ff; - NOUVEAU_MSG("0x%08x 0x%08x NINC " - "Sc %d Mthd 0x%04x Size %d\n", - gpuget, data, (data>>13) & 7, data & 0x1ffc, - mthd_count); - break; - case 0x60000000: - /* DMA_OPCODE_CALL apparently, doesn't seem to work on - * my NV40 at least.. - */ - /* fall-through */ - default: - NOUVEAU_MSG("DMA_PUSHER 0x%08x 0x%08x\n", - gpuget, data); - assert(0); - } - } -} -#endif - -void -nouveau_dma_kickoff(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - - if (dma->cur == dma->put) - return; - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free) { - NOUVEAU_ERR("Packet incomplete: %d left\n", dma->push_free); - return; - } -#endif - -#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF - nouveau_dma_parse_pushbuf(chan, dma->put, dma->cur); -#endif - - WRITE_PUT(nvchan, dma->cur); -} diff --git a/src/gallium/winsys/dri/nouveau/nouveau_dma.h b/src/gallium/winsys/dri/nouveau/nouveau_dma.h deleted file mode 100644 index cfa6d26e82..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_dma.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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. - */ - -#ifndef __NOUVEAU_DMA_H__ -#define __NOUVEAU_DMA_H__ - -#include -#include "nouveau_drmif.h" -#include "nouveau_local.h" - -#define RING_SKIPS 8 - -extern int nouveau_dma_wait(struct nouveau_channel *chan, int size); -extern void nouveau_dma_subc_bind(struct nouveau_grobj *); -extern void nouveau_dma_channel_init(struct nouveau_channel *); -extern void nouveau_dma_kickoff(struct nouveau_channel *); - -#ifdef NOUVEAU_DMA_DEBUG -static char faulty[1024]; -#endif - -static inline void -nouveau_dma_out(struct nouveau_channel *chan, uint32_t data) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free == 0) { - NOUVEAU_ERR("No space left in packet at %s\n", faulty); - return; - } - dma->push_free--; -#endif -#ifdef NOUVEAU_DMA_TRACE - { - uint32_t offset = (dma->cur << 2) + dma->base; - NOUVEAU_MSG("\tOUT_RING %d/0x%08x -> 0x%08x\n", - nvchan->drm.channel, offset, data); - } -#endif - nvchan->pushbuf[dma->cur + (dma->base - nvchan->drm.put_base)/4] = data; - dma->cur++; -} - -static inline void -nouveau_dma_outp(struct nouveau_channel *chan, uint32_t *ptr, int size) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - (void)dma; - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free < size) { - NOUVEAU_ERR("Packet too small. Free=%d, Need=%d\n", - dma->push_free, size); - return; - } -#endif -#ifdef NOUVEAU_DMA_TRACE - while (size--) { - nouveau_dma_out(chan, *ptr); - ptr++; - } -#else - memcpy(&nvchan->pushbuf[dma->cur], ptr, size << 2); -#ifdef NOUVEAU_DMA_DEBUG - dma->push_free -= size; -#endif - dma->cur += size; -#endif -} - -static inline void -nouveau_dma_space(struct nouveau_channel *chan, int size) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - - if (dma->free < size) { - if (nouveau_dma_wait(chan, size) && chan->hang_notify) - chan->hang_notify(chan); - } - dma->free -= size; -#ifdef NOUVEAU_DMA_DEBUG - dma->push_free = size; -#endif -} - -static inline void -nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj, - int method, int size, const char* file, int line) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - (void)dma; - -#ifdef NOUVEAU_DMA_TRACE - NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", nvchan->drm.channel, - grobj->handle, grobj->subc, method, size); -#endif - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free) { - NOUVEAU_ERR("Previous packet incomplete: %d left at %s\n", - dma->push_free, faulty); - return; - } - sprintf(faulty,"%s:%d",file,line); -#endif - - nouveau_dma_space(chan, (size + 1)); - nouveau_dma_out(chan, (size << 18) | (grobj->subc << 13) | method); -} - -#define RING_SPACE_CH(ch,sz) nouveau_dma_space((ch), (sz)) -#define BEGIN_RING_CH(ch,gr,m,sz) nouveau_dma_begin((ch), (gr), (m), (sz), __FUNCTION__, __LINE__ ) -#define OUT_RING_CH(ch, data) nouveau_dma_out((ch), (data)) -#define OUT_RINGp_CH(ch,ptr,dwords) nouveau_dma_outp((ch), (void*)(ptr), \ - (dwords)) -#define FIRE_RING_CH(ch) nouveau_dma_kickoff((ch)) -#define WAIT_RING_CH(ch,sz) nouveau_dma_wait((ch), (sz)) - -#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_dri.h b/src/gallium/winsys/dri/nouveau/nouveau_dri.h deleted file mode 100644 index 1207c2d609..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_dri.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _NOUVEAU_DRI_ -#define _NOUVEAU_DRI_ - -#include "xf86drm.h" -#include "drm.h" -#include "nouveau_drm.h" - -struct nouveau_dri { - uint32_t device_id; /**< \brief PCI device ID */ - uint32_t width; /**< \brief width in pixels of display */ - uint32_t height; /**< \brief height in scanlines of display */ - uint32_t depth; /**< \brief depth of display (8, 15, 16, 24) */ - uint32_t bpp; /**< \brief bit depth of display (8, 16, 24, 32) */ - - uint32_t bus_type; /**< \brief ths bus type */ - uint32_t bus_mode; /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */ - - uint32_t front_offset; /**< \brief front buffer offset */ - uint32_t front_pitch; /**< \brief front buffer pitch */ - uint32_t back_offset; /**< \brief private back buffer offset */ - uint32_t back_pitch; /**< \brief private back buffer pitch */ - uint32_t depth_offset; /**< \brief private depth buffer offset */ - uint32_t depth_pitch; /**< \brief private depth buffer pitch */ - -}; - -#endif - diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h deleted file mode 100644 index dcd6a5eb0a..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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. - */ - -#ifndef __NOUVEAU_DRMIF_H__ -#define __NOUVEAU_DRMIF_H__ - -#include -#include -#include - -#include "nouveau/nouveau_device.h" -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_grobj.h" -#include "nouveau/nouveau_notifier.h" -#include "nouveau/nouveau_bo.h" -#include "nouveau/nouveau_resource.h" -#include "nouveau/nouveau_pushbuf.h" - -struct nouveau_device_priv { - struct nouveau_device base; - - int fd; - drm_context_t ctx; - drmLock *lock; - int needs_close; - - struct drm_nouveau_mem_alloc sa; - void *sa_map; - struct nouveau_resource *sa_heap; -}; -#define nouveau_device(n) ((struct nouveau_device_priv *)(n)) - -extern int -nouveau_device_open_existing(struct nouveau_device **, int close, - int fd, drm_context_t ctx); - -extern int -nouveau_device_open(struct nouveau_device **, const char *busid); - -extern void -nouveau_device_close(struct nouveau_device **); - -extern int -nouveau_device_get_param(struct nouveau_device *, uint64_t param, uint64_t *v); - -extern int -nouveau_device_set_param(struct nouveau_device *, uint64_t param, uint64_t val); - -struct nouveau_fence { - struct nouveau_channel *channel; -}; - -struct nouveau_fence_cb { - struct nouveau_fence_cb *next; - void (*func)(void *); - void *priv; -}; - -struct nouveau_fence_priv { - struct nouveau_fence base; - int refcount; - - struct nouveau_fence *next; - struct nouveau_fence_cb *signal_cb; - - uint32_t sequence; - int emitted; - int signalled; -}; -#define nouveau_fence(n) ((struct nouveau_fence_priv *)(n)) - -extern int -nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **); - -extern int -nouveau_fence_ref(struct nouveau_fence *, struct nouveau_fence **); - -extern int -nouveau_fence_signal_cb(struct nouveau_fence *, void (*)(void *), void *); - -extern void -nouveau_fence_emit(struct nouveau_fence *); - -extern int -nouveau_fence_wait(struct nouveau_fence **); - -extern void -nouveau_fence_flush(struct nouveau_channel *); - -struct nouveau_pushbuf_reloc { - struct nouveau_pushbuf_bo *pbbo; - uint32_t *ptr; - uint32_t flags; - uint32_t data; - uint32_t vor; - uint32_t tor; -}; - -struct nouveau_pushbuf_bo { - struct nouveau_channel *channel; - struct nouveau_bo *bo; - unsigned flags; - unsigned handled; -}; - -#define NOUVEAU_PUSHBUF_MAX_BUFFERS 1024 -#define NOUVEAU_PUSHBUF_MAX_RELOCS 1024 -struct nouveau_pushbuf_priv { - struct nouveau_pushbuf base; - - struct nouveau_fence *fence; - - unsigned nop_jump; - unsigned start; - unsigned size; - - struct nouveau_pushbuf_bo *buffers; - unsigned nr_buffers; - struct nouveau_pushbuf_reloc *relocs; - unsigned nr_relocs; -}; -#define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n)) - -#define pbbo_to_ptr(o) ((uint64_t)(unsigned long)(o)) -#define ptr_to_pbbo(h) ((struct nouveau_pushbuf_bo *)(unsigned long)(h)) -#define pbrel_to_ptr(o) ((uint64_t)(unsigned long)(o)) -#define ptr_to_pbrel(h) ((struct nouveau_pushbuf_reloc *)(unsigned long)(h)) -#define bo_to_ptr(o) ((uint64_t)(unsigned long)(o)) -#define ptr_to_bo(h) ((struct nouveau_bo_priv *)(unsigned long)(h)) - -extern int -nouveau_pushbuf_init(struct nouveau_channel *); - -extern int -nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); - -extern int -nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr, - struct nouveau_bo *, uint32_t data, uint32_t flags, - uint32_t vor, uint32_t tor); - -struct nouveau_dma_priv { - uint32_t base; - uint32_t max; - uint32_t cur; - uint32_t put; - uint32_t free; - - int push_free; -} dma; - -struct nouveau_channel_priv { - struct nouveau_channel base; - - struct drm_nouveau_channel_alloc drm; - - uint32_t *pushbuf; - void *notifier_block; - - volatile uint32_t *user; - volatile uint32_t *put; - volatile uint32_t *get; - volatile uint32_t *ref_cnt; - - struct nouveau_dma_priv dma_master; - struct nouveau_dma_priv dma_bufmgr; - struct nouveau_dma_priv *dma; - - struct nouveau_fence *fence_head; - struct nouveau_fence *fence_tail; - uint32_t fence_sequence; - - struct nouveau_pushbuf_priv pb; - - unsigned user_charge; -}; -#define nouveau_channel(n) ((struct nouveau_channel_priv *)(n)) - -extern int -nouveau_channel_alloc(struct nouveau_device *, uint32_t fb, uint32_t tt, - struct nouveau_channel **); - -extern void -nouveau_channel_free(struct nouveau_channel **); - -struct nouveau_grobj_priv { - struct nouveau_grobj base; -}; -#define nouveau_grobj(n) ((struct nouveau_grobj_priv *)(n)) - -extern int nouveau_grobj_alloc(struct nouveau_channel *, uint32_t handle, - int class, struct nouveau_grobj **); -extern int nouveau_grobj_ref(struct nouveau_channel *, uint32_t handle, - struct nouveau_grobj **); -extern void nouveau_grobj_free(struct nouveau_grobj **); - - -struct nouveau_notifier_priv { - struct nouveau_notifier base; - - struct drm_nouveau_notifierobj_alloc drm; - volatile void *map; -}; -#define nouveau_notifier(n) ((struct nouveau_notifier_priv *)(n)) - -extern int -nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, int count, - struct nouveau_notifier **); - -extern void -nouveau_notifier_free(struct nouveau_notifier **); - -extern void -nouveau_notifier_reset(struct nouveau_notifier *, int id); - -extern uint32_t -nouveau_notifier_status(struct nouveau_notifier *, int id); - -extern uint32_t -nouveau_notifier_return_val(struct nouveau_notifier *, int id); - -extern int -nouveau_notifier_wait_status(struct nouveau_notifier *, int id, int status, - int timeout); - -struct nouveau_bo_priv { - struct nouveau_bo base; - - struct nouveau_pushbuf_bo *pending; - struct nouveau_fence *fence; - struct nouveau_fence *wr_fence; - - struct drm_nouveau_mem_alloc drm; - void *map; - - void *sysmem; - int user; - - int refcount; - - uint64_t offset; - uint64_t flags; - int tiled; -}; -#define nouveau_bo(n) ((struct nouveau_bo_priv *)(n)) - -extern int -nouveau_bo_init(struct nouveau_device *); - -extern void -nouveau_bo_takedown(struct nouveau_device *); - -extern int -nouveau_bo_new(struct nouveau_device *, uint32_t flags, int align, int size, - struct nouveau_bo **); - -extern int -nouveau_bo_user(struct nouveau_device *, void *ptr, int size, - struct nouveau_bo **); - -extern int -nouveau_bo_ref(struct nouveau_device *, uint64_t handle, struct nouveau_bo **); - -extern int -nouveau_bo_set_status(struct nouveau_bo *, uint32_t flags); - -extern void -nouveau_bo_del(struct nouveau_bo **); - -extern int -nouveau_bo_map(struct nouveau_bo *, uint32_t flags); - -extern void -nouveau_bo_unmap(struct nouveau_bo *); - -extern int -nouveau_bo_validate(struct nouveau_channel *, struct nouveau_bo *, - uint32_t flags); - -extern int -nouveau_resource_init(struct nouveau_resource **heap, unsigned start, - unsigned size); - -extern int -nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, - struct nouveau_resource **); - -extern void -nouveau_resource_free(struct nouveau_resource **); - -#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_fence.c b/src/gallium/winsys/dri/nouveau/nouveau_fence.c deleted file mode 100644 index e7b0b4ff07..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_fence.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" -#include "nouveau_local.h" - -static void -nouveau_fence_del_unsignalled(struct nouveau_fence *fence) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); - struct nouveau_fence *le; - - if (nvchan->fence_head == fence) { - nvchan->fence_head = nouveau_fence(fence)->next; - if (nvchan->fence_head == NULL) - nvchan->fence_tail = NULL; - return; - } - - le = nvchan->fence_head; - while (le && nouveau_fence(le)->next != fence) - le = nouveau_fence(le)->next; - assert(le && nouveau_fence(le)->next == fence); - nouveau_fence(le)->next = nouveau_fence(fence)->next; - if (nvchan->fence_tail == fence) - nvchan->fence_tail = le; -} - -static void -nouveau_fence_del(struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!fence || !*fence) - return; - nvfence = nouveau_fence(*fence); - *fence = NULL; - - if (--nvfence->refcount) - return; - - if (nvfence->emitted && !nvfence->signalled) { - if (nvfence->signal_cb) { - nvfence->refcount++; - nouveau_fence_wait((void *)&nvfence); - return; - } - - nouveau_fence_del_unsignalled(&nvfence->base); - } - free(nvfence); -} - -int -nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!chan || !fence || *fence) - return -EINVAL; - - nvfence = calloc(1, sizeof(struct nouveau_fence_priv)); - if (!nvfence) - return -ENOMEM; - nvfence->base.channel = chan; - nvfence->refcount = 1; - - *fence = &nvfence->base; - return 0; -} - -int -nouveau_fence_ref(struct nouveau_fence *ref, struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!fence) - return -EINVAL; - - if (*fence) { - nouveau_fence_del(fence); - *fence = NULL; - } - - if (ref) { - nvfence = nouveau_fence(ref); - nvfence->refcount++; - *fence = &nvfence->base; - } - - return 0; -} - -int -nouveau_fence_signal_cb(struct nouveau_fence *fence, void (*func)(void *), - void *priv) -{ - struct nouveau_fence_priv *nvfence = nouveau_fence(fence); - struct nouveau_fence_cb *cb; - - if (!nvfence || !func) - return -EINVAL; - - cb = malloc(sizeof(struct nouveau_fence_cb)); - if (!cb) - return -ENOMEM; - - cb->func = func; - cb->priv = priv; - cb->next = nvfence->signal_cb; - nvfence->signal_cb = cb; - return 0; -} - -void -nouveau_fence_emit(struct nouveau_fence *fence) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); - struct nouveau_fence_priv *nvfence = nouveau_fence(fence); - - nvfence->emitted = 1; - nvfence->sequence = ++nvchan->fence_sequence; - if (nvfence->sequence == 0xffffffff) - NOUVEAU_ERR("AII wrap unhandled\n"); - - /*XXX: assumes subc 0 is populated */ - RING_SPACE_CH(fence->channel, 2); - OUT_RING_CH (fence->channel, 0x00040050); - OUT_RING_CH (fence->channel, nvfence->sequence); - - if (nvchan->fence_tail) { - nouveau_fence(nvchan->fence_tail)->next = fence; - } else { - nvchan->fence_head = fence; - } - nvchan->fence_tail = fence; -} - -void -nouveau_fence_flush(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - uint32_t sequence = *nvchan->ref_cnt; - - while (nvchan->fence_head) { - struct nouveau_fence_priv *nvfence; - - nvfence = nouveau_fence(nvchan->fence_head); - if (nvfence->sequence > sequence) - break; - nouveau_fence_del_unsignalled(&nvfence->base); - nvfence->signalled = 1; - - if (nvfence->signal_cb) { - struct nouveau_fence *fence = NULL; - - nouveau_fence_ref(&nvfence->base, &fence); - - while (nvfence->signal_cb) { - struct nouveau_fence_cb *cb; - - cb = nvfence->signal_cb; - nvfence->signal_cb = cb->next; - cb->func(cb->priv); - free(cb); - } - - nouveau_fence_ref(NULL, &fence); - } - } -} - -int -nouveau_fence_wait(struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!fence || !*fence) - return -EINVAL; - nvfence = nouveau_fence(*fence); - - if (nvfence->emitted) { - while (!nvfence->signalled) - nouveau_fence_flush(nvfence->base.channel); - } - nouveau_fence_ref(NULL, fence); - - return 0; -} - diff --git a/src/gallium/winsys/dri/nouveau/nouveau_grobj.c b/src/gallium/winsys/dri/nouveau/nouveau_grobj.c deleted file mode 100644 index 51523897d5..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_grobj.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include - -#include "nouveau_drmif.h" - -int -nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle, - int class, struct nouveau_grobj **grobj) -{ - struct nouveau_device_priv *nvdev = nouveau_device(chan->device); - struct nouveau_grobj_priv *nvgrobj; - struct drm_nouveau_grobj_alloc g; - int ret; - - if (!nvdev || !grobj || *grobj) - return -EINVAL; - - nvgrobj = calloc(1, sizeof(*nvgrobj)); - if (!nvgrobj) - return -ENOMEM; - nvgrobj->base.channel = chan; - nvgrobj->base.handle = handle; - nvgrobj->base.grclass = class; - - g.channel = chan->id; - g.handle = handle; - g.class = class; - ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GROBJ_ALLOC, - &g, sizeof(g)); - if (ret) { - nouveau_grobj_free((void *)&nvgrobj); - return ret; - } - - *grobj = &nvgrobj->base; - return 0; -} - -int -nouveau_grobj_ref(struct nouveau_channel *chan, uint32_t handle, - struct nouveau_grobj **grobj) -{ - struct nouveau_grobj_priv *nvgrobj; - - if (!chan || !grobj || *grobj) - return -EINVAL; - - nvgrobj = calloc(1, sizeof(struct nouveau_grobj_priv)); - if (!nvgrobj) - return -ENOMEM; - nvgrobj->base.channel = chan; - nvgrobj->base.handle = handle; - nvgrobj->base.grclass = 0; - - *grobj = &nvgrobj->base; - return 0; -} - -void -nouveau_grobj_free(struct nouveau_grobj **grobj) -{ - struct nouveau_device_priv *nvdev; - struct nouveau_channel_priv *chan; - struct nouveau_grobj_priv *nvgrobj; - - if (!grobj || !*grobj) - return; - nvgrobj = nouveau_grobj(*grobj); - *grobj = NULL; - - - chan = nouveau_channel(nvgrobj->base.channel); - nvdev = nouveau_device(chan->base.device); - - if (nvgrobj->base.grclass) { - struct drm_nouveau_gpuobj_free f; - - f.channel = chan->drm.channel; - f.handle = nvgrobj->base.handle; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, - &f, sizeof(f)); - } - free(nvgrobj); -} - diff --git a/src/gallium/winsys/dri/nouveau/nouveau_local.h b/src/gallium/winsys/dri/nouveau/nouveau_local.h deleted file mode 100644 index e878a40803..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_local.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef __NOUVEAU_LOCAL_H__ -#define __NOUVEAU_LOCAL_H__ - -#include "pipe/p_compiler.h" -#include "nouveau_winsys_pipe.h" -#include - -struct pipe_buffer; - -/* Debug output */ -#define NOUVEAU_MSG(fmt, args...) do { \ - fprintf(stdout, "nouveau: "fmt, ##args); \ - fflush(stdout); \ -} while(0) - -#define NOUVEAU_ERR(fmt, args...) do { \ - fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); \ - fflush(stderr); \ -} while(0) - -#define NOUVEAU_TIME_MSEC() 0 - -/* User FIFO control */ -//#define NOUVEAU_DMA_TRACE -//#define NOUVEAU_DMA_DEBUG -//#define NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF -#define NOUVEAU_DMA_BARRIER -#define NOUVEAU_DMA_TIMEOUT 2000 - -/* Push buffer access macros */ -static INLINE void -OUT_RING(struct nouveau_channel *chan, unsigned data) -{ - *(chan->pushbuf->cur++) = (data); -} - -static INLINE void -OUT_RINGp(struct nouveau_channel *chan, uint32_t *data, unsigned size) -{ - memcpy(chan->pushbuf->cur, data, size * 4); - chan->pushbuf->cur += size; -} - -static INLINE void -OUT_RINGf(struct nouveau_channel *chan, float f) -{ - union { uint32_t i; float f; } c; - c.f = f; - OUT_RING(chan, c.i); -} - -static INLINE void -BEGIN_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, - unsigned mthd, unsigned size) -{ - if (chan->pushbuf->remaining < (size + 1)) - nouveau_pushbuf_flush(chan, (size + 1)); - OUT_RING(chan, (gr->subc << 13) | (size << 18) | mthd); - chan->pushbuf->remaining -= (size + 1); -} - -static INLINE void -FIRE_RING(struct nouveau_channel *chan) -{ - nouveau_pushbuf_flush(chan, 0); -} - -static INLINE void -BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc) -{ - gr->subc = subc; - BEGIN_RING(chan, gr, 0x0000, 1); - OUT_RING (chan, gr->handle); -} - -static INLINE void -OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned data, unsigned flags, unsigned vor, unsigned tor) -{ - nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, - data, flags, vor, tor); -} - -/* Raw data + flags depending on FB/TT buffer */ -static INLINE void -OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned data, unsigned flags, unsigned vor, unsigned tor) -{ - OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor); -} - -/* FB/TT object handle */ -static INLINE void -OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned flags) -{ - OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR, - chan->vram->handle, chan->gart->handle); -} - -/* Low 32-bits of offset */ -static INLINE void -OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned delta, unsigned flags) -{ - OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0); -} - -/* High 32-bits of offset */ -static INLINE void -OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned delta, unsigned flags) -{ - OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); -} - -#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_lock.c b/src/gallium/winsys/dri/nouveau/nouveau_lock.c deleted file mode 100644 index 9adb9ac854..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_lock.c +++ /dev/null @@ -1,94 +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 "main/glheader.h" -#include "glapi/glthread.h" -#include - -#include "nouveau_context.h" -#include "nouveau_screen.h" - -_glthread_DECLARE_STATIC_MUTEX( lockMutex ); - -static void -nouveau_contended_lock(struct nouveau_context *nv, GLuint flags) -{ - __DRIdrawablePrivate *dPriv = nv->dri_drawable; - __DRIscreenPrivate *sPriv = nv->dri_screen; - struct nouveau_screen *nv_screen = nv->nv_screen; - struct nouveau_device *dev = nv_screen->device; - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - drmGetLock(nvdev->fd, nvdev->ctx, flags); - - /* 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); -} - -/* Lock the hardware and validate our state. - */ -void -LOCK_HARDWARE(struct nouveau_context *nv) -{ - struct nouveau_screen *nv_screen = nv->nv_screen; - struct nouveau_device *dev = nv_screen->device; - struct nouveau_device_priv *nvdev = nouveau_device(dev); - char __ret=0; - - _glthread_LOCK_MUTEX(lockMutex); - assert(!nv->locked); - - DRM_CAS(nvdev->lock, nvdev->ctx, - (DRM_LOCK_HELD | nvdev->ctx), __ret); - - if (__ret) - nouveau_contended_lock(nv, 0); - nv->locked = GL_TRUE; -} - - - /* Unlock the hardware using the global current context - */ -void -UNLOCK_HARDWARE(struct nouveau_context *nv) -{ - struct nouveau_screen *nv_screen = nv->nv_screen; - struct nouveau_device *dev = nv_screen->device; - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - assert(nv->locked); - nv->locked = GL_FALSE; - - DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx); - - _glthread_UNLOCK_MUTEX(lockMutex); -} diff --git a/src/gallium/winsys/dri/nouveau/nouveau_notifier.c b/src/gallium/winsys/dri/nouveau/nouveau_notifier.c deleted file mode 100644 index 01e8f38440..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_notifier.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include - -#include "nouveau_drmif.h" -#include "nouveau_local.h" - -#define NOTIFIER(__v) \ - struct nouveau_notifier_priv *nvnotify = nouveau_notifier(notifier); \ - volatile uint32_t *__v = (void*)nvnotify->map + (id * 32) - -int -nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, - int count, struct nouveau_notifier **notifier) -{ - struct nouveau_notifier_priv *nvnotify; - int ret; - - if (!chan || !notifier || *notifier) - return -EINVAL; - - nvnotify = calloc(1, sizeof(struct nouveau_notifier_priv)); - if (!nvnotify) - return -ENOMEM; - nvnotify->base.channel = chan; - nvnotify->base.handle = handle; - - nvnotify->drm.channel = chan->id; - nvnotify->drm.handle = handle; - nvnotify->drm.count = count; - if ((ret = drmCommandWriteRead(nouveau_device(chan->device)->fd, - DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, - &nvnotify->drm, - sizeof(nvnotify->drm)))) { - nouveau_notifier_free((void *)&nvnotify); - return ret; - } - - nvnotify->map = (void *)nouveau_channel(chan)->notifier_block + - nvnotify->drm.offset; - *notifier = &nvnotify->base; - return 0; -} - -void -nouveau_notifier_free(struct nouveau_notifier **notifier) -{ - - struct nouveau_notifier_priv *nvnotify; - struct nouveau_channel_priv *nvchan; - struct nouveau_device_priv *nvdev; - struct drm_nouveau_gpuobj_free f; - - if (!notifier || !*notifier) - return; - nvnotify = nouveau_notifier(*notifier); - *notifier = NULL; - - nvchan = nouveau_channel(nvnotify->base.channel); - nvdev = nouveau_device(nvchan->base.device); - - f.channel = nvchan->drm.channel; - f.handle = nvnotify->base.handle; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, &f, sizeof(f)); - free(nvnotify); -} - -void -nouveau_notifier_reset(struct nouveau_notifier *notifier, int id) -{ - NOTIFIER(n); - - n[NV_NOTIFY_TIME_0 /4] = 0x00000000; - n[NV_NOTIFY_TIME_1 /4] = 0x00000000; - n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000; - n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS << - NV_NOTIFY_STATE_STATUS_SHIFT); -} - -uint32_t -nouveau_notifier_status(struct nouveau_notifier *notifier, int id) -{ - NOTIFIER(n); - - return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; -} - -uint32_t -nouveau_notifier_return_val(struct nouveau_notifier *notifier, int id) -{ - NOTIFIER(n); - - return n[NV_NOTIFY_RETURN_VALUE/4]; -} - -int -nouveau_notifier_wait_status(struct nouveau_notifier *notifier, int id, - int status, int timeout) -{ - NOTIFIER(n); - uint32_t time = 0, t_start = NOUVEAU_TIME_MSEC(); - - while (time <= timeout) { - uint32_t v; - - v = n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; - if (v == status) - return 0; - - if (timeout) - time = NOUVEAU_TIME_MSEC() - t_start; - } - - return -EBUSY; -} - diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c deleted file mode 100644 index 815046ba85..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" - -#define PB_BUFMGR_DWORDS (4096 / 2) -#define PB_MIN_USER_DWORDS 2048 - -static int -nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; - - assert((min + 1) <= nvchan->dma->max); - - /* Wait for enough space in push buffer */ - min = min < PB_MIN_USER_DWORDS ? PB_MIN_USER_DWORDS : min; - min += 1; /* a bit extra for the NOP */ - if (nvchan->dma->free < min) - WAIT_RING_CH(chan, min); - - /* Insert NOP, may turn into a jump later */ - RING_SPACE_CH(chan, 1); - nvpb->nop_jump = nvchan->dma->cur; - OUT_RING_CH(chan, 0); - - /* Any remaining space is available to the user */ - nvpb->start = nvchan->dma->cur; - nvpb->size = nvchan->dma->free; - nvpb->base.channel = chan; - nvpb->base.remaining = nvpb->size; - nvpb->base.cur = &nvchan->pushbuf[nvpb->start]; - - /* Create a new fence object for this "frame" */ - nouveau_fence_ref(NULL, &nvpb->fence); - nouveau_fence_new(chan, &nvpb->fence); - - return 0; -} - -int -nouveau_pushbuf_init(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *m = &nvchan->dma_master; - struct nouveau_dma_priv *b = &nvchan->dma_bufmgr; - int i; - - if (!nvchan) - return -EINVAL; - - /* Reassign last bit of push buffer for a "separate" bufmgr - * ring buffer - */ - m->max -= PB_BUFMGR_DWORDS; - m->free -= PB_BUFMGR_DWORDS; - - b->base = m->base + ((m->max + 2) << 2); - b->max = PB_BUFMGR_DWORDS - 2; - b->cur = b->put = 0; - b->free = b->max - b->cur; - - /* Some NOPs just to be safe - *XXX: RING_SKIPS - */ - nvchan->dma = b; - RING_SPACE_CH(chan, 8); - for (i = 0; i < 8; i++) - OUT_RING_CH(chan, 0); - nvchan->dma = m; - - nouveau_pushbuf_space(chan, 0); - chan->pushbuf = &nvchan->pb.base; - - nvchan->pb.buffers = calloc(NOUVEAU_PUSHBUF_MAX_BUFFERS, - sizeof(struct nouveau_pushbuf_bo)); - nvchan->pb.relocs = calloc(NOUVEAU_PUSHBUF_MAX_RELOCS, - sizeof(struct nouveau_pushbuf_reloc)); - return 0; -} - -static uint32_t -nouveau_pushbuf_calc_reloc(struct nouveau_bo *bo, - struct nouveau_pushbuf_reloc *r) -{ - uint32_t push; - - if (r->flags & NOUVEAU_BO_LOW) { - push = bo->offset + r->data; - } else - if (r->flags & NOUVEAU_BO_HIGH) { - push = (bo->offset + r->data) >> 32; - } else { - push = r->data; - } - - if (r->flags & NOUVEAU_BO_OR) { - if (bo->flags & NOUVEAU_BO_VRAM) - push |= r->vor; - else - push |= r->tor; - } - - return push; -} - -/* This would be our TTM "superioctl" */ -int -nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; - int ret, i; - - if (nvpb->base.remaining == nvpb->size) - return 0; - - nouveau_fence_flush(chan); - - nvpb->size -= nvpb->base.remaining; - nvchan->dma->cur += nvpb->size; - nvchan->dma->free -= nvpb->size; - assert(nvchan->dma->cur <= nvchan->dma->max); - - nvchan->dma = &nvchan->dma_bufmgr; - nvchan->pushbuf[nvpb->nop_jump] = 0x20000000 | - (nvchan->dma->base + (nvchan->dma->cur << 2)); - - /* Validate buffers + apply relocations */ - nvchan->user_charge = 0; - for (i = 0; i < nvpb->nr_relocs; i++) { - struct nouveau_pushbuf_reloc *r = &nvpb->relocs[i]; - struct nouveau_pushbuf_bo *pbbo = r->pbbo; - struct nouveau_bo *bo = pbbo->bo; - - /* Validated, mem matches presumed, no relocation necessary */ - if (pbbo->handled & 2) { - if (!(pbbo->handled & 1)) - assert(0); - continue; - } - - /* Not yet validated, do it now */ - if (!(pbbo->handled & 1)) { - ret = nouveau_bo_validate(chan, bo, pbbo->flags); - if (ret) { - assert(0); - return ret; - } - pbbo->handled |= 1; - - if (bo->offset == nouveau_bo(bo)->offset && - bo->flags == nouveau_bo(bo)->flags) { - pbbo->handled |= 2; - continue; - } - bo->offset = nouveau_bo(bo)->offset; - bo->flags = nouveau_bo(bo)->flags; - } - - /* Apply the relocation */ - *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); - } - nvpb->nr_relocs = 0; - - /* Dereference all buffers on validate list */ - for (i = 0; i < nvpb->nr_buffers; i++) { - struct nouveau_pushbuf_bo *pbbo = &nvpb->buffers[i]; - - nouveau_bo(pbbo->bo)->pending = NULL; - nouveau_bo_del(&pbbo->bo); - } - nvpb->nr_buffers = 0; - - /* Switch back to user's ring */ - RING_SPACE_CH(chan, 1); - OUT_RING_CH(chan, 0x20000000 | ((nvpb->start << 2) + - nvchan->dma_master.base)); - nvchan->dma = &nvchan->dma_master; - - /* Fence + kickoff */ - nouveau_fence_emit(nvpb->fence); - FIRE_RING_CH(chan); - - /* Allocate space for next push buffer */ - ret = nouveau_pushbuf_space(chan, min); - assert(!ret); - - return 0; -} - -static struct nouveau_pushbuf_bo * -nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) -{ - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_pushbuf_bo *pbbo; - - if (nvbo->pending) - return nvbo->pending; - - if (nvpb->nr_buffers >= NOUVEAU_PUSHBUF_MAX_BUFFERS) - return NULL; - pbbo = nvpb->buffers + nvpb->nr_buffers++; - nvbo->pending = pbbo; - - nouveau_bo_ref(bo->device, bo->handle, &pbbo->bo); - pbbo->channel = chan; - pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; - pbbo->handled = 0; - return pbbo; -} - -int -nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, - struct nouveau_bo *bo, uint32_t data, uint32_t flags, - uint32_t vor, uint32_t tor) -{ - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); - struct nouveau_pushbuf_bo *pbbo; - struct nouveau_pushbuf_reloc *r; - - if (nvpb->nr_relocs >= NOUVEAU_PUSHBUF_MAX_RELOCS) - return -ENOMEM; - - pbbo = nouveau_pushbuf_emit_buffer(chan, bo); - if (!pbbo) - return -ENOMEM; - pbbo->flags |= (flags & NOUVEAU_BO_RDWR); - pbbo->flags &= (flags | NOUVEAU_BO_RDWR); - - r = nvpb->relocs + nvpb->nr_relocs++; - r->pbbo = pbbo; - r->ptr = ptr; - r->flags = flags; - r->data = data; - r->vor = vor; - r->tor = tor; - - if (flags & NOUVEAU_BO_DUMMY) - *(uint32_t *)ptr = 0; - else - *(uint32_t *)ptr = nouveau_pushbuf_calc_reloc(bo, r); - return 0; -} - diff --git a/src/gallium/winsys/dri/nouveau/nouveau_resource.c b/src/gallium/winsys/dri/nouveau/nouveau_resource.c deleted file mode 100644 index 3bbcb5c45e..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_resource.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include - -#include "nouveau_drmif.h" -#include "nouveau_local.h" - -int -nouveau_resource_init(struct nouveau_resource **heap, - unsigned start, unsigned size) -{ - struct nouveau_resource *r; - - r = calloc(1, sizeof(struct nouveau_resource)); - if (!r) - return 1; - - r->start = start; - r->size = size; - *heap = r; - return 0; -} - -int -nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, - struct nouveau_resource **res) -{ - struct nouveau_resource *r; - - if (!heap || !size || !res || *res) - return 1; - - while (heap) { - if (!heap->in_use && heap->size >= size) { - r = calloc(1, sizeof(struct nouveau_resource)); - if (!r) - return 1; - - r->start = (heap->start + heap->size) - size; - r->size = size; - r->in_use = 1; - r->priv = priv; - - heap->size -= size; - - r->next = heap->next; - if (heap->next) - heap->next->prev = r; - r->prev = heap; - heap->next = r; - - *res = r; - return 0; - } - - heap = heap->next; - } - - return 1; -} - -void -nouveau_resource_free(struct nouveau_resource **res) -{ - struct nouveau_resource *r; - - if (!res || !*res) - return; - r = *res; - *res = NULL; - - r->in_use = 0; - - if (r->next && !r->next->in_use) { - struct nouveau_resource *new = r->next; - - new->prev = r->prev; - if (r->prev) - r->prev->next = new; - new->size += r->size; - new->start = r->start; - - free(r); - r = new; - } - - if (r->prev && !r->prev->in_use) { - r->prev->next = r->next; - if (r->next) - r->next->prev = r->prev; - r->prev->size += r->size; - free(r); - } - -} diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c deleted file mode 100644 index df1fe7e69b..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ /dev/null @@ -1,310 +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 "nouveau_context.h" -#include "nouveau_drm.h" -#include "nouveau_dri.h" -#include "nouveau_local.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" - -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 -#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_screen_create(__DRIscreenPrivate *driScrnPriv) -{ - struct nouveau_dri *nv_dri = driScrnPriv->pDevPriv; - struct nouveau_screen *nv_screen; - int ret; - - if (driScrnPriv->devPrivSize != sizeof(struct nouveau_dri)) { - NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n"); - return GL_FALSE; - } - - nv_screen = CALLOC_STRUCT(nouveau_screen); - if (!nv_screen) - return GL_FALSE; - nv_screen->driScrnPriv = driScrnPriv; - driScrnPriv->private = (void *)nv_screen; - - driParseOptionInfo(&nv_screen->option_cache, - __driConfigOptions, __driNConfigOptions); - - if ((ret = nouveau_device_open_existing(&nv_screen->device, 0, - driScrnPriv->fd, 0))) { - NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret); - return GL_FALSE; - } - - nv_screen->front_offset = nv_dri->front_offset; - nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8); - nv_screen->front_cpp = nv_dri->bpp / 8; - nv_screen->front_height = nv_dri->height; - - return GL_TRUE; -} - -static void -nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv) -{ - struct nouveau_screen *nv_screen = driScrnPriv->private; - - driScrnPriv->private = NULL; - FREE(nv_screen); -} - -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 struct __DriverAPIRec -nouveau_api = { - .InitDriver = 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, - .GetSwapInfo = NULL, - .GetMSC = NULL, - .WaitForMSC = NULL, - .WaitForSBC = NULL, - .SwapBuffersMSC = NULL, - .CopySubBuffer = nouveau_copy_sub_buffer, - .setTexOffset = NULL -}; - -static __GLcontextModes * -nouveau_fill_in_modes(unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) -{ - __GLcontextModes * modes; - __GLcontextModes * m; - unsigned num_modes; - unsigned depth_buffer_factor; - unsigned back_buffer_factor; - int i; - - static const struct { - GLenum format; - GLenum type; - } fb_format_array[] = { - { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 }, - { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV }, - { GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV }, - }; - - /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't - * support pageflipping at all. - */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML - }; - - uint8_t depth_bits_array[4] = { 0, 16, 24, 24 }; - uint8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; - uint8_t msaa_samples_array[1] = { 0 }; - - depth_buffer_factor = 4; - back_buffer_factor = (have_back_buffer) ? 3 : 1; - - num_modes = ((pixel_bits==16) ? 1 : 2) * - depth_buffer_factor * back_buffer_factor * 4; - modes = (*dri_interface->createContextModes)(num_modes, - sizeof(__GLcontextModes)); - m = modes; - - for (i=((pixel_bits==16)?0:1);i<((pixel_bits==16)?1:3);i++) { - if (!driFillInModes(&m, fb_format_array[i].format, - fb_format_array[i].type, - depth_bits_array, - stencil_bits_array, - depth_buffer_factor, - back_buffer_modes, - back_buffer_factor, - msaa_samples_array, 1, - GLX_TRUE_COLOR)) { - fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__ ); - return NULL; - } - - if (!driFillInModes(&m, fb_format_array[i].format, - fb_format_array[i].type, - depth_bits_array, - stencil_bits_array, - depth_buffer_factor, - back_buffer_modes, - back_buffer_factor, - msaa_samples_array, 1, - GLX_DIRECT_COLOR)) { - fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__ ); - return NULL; - } - } - - return modes; -} -PUBLIC void * -__driCreateNewScreen_20050727(__DRInativeDisplay *dpy, int scrn, - __DRIscreen *psc, const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - void * pSAREA, int fd, int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) -{ - __DRIscreenPrivate *psp; - 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 }; - struct nouveau_dri *nv_dri = NULL; - - dri_interface = interface; - - if (!driCheckDriDdxDrmVersions2("nouveau", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { - return NULL; - } - - if (drm_expected.patch != drm_version->patch) { - fprintf(stderr, "Incompatible DRM patch level.\n" - "Expected: %d\n" "Current : %d\n", - drm_expected.patch, drm_version->patch); - return NULL; - } - - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, - &nouveau_api); - if (psp == NULL) - return NULL; - nv_dri = psp->pDevPriv; - - *driver_modes = nouveau_fill_in_modes(nv_dri->bpp, - (nv_dri->bpp == 16) ? 16 : 24, - (nv_dri->bpp == 16) ? 0 : 8, - 1); - - driInitExtensions(NULL, card_extensions, GL_FALSE); - - return (void *)psp; -} - diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.h b/src/gallium/winsys/dri/nouveau/nouveau_screen.h deleted file mode 100644 index 388d6be9bb..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __NOUVEAU_SCREEN_H__ -#define __NOUVEAU_SCREEN_H__ - -#include "xmlconfig.h" - -struct nouveau_screen { - __DRIscreenPrivate *driScrnPriv; - driOptionCache option_cache; - - struct nouveau_device *device; - - uint32_t front_offset; - uint32_t front_pitch; - uint32_t front_cpp; - uint32_t front_height; - - void *nvc; -}; - -#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c deleted file mode 100644 index 70e0104e83..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c +++ /dev/null @@ -1,86 +0,0 @@ -#include "main/glheader.h" -#include "glapi/glthread.h" -#include - -#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_local.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" - -void -nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, - const drm_clip_rect_t *rect) -{ - struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate; - drm_clip_rect_t *pbox; - int nbox, i; - - LOCK_HARDWARE(nv); - if (!dPriv->numClipRects) { - UNLOCK_HARDWARE(nv); - return; - } - pbox = dPriv->pClipRects; - nbox = dPriv->numClipRects; - - nv->surface_copy_prep(nv, nv->frontbuffer, surf); - 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; - - nv->surface_copy(nv, dx, dy, sx, sy, w, h); - } - - FIRE_RING(nv->nvc->channel); - 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; - - surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); - 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; - - surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); - if (surf) { - st_notify_swapbuffers(nvfb->stfb); - nouveau_copy_buffer(dPriv, surf, NULL); - } -} - diff --git a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h deleted file mode 100644 index 825d3da6da..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __NOUVEAU_SWAPBUFFERS_H__ -#define __NOUVEAU_SWAPBUFFERS_H__ - -extern void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *, - const drm_clip_rect_t *); -extern void nouveau_copy_sub_buffer(__DRIdrawablePrivate *, - int x, int y, int w, int h); -extern void nouveau_swap_buffers(__DRIdrawablePrivate *); - -#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c deleted file mode 100644 index 5eabbc8893..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ /dev/null @@ -1,158 +0,0 @@ -#include "pipe/p_util.h" - -#include "nouveau_context.h" -#include "nouveau_screen.h" -#include "nouveau_winsys_pipe.h" - -#include "nouveau/nouveau_winsys.h" - -static int -nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count, - struct nouveau_notifier **notify) -{ - struct nouveau_context *nv = nvws->nv; - - return nouveau_notifier_alloc(nv->nvc->channel, nv->nvc->next_handle++, - count, notify); -} - -static int -nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass, - struct nouveau_grobj **grobj) -{ - struct nouveau_context *nv = nvws->nv; - struct nouveau_channel *chan = nv->nvc->channel; - int ret; - - ret = nouveau_grobj_alloc(chan, nv->nvc->next_handle++, - grclass, grobj); - if (ret) - return ret; - - assert(nv->nvc->next_subchannel < 7); - BIND_RING(chan, *grobj, nv->nvc->next_subchannel++); - return 0; -} - -static int -nouveau_pipe_surface_copy(struct nouveau_winsys *nvws, struct pipe_surface *dst, - unsigned dx, unsigned dy, struct pipe_surface *src, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_context *nv = nvws->nv; - - if (nv->surface_copy_prep(nv, dst, src)) - return 1; - nv->surface_copy(nv, dx, dy, sx, sy, w, h); - nv->surface_copy_done(nv); - - return 0; -} - -static int -nouveau_pipe_surface_fill(struct nouveau_winsys *nvws, struct pipe_surface *dst, - unsigned dx, unsigned dy, unsigned w, unsigned h, - unsigned value) -{ - if (nvws->nv->surface_fill(nvws->nv, dst, dx, dy, w, h, value)) - return 1; - 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) -{ - return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, - nouveau_buffer(buf)->bo, - data, flags, vor, tor); -} - -static int -nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size, - struct pipe_fence_handle **fence) -{ - if (fence) { - struct nouveau_pushbuf *pb = nvws->channel->pushbuf; - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(pb); - struct nouveau_fence *ref = NULL; - - nouveau_fence_ref(nvpb->fence, &ref); - *fence = (struct pipe_fence_handle *)ref; - } - - return nouveau_pushbuf_flush(nvws->channel, size); -} - -struct pipe_context * -nouveau_pipe_create(struct nouveau_context *nv) -{ - struct nouveau_channel_context *nvc = nv->nvc; - struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); - struct pipe_screen *(*hws_create)(struct pipe_winsys *, - struct nouveau_winsys *); - struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); - struct pipe_winsys *ws; - unsigned chipset = nv->nv_screen->device->chipset; - - if (!nvws) - return NULL; - - switch (chipset & 0xf0) { - case 0x10: - case 0x20: - hws_create = nv10_screen_create; - hw_create = nv10_create; - break; - case 0x30: - hws_create = nv30_screen_create; - hw_create = nv30_create; - break; - case 0x40: - case 0x60: - hws_create = nv40_screen_create; - hw_create = nv40_create; - break; - case 0x50: - case 0x80: - case 0x90: - hws_create = nv50_screen_create; - hw_create = nv50_create; - break; - default: - NOUVEAU_ERR("Unknown chipset NV%02x\n", chipset); - return NULL; - } - - nvws->nv = nv; - nvws->channel = nv->nvc->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->surface_copy = nouveau_pipe_surface_copy; - nvws->surface_fill = nouveau_pipe_surface_fill; - - ws = nouveau_create_pipe_winsys(nv); - - if (!nvc->pscreen) - nvc->pscreen = hws_create(ws, nvws); - nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id); - return nvc->pctx[nv->pctx_id]; -} - diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c deleted file mode 100644 index 8a2870a2ff..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ /dev/null @@ -1,205 +0,0 @@ -#include "pipe/p_winsys.h" -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" - -#include "nouveau_context.h" -#include "nouveau_local.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" -#include "nouveau_winsys_pipe.h" - -static void -nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, - void *context_private) -{ - struct nouveau_context *nv = context_private; - __DRIdrawablePrivate *dPriv = nv->dri_drawable; - - nouveau_copy_buffer(dPriv, surf, NULL); -} - -static const char * -nouveau_get_name(struct pipe_winsys *pws) -{ - return "Nouveau/DRI"; -} - -static struct pipe_buffer * -nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, - unsigned usage, unsigned size) -{ - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; - struct nouveau_context *nv = nvpws->nv; - struct nouveau_device *dev = nv->nv_screen->device; - struct nouveau_pipe_buffer *nvbuf; - uint32_t flags; - - nvbuf = calloc(1, sizeof(*nvbuf)); - if (!nvbuf) - return NULL; - nvbuf->base.refcount = 1; - nvbuf->base.alignment = alignment; - nvbuf->base.usage = usage; - nvbuf->base.size = size; - - flags = NOUVEAU_BO_LOCAL; - - if (usage & PIPE_BUFFER_USAGE_PIXEL) { - if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) - flags |= NOUVEAU_BO_GART; - flags |= NOUVEAU_BO_VRAM; - - switch (dev->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 (nv->cap.hw_vertex_buffer) - flags |= NOUVEAU_BO_GART; - } - - if (usage & PIPE_BUFFER_USAGE_INDEX) { - if (nv->cap.hw_index_buffer) - flags |= NOUVEAU_BO_GART; - } - - 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 *pws, void *ptr, unsigned bytes) -{ - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; - struct nouveau_device *dev = nvpws->nv->nv_screen->device; - struct nouveau_pipe_buffer *nvbuf; - - nvbuf = calloc(1, sizeof(*nvbuf)); - if (!nvbuf) - return NULL; - nvbuf->base.refcount = 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_winsys *ws, struct pipe_buffer *buf) -{ - struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); - - nouveau_bo_del(&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_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_buffer(buf); - - nouveau_bo_unmap(nvbuf->bo); -} - -static INLINE struct nouveau_fence * -nouveau_pipe_fence(struct pipe_fence_handle *pfence) -{ - return (struct nouveau_fence *)pfence; -} - -static void -nouveau_pipe_fence_reference(struct pipe_winsys *ws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *pfence) -{ - nouveau_fence_ref((void *)pfence, (void *)ptr); -} - -static int -nouveau_pipe_fence_signalled(struct pipe_winsys *ws, - struct pipe_fence_handle *pfence, unsigned flag) -{ - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)ws; - struct nouveau_fence *fence = nouveau_pipe_fence(pfence); - - if (nouveau_fence(fence)->signalled == 0) - nouveau_fence_flush(nvpws->nv->nvc->channel); - - return !nouveau_fence(fence)->signalled; -} - -static int -nouveau_pipe_fence_finish(struct pipe_winsys *ws, - struct pipe_fence_handle *pfence, unsigned flag) -{ - struct nouveau_fence *fence = nouveau_pipe_fence(pfence); - struct nouveau_fence *ref = NULL; - - nouveau_fence_ref(fence, &ref); - return nouveau_fence_wait(&ref); -} - -struct pipe_winsys * -nouveau_create_pipe_winsys(struct nouveau_context *nv) -{ - struct nouveau_pipe_winsys *nvpws; - struct pipe_winsys *pws; - - nvpws = CALLOC_STRUCT(nouveau_pipe_winsys); - if (!nvpws) - return NULL; - nvpws->nv = nv; - pws = &nvpws->pws; - - pws->flush_frontbuffer = nouveau_flush_frontbuffer; - - pws->buffer_create = nouveau_pipe_bo_create; - pws->buffer_destroy = nouveau_pipe_bo_del; - pws->user_buffer_create = nouveau_pipe_bo_user_create; - pws->buffer_map = nouveau_pipe_bo_map; - pws->buffer_unmap = nouveau_pipe_bo_unmap; - - pws->fence_reference = nouveau_pipe_fence_reference; - pws->fence_signalled = nouveau_pipe_fence_signalled; - pws->fence_finish = nouveau_pipe_fence_finish; - - pws->get_name = nouveau_get_name; - - return &nvpws->pws; -} - diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h deleted file mode 100644 index 6a03ac0d77..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef NOUVEAU_PIPE_WINSYS_H -#define NOUVEAU_PIPE_WINSYS_H - -#include "pipe/p_context.h" -#include "pipe/p_winsys.h" -#include "nouveau_context.h" - -struct nouveau_pipe_buffer { - struct pipe_buffer base; - struct nouveau_bo *bo; -}; - -static inline struct nouveau_pipe_buffer * -nouveau_buffer(struct pipe_buffer *buf) -{ - return (struct nouveau_pipe_buffer *)buf; -} - -struct nouveau_pipe_winsys { - struct pipe_winsys pws; - - struct nouveau_context *nv; -}; - -extern struct pipe_winsys * -nouveau_create_pipe_winsys(struct nouveau_context *nv); - -struct pipe_context * -nouveau_create_softpipe(struct nouveau_context *nv); - -struct pipe_context * -nouveau_pipe_create(struct nouveau_context *nv); - -#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c deleted file mode 100644 index 704f6c7750..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include "imports.h" - -#include "pipe/p_defines.h" -#include "pipe/p_format.h" -#include "softpipe/sp_winsys.h" - -#include "nouveau_context.h" -#include "nouveau_winsys_pipe.h" - -struct nouveau_softpipe_winsys { - struct softpipe_winsys sws; - struct nouveau_context *nv; -}; - -/** - * Return list of surface formats supported by this driver. - */ -static boolean -nouveau_is_format_supported(struct softpipe_winsys *sws, uint format) -{ - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return TRUE; - default: - break; - }; - - return FALSE; -} - -struct pipe_context * -nouveau_create_softpipe(struct nouveau_context *nv) -{ - struct nouveau_softpipe_winsys *nvsws; - struct pipe_screen *pscreen; - struct pipe_winsys *ws; - - ws = nouveau_create_pipe_winsys(nv); - if (!ws) - return NULL; - pscreen = softpipe_create_screen(ws); - - nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys); - if (!nvsws) - return NULL; - - nvsws->sws.is_format_supported = nouveau_is_format_supported; - nvsws->nv = nv; - - return softpipe_create(pscreen, ws, &nvsws->sws); -} - diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c deleted file mode 100644 index 8fa3d106c8..0000000000 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ /dev/null @@ -1,314 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_format.h" - -#include "nouveau_context.h" - -static INLINE int -nv04_surface_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; - case PIPE_FORMAT_R5G6B5_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; - default: - return -1; - } -} - -static INLINE int -nv04_rect_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; - case PIPE_FORMAT_R5G6B5_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; - default: - return -1; - } -} - -static void -nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct pipe_surface *dst = nv->surf_dst; - struct pipe_surface *src = nv->surf_src; - unsigned dst_offset, src_offset; - - dst_offset = dst->offset + (dy * dst->stride) + (dx * dst->block.size); - src_offset = src->offset + (sy * src->stride) + (sx * src->block.size); - - while (h) { - int count = (h > 2047) ? 2047 : h; - - BEGIN_RING(chan, nv->nvc->NvM2MF, - NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src_offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst_offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RING (chan, src->stride); - OUT_RING (chan, dst->stride); - OUT_RING (chan, w * src->block.size); - OUT_RING (chan, count); - OUT_RING (chan, 0x0101); - OUT_RING (chan, 0); - - h -= count; - src_offset += src->stride * count; - dst_offset += dst->stride * count; - } -} - -static void -nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_channel *chan = nv->nvc->channel; - - BEGIN_RING(chan, nv->nvc->NvImageBlit, 0x0300, 3); - OUT_RING (chan, (sy << 16) | sx); - OUT_RING (chan, (dy << 16) | dx); - OUT_RING (chan, ( h << 16) | w); -} - -static int -nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, - struct pipe_surface *src) -{ - struct nouveau_channel *chan = nv->nvc->channel; - int format; - - if (src->format != dst->format) - return 1; - - /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback - * to NV_MEMORY_TO_MEMORY_FORMAT in this case. - */ - if ((src->offset & 63) || (dst->offset & 63)) { - BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF, - NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - nv->surface_copy = nv04_surface_copy_m2mf; - nv->surf_dst = dst; - nv->surf_src = src; - return 0; - - } - - if ((format = nv04_surface_format(dst->format)) < 0) { - NOUVEAU_ERR("Bad surface format 0x%x\n", dst->format); - return 1; - } - nv->surface_copy = nv04_surface_copy_blit; - - BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, - NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, - NV04_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (chan, format); - OUT_RING (chan, (dst->stride << 16) | src->stride); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - return 0; -} - -static void -nv04_surface_copy_done(struct nouveau_context *nv) -{ - FIRE_RING(nv->nvc->channel); -} - -static int -nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, - unsigned dx, unsigned dy, unsigned w, unsigned h, - unsigned value) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *surf2d = nv->nvc->NvCtxSurf2D; - struct nouveau_grobj *rect = nv->nvc->NvGdiRect; - int cs2d_format, gdirect_format; - - if ((cs2d_format = nv04_surface_format(dst->format)) < 0) { - NOUVEAU_ERR("Bad format = %d\n", dst->format); - return 1; - } - - if ((gdirect_format = nv04_rect_format(dst->format)) < 0) { - NOUVEAU_ERR("Bad format = %d\n", dst->format); - return 1; - } - - BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (chan, cs2d_format); - OUT_RING (chan, (dst->stride << 16) | dst->stride); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); - OUT_RING (chan, gdirect_format); - BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); - OUT_RING (chan, value); - BEGIN_RING(chan, rect, - NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); - OUT_RING (chan, (dx << 16) | dy); - OUT_RING (chan, ( w << 16) | h); - - FIRE_RING(chan); - return 0; -} - -int -nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) -{ - struct nouveau_channel *chan = nvc->channel; - unsigned chipset = nvc->channel->device->chipset, class; - int ret; - - if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, 0x39, - &nvc->NvM2MF))) { - NOUVEAU_ERR("Error creating m2mf object: %d\n", ret); - return 1; - } - BIND_RING (chan, nvc->NvM2MF, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvM2MF, - NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - - class = chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : - NV10_CONTEXT_SURFACES_2D; - if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvCtxSurf2D))) { - NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); - return 1; - } - BIND_RING (chan, nvc->NvCtxSurf2D, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvCtxSurf2D, - NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RING (chan, nvc->channel->vram->handle); - OUT_RING (chan, nvc->channel->vram->handle); - - class = chipset < 0x10 ? NV04_IMAGE_BLIT : NV12_IMAGE_BLIT; - if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvImageBlit))) { - NOUVEAU_ERR("Error creating blit object: %d\n", ret); - return 1; - } - BIND_RING (chan, nvc->NvImageBlit, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); - OUT_RING (chan, nvc->NvCtxSurf2D->handle); - BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); - OUT_RING (chan, NV04_IMAGE_BLIT_OPERATION_SRCCOPY); - - class = NV04_GDI_RECTANGLE_TEXT; - if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvGdiRect))) { - NOUVEAU_ERR("Error creating rect object: %d\n", ret); - return 1; - } - BIND_RING (chan, nvc->NvGdiRect, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); - OUT_RING (chan, nvc->NvCtxSurf2D->handle); - BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); - OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); - BEGIN_RING(chan, nvc->NvGdiRect, - NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); - OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); - - switch (chipset & 0xf0) { - case 0x00: - case 0x10: - class = NV04_SWIZZLED_SURFACE; - break; - case 0x20: - class = NV20_SWIZZLED_SURFACE; - break; - case 0x30: - class = NV30_SWIZZLED_SURFACE; - break; - case 0x40: - case 0x60: - class = NV40_SWIZZLED_SURFACE; - break; - default: - /* Famous last words: this really can't happen.. */ - assert(0); - break; - } - - ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvSwzSurf); - if (ret) { - NOUVEAU_ERR("Error creating swizzled surface: %d\n", ret); - return 1; - } - - BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); - OUT_RING (chan, nvc->channel->vram->handle); - - if (chipset < 0x10) { - class = NV04_SCALED_IMAGE_FROM_MEMORY; - } else - if (chipset < 0x40) { - class = NV10_SCALED_IMAGE_FROM_MEMORY; - } else { - class = NV40_SCALED_IMAGE_FROM_MEMORY; - } - - ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvSIFM); - if (ret) { - NOUVEAU_ERR("Error creating scaled image object: %d\n", ret); - return 1; - } - - BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); - - return 0; -} - -int -nouveau_surface_init_nv04(struct nouveau_context *nv) -{ - nv->surface_copy_prep = nv04_surface_copy_prep; - nv->surface_copy = nv04_surface_copy_blit; - nv->surface_copy_done = nv04_surface_copy_done; - nv->surface_fill = nv04_surface_fill; - return 0; -} - diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c deleted file mode 100644 index c8ab7f690f..0000000000 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ /dev/null @@ -1,194 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_format.h" - -#include "nouveau_context.h" - -static INLINE int -nv50_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return NV50_2D_DST_FORMAT_32BPP; - case PIPE_FORMAT_X8R8G8B8_UNORM: - return NV50_2D_DST_FORMAT_24BPP; - case PIPE_FORMAT_R5G6B5_UNORM: - return NV50_2D_DST_FORMAT_16BPP; - case PIPE_FORMAT_A8_UNORM: - return NV50_2D_DST_FORMAT_8BPP; - default: - return -1; - } -} - -static int -nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->bo; - int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; - int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); - - surf_format = nv50_format(surf->format); - if (surf_format < 0) - return 1; - - if (!nouveau_bo(bo)->tiled) { - BEGIN_RING(chan, eng2d, mthd, 2); - OUT_RING (chan, surf_format); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, mthd + 0x14, 5); - OUT_RING (chan, surf->stride); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - OUT_RELOCh(chan, bo, surf->offset, flags); - OUT_RELOCl(chan, bo, surf->offset, flags); - } else { - BEGIN_RING(chan, eng2d, mthd, 5); - OUT_RING (chan, surf_format); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, mthd + 0x18, 4); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - OUT_RELOCh(chan, bo, surf->offset, flags); - OUT_RELOCl(chan, bo, surf->offset, flags); - } - -#if 0 - if (dst) { - BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - } -#endif - - return 0; -} - -static int -nv50_surface_copy_prep(struct nouveau_context *nv, - struct pipe_surface *dst, struct pipe_surface *src) -{ - int ret; - - assert(src->format == dst->format); - - ret = nv50_surface_set(nv, dst, 1); - if (ret) - return ret; - - ret = nv50_surface_set(nv, src, 0); - if (ret) - return ret; - - return 0; -} - -static void -nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - - BEGIN_RING(chan, eng2d, 0x088c, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4); - OUT_RING (chan, dx); - OUT_RING (chan, dy); - OUT_RING (chan, w); - OUT_RING (chan, h); - BEGIN_RING(chan, eng2d, 0x08c0, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, 0x08d0, 4); - OUT_RING (chan, 0); - OUT_RING (chan, sx); - OUT_RING (chan, 0); - OUT_RING (chan, sy); -} - -static void -nv50_surface_copy_done(struct nouveau_context *nv) -{ - FIRE_RING(nv->nvc->channel); -} - -static int -nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, - unsigned dx, unsigned dy, unsigned w, unsigned h, - unsigned value) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - int rect_format, ret; - - rect_format = nv50_format(dst->format); - if (rect_format < 0) - return 1; - - ret = nv50_surface_set(nv, dst, 1); - if (ret) - return ret; - - BEGIN_RING(chan, eng2d, 0x0580, 3); - OUT_RING (chan, 4); - OUT_RING (chan, rect_format); - OUT_RING (chan, value); - - BEGIN_RING(chan, eng2d, NV50_2D_RECT_X1, 4); - OUT_RING (chan, dx); - OUT_RING (chan, dy); - OUT_RING (chan, dx + w); - OUT_RING (chan, dy + h); - - FIRE_RING(chan); - return 0; -} - -int -nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) -{ - struct nouveau_channel *chan = nvc->channel; - struct nouveau_grobj *eng2d = NULL; - int ret; - - ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d); - if (ret) - return ret; - nvc->Nv2D = eng2d; - - BIND_RING (chan, eng2d, nvc->next_subchannel++); - BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4); - OUT_RING (chan, nvc->sync_notifier->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1); - OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); - BEGIN_RING(chan, eng2d, 0x0290, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, 0x0888, 1); - OUT_RING (chan, 1); - - return 0; -} - -int -nouveau_surface_init_nv50(struct nouveau_context *nv) -{ - nv->surface_copy_prep = nv50_surface_copy_prep; - nv->surface_copy = nv50_surface_copy; - nv->surface_copy_done = nv50_surface_copy_done; - nv->surface_fill = nv50_surface_fill; - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile new file mode 100644 index 0000000000..be630ff6d1 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/Makefile @@ -0,0 +1,45 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = nouveau_dri.so + +MINIGLX_SOURCES = + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/nv04/libnv04.a \ + $(TOP)/src/gallium/drivers/nv10/libnv10.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_bo.c \ + nouveau_channel.c \ + nouveau_context.c \ + nouveau_device.c \ + nouveau_dma.c \ + nouveau_fence.c \ + nouveau_grobj.c \ + nouveau_lock.c \ + nouveau_notifier.c \ + nouveau_pushbuf.c \ + nouveau_resource.c \ + nouveau_screen.c \ + nouveau_swapbuffers.c \ + nouveau_winsys.c \ + nouveau_winsys_pipe.c \ + nouveau_winsys_softpipe.c \ + nv04_surface.c \ + nv50_surface.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../Makefile.template + +symlinks: diff --git a/src/gallium/winsys/drm/nouveau/nouveau_bo.c b/src/gallium/winsys/drm/nouveau/nouveau_bo.c new file mode 100644 index 0000000000..b5942994d9 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_bo.c @@ -0,0 +1,470 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" +#include "nouveau_local.h" + +static void +nouveau_mem_free(struct nouveau_device *dev, struct drm_nouveau_mem_alloc *ma, + void **map) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct drm_nouveau_mem_free mf; + + if (map && *map) { + drmUnmap(*map, ma->size); + *map = NULL; + } + + if (ma->size) { + mf.offset = ma->offset; + mf.flags = ma->flags; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_MEM_FREE, + &mf, sizeof(mf)); + ma->size = 0; + } +} + +static int +nouveau_mem_alloc(struct nouveau_device *dev, unsigned size, unsigned align, + uint32_t flags, struct drm_nouveau_mem_alloc *ma, void **map) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + int ret; + + ma->alignment = align; + ma->size = size; + ma->flags = flags; + if (map) + ma->flags |= NOUVEAU_MEM_MAPPED; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_MEM_ALLOC, ma, + sizeof(struct drm_nouveau_mem_alloc)); + if (ret) + return ret; + + if (map) { + ret = drmMap(nvdev->fd, ma->map_handle, ma->size, map); + if (ret) { + *map = NULL; + nouveau_mem_free(dev, ma, map); + return ret; + } + } + + return 0; +} + +static void +nouveau_bo_tmp_del(void *priv) +{ + struct nouveau_resource *r = priv; + + nouveau_fence_ref(NULL, (struct nouveau_fence **)&r->priv); + nouveau_resource_free(&r); +} + +static unsigned +nouveau_bo_tmp_max(struct nouveau_device_priv *nvdev) +{ + struct nouveau_resource *r = nvdev->sa_heap; + unsigned max = 0; + + while (r) { + if (r->in_use && !nouveau_fence(r->priv)->emitted) { + r = r->next; + continue; + } + + if (max < r->size) + max = r->size; + r = r->next; + } + + return max; +} + +static struct nouveau_resource * +nouveau_bo_tmp(struct nouveau_channel *chan, unsigned size, + struct nouveau_fence *fence) +{ + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_resource *r = NULL; + struct nouveau_fence *ref = NULL; + + if (fence) + nouveau_fence_ref(fence, &ref); + else + nouveau_fence_new(chan, &ref); + assert(ref); + + while (nouveau_resource_alloc(nvdev->sa_heap, size, ref, &r)) { + if (nouveau_bo_tmp_max(nvdev) < size) { + nouveau_fence_ref(NULL, &ref); + return NULL; + } + + nouveau_fence_flush(chan); + } + nouveau_fence_signal_cb(ref, nouveau_bo_tmp_del, r); + + return r; +} + +int +nouveau_bo_init(struct nouveau_device *dev) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + int ret; + + ret = nouveau_mem_alloc(dev, 128*1024, 0, NOUVEAU_MEM_AGP | + NOUVEAU_MEM_PCI, &nvdev->sa, &nvdev->sa_map); + if (ret) + return ret; + + ret = nouveau_resource_init(&nvdev->sa_heap, 0, nvdev->sa.size); + if (ret) { + nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); + return ret; + } + + return 0; +} + +void +nouveau_bo_takedown(struct nouveau_device *dev) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); +} + +int +nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, + int size, struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + int ret; + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo = calloc(1, sizeof(struct nouveau_bo_priv)); + if (!nvbo) + return -ENOMEM; + nvbo->base.device = dev; + nvbo->base.size = size; + nvbo->base.handle = bo_to_ptr(nvbo); + nvbo->drm.alignment = align; + nvbo->refcount = 1; + + if (flags & NOUVEAU_BO_TILED) { + nvbo->tiled = 1; + if (flags & NOUVEAU_BO_ZTILE) + nvbo->tiled |= 2; + flags &= ~NOUVEAU_BO_TILED; + } + + ret = nouveau_bo_set_status(&nvbo->base, flags); + if (ret) { + free(nvbo); + return ret; + } + + *bo = &nvbo->base; + return 0; +} + +int +nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size, + struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo = calloc(1, sizeof(*nvbo)); + if (!nvbo) + return -ENOMEM; + nvbo->base.device = dev; + + nvbo->sysmem = ptr; + nvbo->user = 1; + + nvbo->base.size = size; + nvbo->base.offset = nvbo->drm.offset; + nvbo->base.handle = bo_to_ptr(nvbo); + nvbo->refcount = 1; + *bo = &nvbo->base; + return 0; +} + +int +nouveau_bo_ref(struct nouveau_device *dev, uint64_t handle, + struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo = ptr_to_bo(handle); + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo->refcount++; + *bo = &nvbo->base; + return 0; +} + +static void +nouveau_bo_del_cb(void *priv) +{ + struct nouveau_bo_priv *nvbo = priv; + + nouveau_fence_ref(NULL, &nvbo->fence); + nouveau_mem_free(nvbo->base.device, &nvbo->drm, &nvbo->map); + if (nvbo->sysmem && !nvbo->user) + free(nvbo->sysmem); + free(nvbo); +} + +void +nouveau_bo_del(struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + + if (!bo || !*bo) + return; + nvbo = nouveau_bo(*bo); + *bo = NULL; + + if (--nvbo->refcount) + return; + + if (nvbo->pending) + nouveau_pushbuf_flush(nvbo->pending->channel, 0); + + if (nvbo->fence) + nouveau_fence_signal_cb(nvbo->fence, nouveau_bo_del_cb, nvbo); + else + nouveau_bo_del_cb(nvbo); +} + +int +nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + + if (!nvbo) + return -EINVAL; + + if (nvbo->pending && + (nvbo->pending->flags & NOUVEAU_BO_WR || flags & NOUVEAU_BO_WR)) { + nouveau_pushbuf_flush(nvbo->pending->channel, 0); + } + + if (flags & NOUVEAU_BO_WR) + nouveau_fence_wait(&nvbo->fence); + else + nouveau_fence_wait(&nvbo->wr_fence); + + if (nvbo->sysmem) + bo->map = nvbo->sysmem; + else + bo->map = nvbo->map; + return 0; +} + +void +nouveau_bo_unmap(struct nouveau_bo *bo) +{ + bo->map = NULL; +} + +static int +nouveau_bo_upload(struct nouveau_bo_priv *nvbo) +{ + if (nvbo->fence) + nouveau_fence_wait(&nvbo->fence); + memcpy(nvbo->map, nvbo->sysmem, nvbo->drm.size); + return 0; +} + +int +nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct drm_nouveau_mem_alloc new; + void *new_map = NULL, *new_sysmem = NULL; + unsigned new_flags = 0, ret; + + assert(!bo->map); + + /* Check current memtype vs requested, if they match do nothing */ + if ((nvbo->drm.flags & NOUVEAU_MEM_FB) && (flags & NOUVEAU_BO_VRAM)) + return 0; + if ((nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) && + (flags & NOUVEAU_BO_GART)) + return 0; + if (nvbo->drm.size == 0 && nvbo->sysmem && (flags & NOUVEAU_BO_LOCAL)) + return 0; + + memset(&new, 0x00, sizeof(new)); + + /* Allocate new memory */ + if (flags & NOUVEAU_BO_VRAM) + new_flags |= NOUVEAU_MEM_FB; + else + if (flags & NOUVEAU_BO_GART) + new_flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI); + + if (nvbo->tiled && flags) { + new_flags |= NOUVEAU_MEM_TILE; + if (nvbo->tiled & 2) + new_flags |= NOUVEAU_MEM_TILE_ZETA; + } + + if (new_flags) { + ret = nouveau_mem_alloc(bo->device, bo->size, + nvbo->drm.alignment, new_flags, + &new, &new_map); + if (ret) + return ret; + } else + if (!nvbo->user) { + new_sysmem = malloc(bo->size); + } + + /* Copy old -> new */ + /*XXX: use M2MF */ + if (nvbo->sysmem || nvbo->map) { + struct nouveau_pushbuf_bo *pbo = nvbo->pending; + nvbo->pending = NULL; + nouveau_bo_map(bo, NOUVEAU_BO_RD); + memcpy(new_map, bo->map, bo->size); + nouveau_bo_unmap(bo); + nvbo->pending = pbo; + } + + /* Free old memory */ + if (nvbo->fence) + nouveau_fence_wait(&nvbo->fence); + nouveau_mem_free(bo->device, &nvbo->drm, &nvbo->map); + if (nvbo->sysmem && !nvbo->user) + free(nvbo->sysmem); + + nvbo->drm = new; + nvbo->map = new_map; + if (!nvbo->user) + nvbo->sysmem = new_sysmem; + bo->flags = flags; + bo->offset = nvbo->drm.offset; + return 0; +} + +static int +nouveau_bo_validate_user(struct nouveau_channel *chan, struct nouveau_bo *bo, + struct nouveau_fence *fence, uint32_t flags) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_resource *r; + + if (nvchan->user_charge + bo->size > nvdev->sa.size) + return 1; + + if (!(flags & NOUVEAU_BO_GART)) + return 1; + + r = nouveau_bo_tmp(chan, bo->size, fence); + if (!r) + return 1; + nvchan->user_charge += bo->size; + + memcpy(nvdev->sa_map + r->start, nvbo->sysmem, bo->size); + + nvbo->offset = nvdev->sa.offset + r->start; + nvbo->flags = NOUVEAU_BO_GART; + return 0; +} + +static int +nouveau_bo_validate_bo(struct nouveau_channel *chan, struct nouveau_bo *bo, + struct nouveau_fence *fence, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + int ret; + + ret = nouveau_bo_set_status(bo, flags); + if (ret) { + nouveau_fence_flush(chan); + + ret = nouveau_bo_set_status(bo, flags); + if (ret) + return ret; + } + + if (nvbo->user) + nouveau_bo_upload(nvbo); + + nvbo->offset = nvbo->drm.offset; + if (nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) + nvbo->flags = NOUVEAU_BO_GART; + else + nvbo->flags = NOUVEAU_BO_VRAM; + + return 0; +} + +int +nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo, + uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_fence *fence = nouveau_pushbuf(chan->pushbuf)->fence; + int ret; + + assert(bo->map == NULL); + + if (nvbo->user) { + ret = nouveau_bo_validate_user(chan, bo, fence, flags); + if (ret) { + ret = nouveau_bo_validate_bo(chan, bo, fence, flags); + if (ret) + return ret; + } + } else { + ret = nouveau_bo_validate_bo(chan, bo, fence, flags); + if (ret) + return ret; + } + + if (flags & NOUVEAU_BO_WR) + nouveau_fence_ref(fence, &nvbo->wr_fence); + nouveau_fence_ref(fence, &nvbo->fence); + return 0; +} + diff --git a/src/gallium/winsys/drm/nouveau/nouveau_channel.c b/src/gallium/winsys/drm/nouveau/nouveau_channel.c new file mode 100644 index 0000000000..3b4dcd1ecf --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_channel.c @@ -0,0 +1,126 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +int +nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, + uint32_t tt_ctxdma, struct nouveau_channel **chan) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct nouveau_channel_priv *nvchan; + int ret; + + if (!nvdev || !chan || *chan) + return -EINVAL; + + nvchan = calloc(1, sizeof(struct nouveau_channel_priv)); + if (!nvchan) + return -ENOMEM; + nvchan->base.device = dev; + + nvchan->drm.fb_ctxdma_handle = fb_ctxdma; + nvchan->drm.tt_ctxdma_handle = tt_ctxdma; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, + &nvchan->drm, sizeof(nvchan->drm)); + if (ret) { + free(nvchan); + return ret; + } + + nvchan->base.id = nvchan->drm.channel; + if (nouveau_grobj_ref(&nvchan->base, nvchan->drm.fb_ctxdma_handle, + &nvchan->base.vram) || + nouveau_grobj_ref(&nvchan->base, nvchan->drm.tt_ctxdma_handle, + &nvchan->base.gart)) { + nouveau_channel_free((void *)&nvchan); + return -EINVAL; + } + + ret = drmMap(nvdev->fd, nvchan->drm.ctrl, nvchan->drm.ctrl_size, + (void*)&nvchan->user); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + nvchan->put = &nvchan->user[0x40/4]; + nvchan->get = &nvchan->user[0x44/4]; + nvchan->ref_cnt = &nvchan->user[0x48/4]; + + ret = drmMap(nvdev->fd, nvchan->drm.notifier, nvchan->drm.notifier_size, + (drmAddressPtr)&nvchan->notifier_block); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + ret = drmMap(nvdev->fd, nvchan->drm.cmdbuf, nvchan->drm.cmdbuf_size, + (void*)&nvchan->pushbuf); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + ret = nouveau_grobj_alloc(&nvchan->base, 0x00000000, 0x0030, + &nvchan->base.nullobj); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + nouveau_dma_channel_init(&nvchan->base); + nouveau_pushbuf_init(&nvchan->base); + + *chan = &nvchan->base; + return 0; +} + +void +nouveau_channel_free(struct nouveau_channel **chan) +{ + struct nouveau_channel_priv *nvchan; + struct nouveau_device_priv *nvdev; + struct drm_nouveau_channel_free cf; + + if (!chan || !*chan) + return; + nvchan = nouveau_channel(*chan); + *chan = NULL; + nvdev = nouveau_device(nvchan->base.device); + + FIRE_RING_CH(&nvchan->base); + + nouveau_grobj_free(&nvchan->base.vram); + nouveau_grobj_free(&nvchan->base.gart); + nouveau_grobj_free(&nvchan->base.nullobj); + + cf.channel = nvchan->drm.channel; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf)); + free(nvchan); +} + + diff --git a/src/gallium/winsys/drm/nouveau/nouveau_context.c b/src/gallium/winsys/drm/nouveau/nouveau_context.c new file mode 100644 index 0000000000..74413c408f --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_context.c @@ -0,0 +1,346 @@ +#include "main/glheader.h" +#include "glapi/glthread.h" +#include +#include "utils.h" + +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "pipe/p_screen.h" + +#include "nouveau_context.h" +#include "nouveau_dri.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_winsys_pipe.h" + +#ifdef DEBUG +static const struct dri_debug_control debug_control[] = { + { "bo", DEBUG_BO }, + { NULL, 0 } +}; +int __nouveau_debug = 0; +#endif + +static void +nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) +{ + nouveau_grobj_free(&nvc->NvCtxSurf2D); + nouveau_grobj_free(&nvc->NvImageBlit); + nouveau_grobj_free(&nvc->NvGdiRect); + nouveau_grobj_free(&nvc->NvM2MF); + nouveau_grobj_free(&nvc->Nv2D); + nouveau_grobj_free(&nvc->NvSwzSurf); + nouveau_grobj_free(&nvc->NvSIFM); + + nouveau_notifier_free(&nvc->sync_notifier); + + nouveau_channel_free(&nvc->channel); + + FREE(nvc); +} + +static struct nouveau_channel_context * +nouveau_channel_context_create(struct nouveau_device *dev) +{ + struct nouveau_channel_context *nvc; + int ret; + + nvc = CALLOC_STRUCT(nouveau_channel_context); + if (!nvc) + return NULL; + + if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002, + &nvc->channel))) { + NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + nvc->next_handle = 0x80000000; + + if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, + &nvc->sync_notifier))) { + NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + ret = nouveau_surface_channel_create_nv50(nvc); + break; + default: + ret = nouveau_surface_channel_create_nv04(nvc); + break; + } + + if (ret) { + NOUVEAU_ERR("Error initialising surface objects: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + return nvc; +} + +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 = CALLOC_STRUCT(nouveau_context); + struct pipe_context *pipe = NULL; + struct st_context *st_share = NULL; + struct nouveau_channel_context *nvc = NULL; + struct nouveau_device *dev = nv_screen->device; + int i; + + if (sharedContextPrivate) { + st_share = ((struct nouveau_context *)sharedContextPrivate)->st; + } + + switch (dev->chipset & 0xf0) { + case 0x10: + case 0x20: + /* NV10 */ + case 0x30: + /* NV30 */ + case 0x40: + case 0x60: + /* NV40 */ + case 0x50: + case 0x80: + case 0x90: + /* G80 */ + break; + default: + NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset); + return GL_FALSE; + } + + driContextPriv->driverPrivate = (void *)nv; + nv->nv_screen = nv_screen; + nv->dri_screen = driScrnPriv; + + { + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + nvdev->ctx = driContextPriv->hHWContext; + nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock; + } + + driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, + nv->dri_screen->myNum, "nouveau"); +#ifdef DEBUG + __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"), + debug_control); +#endif + + /*XXX: Hack up a fake region and buffer object for front buffer. + * This will go away with TTM, replaced with a simple reference + * of the front buffer handle passed to us by the DDX. + */ + { + struct pipe_surface *fb_surf; + struct nouveau_pipe_buffer *fb_buf; + struct nouveau_bo_priv *fb_bo; + + fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); + fb_bo->drm.offset = nv_screen->front_offset; + fb_bo->drm.flags = NOUVEAU_MEM_FB; + fb_bo->drm.size = nv_screen->front_pitch * + nv_screen->front_height; + fb_bo->refcount = 1; + fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; + fb_bo->base.offset = fb_bo->drm.offset; + fb_bo->base.handle = (unsigned long)fb_bo; + fb_bo->base.size = fb_bo->drm.size; + fb_bo->base.device = nv_screen->device; + + fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); + fb_buf->bo = &fb_bo->base; + + fb_surf = calloc(1, sizeof(struct pipe_surface)); + if (nv_screen->front_cpp == 2) + fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; + else + fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; + pf_get_block(fb_surf->format, &fb_surf->block); + fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; + fb_surf->height = nv_screen->front_height; + fb_surf->stride = fb_surf->width * fb_surf->block.size; + fb_surf->refcount = 1; + fb_surf->buffer = &fb_buf->base; + + nv->frontbuffer = fb_surf; + } + + /* Attempt to share a single channel between multiple contexts from + * a single process. + */ + nvc = nv_screen->nvc; + if (!nvc && st_share) { + struct nouveau_context *snv = st_share->pipe->priv; + if (snv) { + nvc = snv->nvc; + } + } + + /*XXX: temporary - disable multi-context/single-channel on pre-NV4x */ + switch (dev->chipset & 0xf0) { + case 0x40: + case 0x60: + /* NV40 class */ + case 0x50: + case 0x80: + case 0x90: + /* G80 class */ + break; + default: + nvc = NULL; + break; + } + + if (!nvc) { + nvc = nouveau_channel_context_create(dev); + if (!nvc) { + NOUVEAU_ERR("Failed initialising GPU context\n"); + return GL_FALSE; + } + nv_screen->nvc = nvc; + } + + nvc->refcount++; + nv->nvc = nvc; + + /* Find a free slot for a pipe context, allocate a new one if needed */ + nv->pctx_id = -1; + for (i = 0; i < nvc->nr_pctx; i++) { + if (nvc->pctx[i] == NULL) { + nv->pctx_id = i; + break; + } + } + + if (nv->pctx_id < 0) { + nv->pctx_id = nvc->nr_pctx++; + nvc->pctx = + realloc(nvc->pctx, + sizeof(struct pipe_context *) * nvc->nr_pctx); + } + + /* Create pipe */ + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + if (nouveau_surface_init_nv50(nv)) + return GL_FALSE; + break; + default: + if (nouveau_surface_init_nv04(nv)) + return GL_FALSE; + break; + } + + if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { + struct pipe_screen *pscreen; + + pipe = nouveau_pipe_create(nv); + if (!pipe) + NOUVEAU_ERR("Couldn't create hw pipe\n"); + pscreen = nvc->pscreen; + + nv->cap.hw_vertex_buffer = + pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF); + nv->cap.hw_index_buffer = + pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF); + } + + if (!pipe) { + NOUVEAU_MSG("Using softpipe\n"); + pipe = nouveau_create_softpipe(nv); + if (!pipe) { + NOUVEAU_ERR("Error creating pipe, bailing\n"); + return GL_FALSE; + } + } + + pipe->priv = nv; + nv->st = st_create_context(pipe, glVis, st_share); + return GL_TRUE; +} + +void +nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) +{ + struct nouveau_context *nv = driContextPriv->driverPrivate; + struct nouveau_channel_context *nvc = nv->nvc; + + assert(nv); + + st_finish(nv->st); + st_destroy_context(nv->st); + + if (nv->pctx_id >= 0) { + nvc->pctx[nv->pctx_id] = NULL; + if (--nvc->refcount <= 0) { + nouveau_channel_context_destroy(nvc); + nv->nv_screen->nvc = NULL; + } + } + + 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/nouveau_context.h b/src/gallium/winsys/drm/nouveau/nouveau_context.h new file mode 100644 index 0000000000..77e2147a2c --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_context.h @@ -0,0 +1,113 @@ +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +#include "dri_util.h" +#include "xmlconfig.h" + +#include "nouveau/nouveau_winsys.h" +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +struct nouveau_framebuffer { + struct st_framebuffer *stfb; +}; + +struct nouveau_channel_context { + struct pipe_screen *pscreen; + int refcount; + + unsigned cur_pctx; + unsigned nr_pctx; + struct pipe_context **pctx; + + struct nouveau_channel *channel; + + struct nouveau_notifier *sync_notifier; + + /* Common */ + struct nouveau_grobj *NvM2MF; + /* NV04-NV40 */ + struct nouveau_grobj *NvCtxSurf2D; + struct nouveau_grobj *NvSwzSurf; + struct nouveau_grobj *NvImageBlit; + struct nouveau_grobj *NvGdiRect; + struct nouveau_grobj *NvSIFM; + /* G80 */ + struct nouveau_grobj *Nv2D; + + uint32_t next_handle; + uint32_t next_subchannel; + uint32_t next_sequence; +}; + +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; + GLboolean locked; + struct nouveau_screen *nv_screen; + struct pipe_surface *frontbuffer; + + struct { + int hw_vertex_buffer; + int hw_index_buffer; + } cap; + + /* Hardware context */ + struct nouveau_channel_context *nvc; + int pctx_id; + + /* pipe_surface accel */ + struct pipe_surface *surf_src, *surf_dst; + unsigned surf_src_offset, surf_dst_offset; + int (*surface_copy_prep)(struct nouveau_context *, + struct pipe_surface *dst, + struct pipe_surface *src); + void (*surface_copy)(struct nouveau_context *, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h); + void (*surface_copy_done)(struct nouveau_context *); + int (*surface_fill)(struct nouveau_context *, struct pipe_surface *, + unsigned, unsigned, unsigned, unsigned, unsigned); +}; + +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 *); + +#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 + +extern void LOCK_HARDWARE(struct nouveau_context *); +extern void UNLOCK_HARDWARE(struct nouveau_context *); + +extern int +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *); +extern int +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *); +extern int nouveau_surface_init_nv04(struct nouveau_context *); +extern int nouveau_surface_init_nv50(struct nouveau_context *); + +extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int); +extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *); + +#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_device.c b/src/gallium/winsys/drm/nouveau/nouveau_device.c new file mode 100644 index 0000000000..0b452fcd02 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_device.c @@ -0,0 +1,159 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include + +#include "nouveau_drmif.h" + +int +nouveau_device_open_existing(struct nouveau_device **dev, int close, + int fd, drm_context_t ctx) +{ + struct nouveau_device_priv *nvdev; + int ret; + + if (!dev || *dev) + return -EINVAL; + + nvdev = calloc(1, sizeof(*nvdev)); + if (!nvdev) + return -ENOMEM; + nvdev->fd = fd; + nvdev->ctx = ctx; + nvdev->needs_close = close; + + drmCommandNone(nvdev->fd, DRM_NOUVEAU_CARD_INIT); + + if ((ret = nouveau_bo_init(&nvdev->base))) { + nouveau_device_close((void *)&nvdev); + return ret; + } + + { + uint64_t value; + + ret = nouveau_device_get_param(&nvdev->base, + NOUVEAU_GETPARAM_CHIPSET_ID, + &value); + if (ret) { + nouveau_device_close((void *)&nvdev); + return ret; + } + nvdev->base.chipset = value; + } + + *dev = &nvdev->base; + return 0; +} + +int +nouveau_device_open(struct nouveau_device **dev, const char *busid) +{ + drm_context_t ctx; + int fd, ret; + + if (!dev || *dev) + return -EINVAL; + + fd = drmOpen("nouveau", busid); + if (fd < 0) + return -EINVAL; + + ret = drmCreateContext(fd, &ctx); + if (ret) { + drmClose(fd); + return ret; + } + + ret = nouveau_device_open_existing(dev, 1, fd, ctx); + if (ret) { + drmDestroyContext(fd, ctx); + drmClose(fd); + return ret; + } + + return 0; +} + +void +nouveau_device_close(struct nouveau_device **dev) +{ + struct nouveau_device_priv *nvdev; + + if (dev || !*dev) + return; + nvdev = nouveau_device(*dev); + *dev = NULL; + + nouveau_bo_takedown(&nvdev->base); + + if (nvdev->needs_close) { + drmDestroyContext(nvdev->fd, nvdev->ctx); + drmClose(nvdev->fd); + } + free(nvdev); +} + +int +nouveau_device_get_param(struct nouveau_device *dev, + uint64_t param, uint64_t *value) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct drm_nouveau_getparam g; + int ret; + + if (!nvdev || !value) + return -EINVAL; + + g.param = param; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GETPARAM, + &g, sizeof(g)); + if (ret) + return ret; + + *value = g.value; + return 0; +} + +int +nouveau_device_set_param(struct nouveau_device *dev, + uint64_t param, uint64_t value) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct drm_nouveau_setparam s; + int ret; + + if (!nvdev) + return -EINVAL; + + s.param = param; + s.value = value; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_SETPARAM, + &s, sizeof(s)); + if (ret) + return ret; + + return 0; +} + diff --git a/src/gallium/winsys/drm/nouveau/nouveau_dma.c b/src/gallium/winsys/drm/nouveau/nouveau_dma.c new file mode 100644 index 0000000000..f8a8ba04f6 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_dma.c @@ -0,0 +1,219 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" +#include "nouveau_local.h" + +static inline uint32_t +READ_GET(struct nouveau_channel_priv *nvchan) +{ + return *nvchan->get; +} + +static inline void +WRITE_PUT(struct nouveau_channel_priv *nvchan, uint32_t val) +{ + uint32_t put = ((val << 2) + nvchan->dma->base); + volatile int dum; + + NOUVEAU_DMA_BARRIER; + dum = READ_GET(nvchan); + + *nvchan->put = put; + nvchan->dma->put = val; +#ifdef NOUVEAU_DMA_TRACE + NOUVEAU_MSG("WRITE_PUT %d/0x%08x\n", nvchan->drm.channel, put); +#endif + + NOUVEAU_DMA_BARRIER; +} + +static inline int +LOCAL_GET(struct nouveau_dma_priv *dma, uint32_t *val) +{ + uint32_t get = *val; + + if (get >= dma->base && get <= (dma->base + (dma->max << 2))) { + *val = (get - dma->base) >> 2; + return 1; + } + + return 0; +} + +void +nouveau_dma_channel_init(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + int i; + + nvchan->dma = &nvchan->dma_master; + nvchan->dma->base = nvchan->drm.put_base; + nvchan->dma->cur = nvchan->dma->put = 0; + nvchan->dma->max = (nvchan->drm.cmdbuf_size >> 2) - 2; + nvchan->dma->free = nvchan->dma->max - nvchan->dma->cur; + + RING_SPACE_CH(chan, RING_SKIPS); + for (i = 0; i < RING_SKIPS; i++) + OUT_RING_CH(chan, 0); +} + +#define CHECK_TIMEOUT() do { \ + if ((NOUVEAU_TIME_MSEC() - t_start) > NOUVEAU_DMA_TIMEOUT) \ + return - EBUSY; \ +} while(0) + +int +nouveau_dma_wait(struct nouveau_channel *chan, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + uint32_t get, t_start; + + FIRE_RING_CH(chan); + + t_start = NOUVEAU_TIME_MSEC(); + while (dma->free < size) { + CHECK_TIMEOUT(); + + get = READ_GET(nvchan); + if (!LOCAL_GET(dma, &get)) + continue; + + if (dma->put >= get) { + dma->free = dma->max - dma->cur; + + if (dma->free < size) { +#ifdef NOUVEAU_DMA_DEBUG + dma->push_free = 1; +#endif + OUT_RING_CH(chan, 0x20000000 | dma->base); + if (get <= RING_SKIPS) { + /*corner case - will be idle*/ + if (dma->put <= RING_SKIPS) + WRITE_PUT(nvchan, + RING_SKIPS + 1); + + do { + CHECK_TIMEOUT(); + get = READ_GET(nvchan); + if (!LOCAL_GET(dma, &get)) + get = 0; + } while (get <= RING_SKIPS); + } + + WRITE_PUT(nvchan, RING_SKIPS); + dma->cur = dma->put = RING_SKIPS; + dma->free = get - (RING_SKIPS + 1); + } + } else { + dma->free = get - dma->cur - 1; + } + } + + return 0; +} + +#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF +static void +nouveau_dma_parse_pushbuf(struct nouveau_channel *chan, int get, int put) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + unsigned mthd_count = 0; + + while (get != put) { + uint32_t gpuget = (get << 2) + nvchan->drm.put_base; + uint32_t data; + + if (get < 0 || get >= nvchan->drm.cmdbuf_size) { + NOUVEAU_ERR("DMA_PT 0x%08x\n", gpuget); + assert(0); + } + data = nvchan->pushbuf[get++]; + + if (mthd_count) { + NOUVEAU_MSG("0x%08x 0x%08x\n", gpuget, data); + mthd_count--; + continue; + } + + switch (data & 0x60000000) { + case 0x00000000: + mthd_count = (data >> 18) & 0x7ff; + NOUVEAU_MSG("0x%08x 0x%08x MTHD " + "Sc %d Mthd 0x%04x Size %d\n", + gpuget, data, (data>>13) & 7, data & 0x1ffc, + mthd_count); + break; + case 0x20000000: + get = (data & 0x1ffffffc) >> 2; + NOUVEAU_MSG("0x%08x 0x%08x JUMP 0x%08x\n", + gpuget, data, data & 0x1ffffffc); + continue; + case 0x40000000: + mthd_count = (data >> 18) & 0x7ff; + NOUVEAU_MSG("0x%08x 0x%08x NINC " + "Sc %d Mthd 0x%04x Size %d\n", + gpuget, data, (data>>13) & 7, data & 0x1ffc, + mthd_count); + break; + case 0x60000000: + /* DMA_OPCODE_CALL apparently, doesn't seem to work on + * my NV40 at least.. + */ + /* fall-through */ + default: + NOUVEAU_MSG("DMA_PUSHER 0x%08x 0x%08x\n", + gpuget, data); + assert(0); + } + } +} +#endif + +void +nouveau_dma_kickoff(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + + if (dma->cur == dma->put) + return; + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free) { + NOUVEAU_ERR("Packet incomplete: %d left\n", dma->push_free); + return; + } +#endif + +#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF + nouveau_dma_parse_pushbuf(chan, dma->put, dma->cur); +#endif + + WRITE_PUT(nvchan, dma->cur); +} diff --git a/src/gallium/winsys/drm/nouveau/nouveau_dma.h b/src/gallium/winsys/drm/nouveau/nouveau_dma.h new file mode 100644 index 0000000000..cfa6d26e82 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_dma.h @@ -0,0 +1,143 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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. + */ + +#ifndef __NOUVEAU_DMA_H__ +#define __NOUVEAU_DMA_H__ + +#include +#include "nouveau_drmif.h" +#include "nouveau_local.h" + +#define RING_SKIPS 8 + +extern int nouveau_dma_wait(struct nouveau_channel *chan, int size); +extern void nouveau_dma_subc_bind(struct nouveau_grobj *); +extern void nouveau_dma_channel_init(struct nouveau_channel *); +extern void nouveau_dma_kickoff(struct nouveau_channel *); + +#ifdef NOUVEAU_DMA_DEBUG +static char faulty[1024]; +#endif + +static inline void +nouveau_dma_out(struct nouveau_channel *chan, uint32_t data) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free == 0) { + NOUVEAU_ERR("No space left in packet at %s\n", faulty); + return; + } + dma->push_free--; +#endif +#ifdef NOUVEAU_DMA_TRACE + { + uint32_t offset = (dma->cur << 2) + dma->base; + NOUVEAU_MSG("\tOUT_RING %d/0x%08x -> 0x%08x\n", + nvchan->drm.channel, offset, data); + } +#endif + nvchan->pushbuf[dma->cur + (dma->base - nvchan->drm.put_base)/4] = data; + dma->cur++; +} + +static inline void +nouveau_dma_outp(struct nouveau_channel *chan, uint32_t *ptr, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + (void)dma; + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free < size) { + NOUVEAU_ERR("Packet too small. Free=%d, Need=%d\n", + dma->push_free, size); + return; + } +#endif +#ifdef NOUVEAU_DMA_TRACE + while (size--) { + nouveau_dma_out(chan, *ptr); + ptr++; + } +#else + memcpy(&nvchan->pushbuf[dma->cur], ptr, size << 2); +#ifdef NOUVEAU_DMA_DEBUG + dma->push_free -= size; +#endif + dma->cur += size; +#endif +} + +static inline void +nouveau_dma_space(struct nouveau_channel *chan, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + + if (dma->free < size) { + if (nouveau_dma_wait(chan, size) && chan->hang_notify) + chan->hang_notify(chan); + } + dma->free -= size; +#ifdef NOUVEAU_DMA_DEBUG + dma->push_free = size; +#endif +} + +static inline void +nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj, + int method, int size, const char* file, int line) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + (void)dma; + +#ifdef NOUVEAU_DMA_TRACE + NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", nvchan->drm.channel, + grobj->handle, grobj->subc, method, size); +#endif + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free) { + NOUVEAU_ERR("Previous packet incomplete: %d left at %s\n", + dma->push_free, faulty); + return; + } + sprintf(faulty,"%s:%d",file,line); +#endif + + nouveau_dma_space(chan, (size + 1)); + nouveau_dma_out(chan, (size << 18) | (grobj->subc << 13) | method); +} + +#define RING_SPACE_CH(ch,sz) nouveau_dma_space((ch), (sz)) +#define BEGIN_RING_CH(ch,gr,m,sz) nouveau_dma_begin((ch), (gr), (m), (sz), __FUNCTION__, __LINE__ ) +#define OUT_RING_CH(ch, data) nouveau_dma_out((ch), (data)) +#define OUT_RINGp_CH(ch,ptr,dwords) nouveau_dma_outp((ch), (void*)(ptr), \ + (dwords)) +#define FIRE_RING_CH(ch) nouveau_dma_kickoff((ch)) +#define WAIT_RING_CH(ch,sz) nouveau_dma_wait((ch), (sz)) + +#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/nouveau_dri.h new file mode 100644 index 0000000000..1207c2d609 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_dri.h @@ -0,0 +1,28 @@ +#ifndef _NOUVEAU_DRI_ +#define _NOUVEAU_DRI_ + +#include "xf86drm.h" +#include "drm.h" +#include "nouveau_drm.h" + +struct nouveau_dri { + uint32_t device_id; /**< \brief PCI device ID */ + uint32_t width; /**< \brief width in pixels of display */ + uint32_t height; /**< \brief height in scanlines of display */ + uint32_t depth; /**< \brief depth of display (8, 15, 16, 24) */ + uint32_t bpp; /**< \brief bit depth of display (8, 16, 24, 32) */ + + uint32_t bus_type; /**< \brief ths bus type */ + uint32_t bus_mode; /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */ + + uint32_t front_offset; /**< \brief front buffer offset */ + uint32_t front_pitch; /**< \brief front buffer pitch */ + uint32_t back_offset; /**< \brief private back buffer offset */ + uint32_t back_pitch; /**< \brief private back buffer pitch */ + uint32_t depth_offset; /**< \brief private depth buffer offset */ + uint32_t depth_pitch; /**< \brief private depth buffer pitch */ + +}; + +#endif + diff --git a/src/gallium/winsys/drm/nouveau/nouveau_drmif.h b/src/gallium/winsys/drm/nouveau/nouveau_drmif.h new file mode 100644 index 0000000000..dcd6a5eb0a --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_drmif.h @@ -0,0 +1,310 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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. + */ + +#ifndef __NOUVEAU_DRMIF_H__ +#define __NOUVEAU_DRMIF_H__ + +#include +#include +#include + +#include "nouveau/nouveau_device.h" +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_grobj.h" +#include "nouveau/nouveau_notifier.h" +#include "nouveau/nouveau_bo.h" +#include "nouveau/nouveau_resource.h" +#include "nouveau/nouveau_pushbuf.h" + +struct nouveau_device_priv { + struct nouveau_device base; + + int fd; + drm_context_t ctx; + drmLock *lock; + int needs_close; + + struct drm_nouveau_mem_alloc sa; + void *sa_map; + struct nouveau_resource *sa_heap; +}; +#define nouveau_device(n) ((struct nouveau_device_priv *)(n)) + +extern int +nouveau_device_open_existing(struct nouveau_device **, int close, + int fd, drm_context_t ctx); + +extern int +nouveau_device_open(struct nouveau_device **, const char *busid); + +extern void +nouveau_device_close(struct nouveau_device **); + +extern int +nouveau_device_get_param(struct nouveau_device *, uint64_t param, uint64_t *v); + +extern int +nouveau_device_set_param(struct nouveau_device *, uint64_t param, uint64_t val); + +struct nouveau_fence { + struct nouveau_channel *channel; +}; + +struct nouveau_fence_cb { + struct nouveau_fence_cb *next; + void (*func)(void *); + void *priv; +}; + +struct nouveau_fence_priv { + struct nouveau_fence base; + int refcount; + + struct nouveau_fence *next; + struct nouveau_fence_cb *signal_cb; + + uint32_t sequence; + int emitted; + int signalled; +}; +#define nouveau_fence(n) ((struct nouveau_fence_priv *)(n)) + +extern int +nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **); + +extern int +nouveau_fence_ref(struct nouveau_fence *, struct nouveau_fence **); + +extern int +nouveau_fence_signal_cb(struct nouveau_fence *, void (*)(void *), void *); + +extern void +nouveau_fence_emit(struct nouveau_fence *); + +extern int +nouveau_fence_wait(struct nouveau_fence **); + +extern void +nouveau_fence_flush(struct nouveau_channel *); + +struct nouveau_pushbuf_reloc { + struct nouveau_pushbuf_bo *pbbo; + uint32_t *ptr; + uint32_t flags; + uint32_t data; + uint32_t vor; + uint32_t tor; +}; + +struct nouveau_pushbuf_bo { + struct nouveau_channel *channel; + struct nouveau_bo *bo; + unsigned flags; + unsigned handled; +}; + +#define NOUVEAU_PUSHBUF_MAX_BUFFERS 1024 +#define NOUVEAU_PUSHBUF_MAX_RELOCS 1024 +struct nouveau_pushbuf_priv { + struct nouveau_pushbuf base; + + struct nouveau_fence *fence; + + unsigned nop_jump; + unsigned start; + unsigned size; + + struct nouveau_pushbuf_bo *buffers; + unsigned nr_buffers; + struct nouveau_pushbuf_reloc *relocs; + unsigned nr_relocs; +}; +#define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n)) + +#define pbbo_to_ptr(o) ((uint64_t)(unsigned long)(o)) +#define ptr_to_pbbo(h) ((struct nouveau_pushbuf_bo *)(unsigned long)(h)) +#define pbrel_to_ptr(o) ((uint64_t)(unsigned long)(o)) +#define ptr_to_pbrel(h) ((struct nouveau_pushbuf_reloc *)(unsigned long)(h)) +#define bo_to_ptr(o) ((uint64_t)(unsigned long)(o)) +#define ptr_to_bo(h) ((struct nouveau_bo_priv *)(unsigned long)(h)) + +extern int +nouveau_pushbuf_init(struct nouveau_channel *); + +extern int +nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); + +extern int +nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr, + struct nouveau_bo *, uint32_t data, uint32_t flags, + uint32_t vor, uint32_t tor); + +struct nouveau_dma_priv { + uint32_t base; + uint32_t max; + uint32_t cur; + uint32_t put; + uint32_t free; + + int push_free; +} dma; + +struct nouveau_channel_priv { + struct nouveau_channel base; + + struct drm_nouveau_channel_alloc drm; + + uint32_t *pushbuf; + void *notifier_block; + + volatile uint32_t *user; + volatile uint32_t *put; + volatile uint32_t *get; + volatile uint32_t *ref_cnt; + + struct nouveau_dma_priv dma_master; + struct nouveau_dma_priv dma_bufmgr; + struct nouveau_dma_priv *dma; + + struct nouveau_fence *fence_head; + struct nouveau_fence *fence_tail; + uint32_t fence_sequence; + + struct nouveau_pushbuf_priv pb; + + unsigned user_charge; +}; +#define nouveau_channel(n) ((struct nouveau_channel_priv *)(n)) + +extern int +nouveau_channel_alloc(struct nouveau_device *, uint32_t fb, uint32_t tt, + struct nouveau_channel **); + +extern void +nouveau_channel_free(struct nouveau_channel **); + +struct nouveau_grobj_priv { + struct nouveau_grobj base; +}; +#define nouveau_grobj(n) ((struct nouveau_grobj_priv *)(n)) + +extern int nouveau_grobj_alloc(struct nouveau_channel *, uint32_t handle, + int class, struct nouveau_grobj **); +extern int nouveau_grobj_ref(struct nouveau_channel *, uint32_t handle, + struct nouveau_grobj **); +extern void nouveau_grobj_free(struct nouveau_grobj **); + + +struct nouveau_notifier_priv { + struct nouveau_notifier base; + + struct drm_nouveau_notifierobj_alloc drm; + volatile void *map; +}; +#define nouveau_notifier(n) ((struct nouveau_notifier_priv *)(n)) + +extern int +nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, int count, + struct nouveau_notifier **); + +extern void +nouveau_notifier_free(struct nouveau_notifier **); + +extern void +nouveau_notifier_reset(struct nouveau_notifier *, int id); + +extern uint32_t +nouveau_notifier_status(struct nouveau_notifier *, int id); + +extern uint32_t +nouveau_notifier_return_val(struct nouveau_notifier *, int id); + +extern int +nouveau_notifier_wait_status(struct nouveau_notifier *, int id, int status, + int timeout); + +struct nouveau_bo_priv { + struct nouveau_bo base; + + struct nouveau_pushbuf_bo *pending; + struct nouveau_fence *fence; + struct nouveau_fence *wr_fence; + + struct drm_nouveau_mem_alloc drm; + void *map; + + void *sysmem; + int user; + + int refcount; + + uint64_t offset; + uint64_t flags; + int tiled; +}; +#define nouveau_bo(n) ((struct nouveau_bo_priv *)(n)) + +extern int +nouveau_bo_init(struct nouveau_device *); + +extern void +nouveau_bo_takedown(struct nouveau_device *); + +extern int +nouveau_bo_new(struct nouveau_device *, uint32_t flags, int align, int size, + struct nouveau_bo **); + +extern int +nouveau_bo_user(struct nouveau_device *, void *ptr, int size, + struct nouveau_bo **); + +extern int +nouveau_bo_ref(struct nouveau_device *, uint64_t handle, struct nouveau_bo **); + +extern int +nouveau_bo_set_status(struct nouveau_bo *, uint32_t flags); + +extern void +nouveau_bo_del(struct nouveau_bo **); + +extern int +nouveau_bo_map(struct nouveau_bo *, uint32_t flags); + +extern void +nouveau_bo_unmap(struct nouveau_bo *); + +extern int +nouveau_bo_validate(struct nouveau_channel *, struct nouveau_bo *, + uint32_t flags); + +extern int +nouveau_resource_init(struct nouveau_resource **heap, unsigned start, + unsigned size); + +extern int +nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, + struct nouveau_resource **); + +extern void +nouveau_resource_free(struct nouveau_resource **); + +#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_fence.c b/src/gallium/winsys/drm/nouveau/nouveau_fence.c new file mode 100644 index 0000000000..e7b0b4ff07 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_fence.c @@ -0,0 +1,214 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" +#include "nouveau_local.h" + +static void +nouveau_fence_del_unsignalled(struct nouveau_fence *fence) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); + struct nouveau_fence *le; + + if (nvchan->fence_head == fence) { + nvchan->fence_head = nouveau_fence(fence)->next; + if (nvchan->fence_head == NULL) + nvchan->fence_tail = NULL; + return; + } + + le = nvchan->fence_head; + while (le && nouveau_fence(le)->next != fence) + le = nouveau_fence(le)->next; + assert(le && nouveau_fence(le)->next == fence); + nouveau_fence(le)->next = nouveau_fence(fence)->next; + if (nvchan->fence_tail == fence) + nvchan->fence_tail = le; +} + +static void +nouveau_fence_del(struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!fence || !*fence) + return; + nvfence = nouveau_fence(*fence); + *fence = NULL; + + if (--nvfence->refcount) + return; + + if (nvfence->emitted && !nvfence->signalled) { + if (nvfence->signal_cb) { + nvfence->refcount++; + nouveau_fence_wait((void *)&nvfence); + return; + } + + nouveau_fence_del_unsignalled(&nvfence->base); + } + free(nvfence); +} + +int +nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!chan || !fence || *fence) + return -EINVAL; + + nvfence = calloc(1, sizeof(struct nouveau_fence_priv)); + if (!nvfence) + return -ENOMEM; + nvfence->base.channel = chan; + nvfence->refcount = 1; + + *fence = &nvfence->base; + return 0; +} + +int +nouveau_fence_ref(struct nouveau_fence *ref, struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!fence) + return -EINVAL; + + if (*fence) { + nouveau_fence_del(fence); + *fence = NULL; + } + + if (ref) { + nvfence = nouveau_fence(ref); + nvfence->refcount++; + *fence = &nvfence->base; + } + + return 0; +} + +int +nouveau_fence_signal_cb(struct nouveau_fence *fence, void (*func)(void *), + void *priv) +{ + struct nouveau_fence_priv *nvfence = nouveau_fence(fence); + struct nouveau_fence_cb *cb; + + if (!nvfence || !func) + return -EINVAL; + + cb = malloc(sizeof(struct nouveau_fence_cb)); + if (!cb) + return -ENOMEM; + + cb->func = func; + cb->priv = priv; + cb->next = nvfence->signal_cb; + nvfence->signal_cb = cb; + return 0; +} + +void +nouveau_fence_emit(struct nouveau_fence *fence) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); + struct nouveau_fence_priv *nvfence = nouveau_fence(fence); + + nvfence->emitted = 1; + nvfence->sequence = ++nvchan->fence_sequence; + if (nvfence->sequence == 0xffffffff) + NOUVEAU_ERR("AII wrap unhandled\n"); + + /*XXX: assumes subc 0 is populated */ + RING_SPACE_CH(fence->channel, 2); + OUT_RING_CH (fence->channel, 0x00040050); + OUT_RING_CH (fence->channel, nvfence->sequence); + + if (nvchan->fence_tail) { + nouveau_fence(nvchan->fence_tail)->next = fence; + } else { + nvchan->fence_head = fence; + } + nvchan->fence_tail = fence; +} + +void +nouveau_fence_flush(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + uint32_t sequence = *nvchan->ref_cnt; + + while (nvchan->fence_head) { + struct nouveau_fence_priv *nvfence; + + nvfence = nouveau_fence(nvchan->fence_head); + if (nvfence->sequence > sequence) + break; + nouveau_fence_del_unsignalled(&nvfence->base); + nvfence->signalled = 1; + + if (nvfence->signal_cb) { + struct nouveau_fence *fence = NULL; + + nouveau_fence_ref(&nvfence->base, &fence); + + while (nvfence->signal_cb) { + struct nouveau_fence_cb *cb; + + cb = nvfence->signal_cb; + nvfence->signal_cb = cb->next; + cb->func(cb->priv); + free(cb); + } + + nouveau_fence_ref(NULL, &fence); + } + } +} + +int +nouveau_fence_wait(struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!fence || !*fence) + return -EINVAL; + nvfence = nouveau_fence(*fence); + + if (nvfence->emitted) { + while (!nvfence->signalled) + nouveau_fence_flush(nvfence->base.channel); + } + nouveau_fence_ref(NULL, fence); + + return 0; +} + diff --git a/src/gallium/winsys/drm/nouveau/nouveau_grobj.c b/src/gallium/winsys/drm/nouveau/nouveau_grobj.c new file mode 100644 index 0000000000..51523897d5 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_grobj.c @@ -0,0 +1,107 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include + +#include "nouveau_drmif.h" + +int +nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle, + int class, struct nouveau_grobj **grobj) +{ + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_grobj_priv *nvgrobj; + struct drm_nouveau_grobj_alloc g; + int ret; + + if (!nvdev || !grobj || *grobj) + return -EINVAL; + + nvgrobj = calloc(1, sizeof(*nvgrobj)); + if (!nvgrobj) + return -ENOMEM; + nvgrobj->base.channel = chan; + nvgrobj->base.handle = handle; + nvgrobj->base.grclass = class; + + g.channel = chan->id; + g.handle = handle; + g.class = class; + ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GROBJ_ALLOC, + &g, sizeof(g)); + if (ret) { + nouveau_grobj_free((void *)&nvgrobj); + return ret; + } + + *grobj = &nvgrobj->base; + return 0; +} + +int +nouveau_grobj_ref(struct nouveau_channel *chan, uint32_t handle, + struct nouveau_grobj **grobj) +{ + struct nouveau_grobj_priv *nvgrobj; + + if (!chan || !grobj || *grobj) + return -EINVAL; + + nvgrobj = calloc(1, sizeof(struct nouveau_grobj_priv)); + if (!nvgrobj) + return -ENOMEM; + nvgrobj->base.channel = chan; + nvgrobj->base.handle = handle; + nvgrobj->base.grclass = 0; + + *grobj = &nvgrobj->base; + return 0; +} + +void +nouveau_grobj_free(struct nouveau_grobj **grobj) +{ + struct nouveau_device_priv *nvdev; + struct nouveau_channel_priv *chan; + struct nouveau_grobj_priv *nvgrobj; + + if (!grobj || !*grobj) + return; + nvgrobj = nouveau_grobj(*grobj); + *grobj = NULL; + + + chan = nouveau_channel(nvgrobj->base.channel); + nvdev = nouveau_device(chan->base.device); + + if (nvgrobj->base.grclass) { + struct drm_nouveau_gpuobj_free f; + + f.channel = chan->drm.channel; + f.handle = nvgrobj->base.handle; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, + &f, sizeof(f)); + } + free(nvgrobj); +} + diff --git a/src/gallium/winsys/drm/nouveau/nouveau_local.h b/src/gallium/winsys/drm/nouveau/nouveau_local.h new file mode 100644 index 0000000000..e878a40803 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_local.h @@ -0,0 +1,117 @@ +#ifndef __NOUVEAU_LOCAL_H__ +#define __NOUVEAU_LOCAL_H__ + +#include "pipe/p_compiler.h" +#include "nouveau_winsys_pipe.h" +#include + +struct pipe_buffer; + +/* Debug output */ +#define NOUVEAU_MSG(fmt, args...) do { \ + fprintf(stdout, "nouveau: "fmt, ##args); \ + fflush(stdout); \ +} while(0) + +#define NOUVEAU_ERR(fmt, args...) do { \ + fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); \ + fflush(stderr); \ +} while(0) + +#define NOUVEAU_TIME_MSEC() 0 + +/* User FIFO control */ +//#define NOUVEAU_DMA_TRACE +//#define NOUVEAU_DMA_DEBUG +//#define NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF +#define NOUVEAU_DMA_BARRIER +#define NOUVEAU_DMA_TIMEOUT 2000 + +/* Push buffer access macros */ +static INLINE void +OUT_RING(struct nouveau_channel *chan, unsigned data) +{ + *(chan->pushbuf->cur++) = (data); +} + +static INLINE void +OUT_RINGp(struct nouveau_channel *chan, uint32_t *data, unsigned size) +{ + memcpy(chan->pushbuf->cur, data, size * 4); + chan->pushbuf->cur += size; +} + +static INLINE void +OUT_RINGf(struct nouveau_channel *chan, float f) +{ + union { uint32_t i; float f; } c; + c.f = f; + OUT_RING(chan, c.i); +} + +static INLINE void +BEGIN_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, + unsigned mthd, unsigned size) +{ + if (chan->pushbuf->remaining < (size + 1)) + nouveau_pushbuf_flush(chan, (size + 1)); + OUT_RING(chan, (gr->subc << 13) | (size << 18) | mthd); + chan->pushbuf->remaining -= (size + 1); +} + +static INLINE void +FIRE_RING(struct nouveau_channel *chan) +{ + nouveau_pushbuf_flush(chan, 0); +} + +static INLINE void +BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc) +{ + gr->subc = subc; + BEGIN_RING(chan, gr, 0x0000, 1); + OUT_RING (chan, gr->handle); +} + +static INLINE void +OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, + data, flags, vor, tor); +} + +/* Raw data + flags depending on FB/TT buffer */ +static INLINE void +OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor); +} + +/* FB/TT object handle */ +static INLINE void +OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned flags) +{ + OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR, + chan->vram->handle, chan->gart->handle); +} + +/* Low 32-bits of offset */ +static INLINE void +OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned delta, unsigned flags) +{ + OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0); +} + +/* High 32-bits of offset */ +static INLINE void +OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned delta, unsigned flags) +{ + OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); +} + +#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_lock.c b/src/gallium/winsys/drm/nouveau/nouveau_lock.c new file mode 100644 index 0000000000..9adb9ac854 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_lock.c @@ -0,0 +1,94 @@ +/************************************************************************** + * + * 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 "main/glheader.h" +#include "glapi/glthread.h" +#include + +#include "nouveau_context.h" +#include "nouveau_screen.h" + +_glthread_DECLARE_STATIC_MUTEX( lockMutex ); + +static void +nouveau_contended_lock(struct nouveau_context *nv, GLuint flags) +{ + __DRIdrawablePrivate *dPriv = nv->dri_drawable; + __DRIscreenPrivate *sPriv = nv->dri_screen; + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + drmGetLock(nvdev->fd, nvdev->ctx, flags); + + /* 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); +} + +/* Lock the hardware and validate our state. + */ +void +LOCK_HARDWARE(struct nouveau_context *nv) +{ + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + char __ret=0; + + _glthread_LOCK_MUTEX(lockMutex); + assert(!nv->locked); + + DRM_CAS(nvdev->lock, nvdev->ctx, + (DRM_LOCK_HELD | nvdev->ctx), __ret); + + if (__ret) + nouveau_contended_lock(nv, 0); + nv->locked = GL_TRUE; +} + + + /* Unlock the hardware using the global current context + */ +void +UNLOCK_HARDWARE(struct nouveau_context *nv) +{ + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + assert(nv->locked); + nv->locked = GL_FALSE; + + DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx); + + _glthread_UNLOCK_MUTEX(lockMutex); +} diff --git a/src/gallium/winsys/drm/nouveau/nouveau_notifier.c b/src/gallium/winsys/drm/nouveau/nouveau_notifier.c new file mode 100644 index 0000000000..01e8f38440 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_notifier.c @@ -0,0 +1,137 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include + +#include "nouveau_drmif.h" +#include "nouveau_local.h" + +#define NOTIFIER(__v) \ + struct nouveau_notifier_priv *nvnotify = nouveau_notifier(notifier); \ + volatile uint32_t *__v = (void*)nvnotify->map + (id * 32) + +int +nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, + int count, struct nouveau_notifier **notifier) +{ + struct nouveau_notifier_priv *nvnotify; + int ret; + + if (!chan || !notifier || *notifier) + return -EINVAL; + + nvnotify = calloc(1, sizeof(struct nouveau_notifier_priv)); + if (!nvnotify) + return -ENOMEM; + nvnotify->base.channel = chan; + nvnotify->base.handle = handle; + + nvnotify->drm.channel = chan->id; + nvnotify->drm.handle = handle; + nvnotify->drm.count = count; + if ((ret = drmCommandWriteRead(nouveau_device(chan->device)->fd, + DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, + &nvnotify->drm, + sizeof(nvnotify->drm)))) { + nouveau_notifier_free((void *)&nvnotify); + return ret; + } + + nvnotify->map = (void *)nouveau_channel(chan)->notifier_block + + nvnotify->drm.offset; + *notifier = &nvnotify->base; + return 0; +} + +void +nouveau_notifier_free(struct nouveau_notifier **notifier) +{ + + struct nouveau_notifier_priv *nvnotify; + struct nouveau_channel_priv *nvchan; + struct nouveau_device_priv *nvdev; + struct drm_nouveau_gpuobj_free f; + + if (!notifier || !*notifier) + return; + nvnotify = nouveau_notifier(*notifier); + *notifier = NULL; + + nvchan = nouveau_channel(nvnotify->base.channel); + nvdev = nouveau_device(nvchan->base.device); + + f.channel = nvchan->drm.channel; + f.handle = nvnotify->base.handle; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, &f, sizeof(f)); + free(nvnotify); +} + +void +nouveau_notifier_reset(struct nouveau_notifier *notifier, int id) +{ + NOTIFIER(n); + + n[NV_NOTIFY_TIME_0 /4] = 0x00000000; + n[NV_NOTIFY_TIME_1 /4] = 0x00000000; + n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000; + n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS << + NV_NOTIFY_STATE_STATUS_SHIFT); +} + +uint32_t +nouveau_notifier_status(struct nouveau_notifier *notifier, int id) +{ + NOTIFIER(n); + + return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; +} + +uint32_t +nouveau_notifier_return_val(struct nouveau_notifier *notifier, int id) +{ + NOTIFIER(n); + + return n[NV_NOTIFY_RETURN_VALUE/4]; +} + +int +nouveau_notifier_wait_status(struct nouveau_notifier *notifier, int id, + int status, int timeout) +{ + NOTIFIER(n); + uint32_t time = 0, t_start = NOUVEAU_TIME_MSEC(); + + while (time <= timeout) { + uint32_t v; + + v = n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; + if (v == status) + return 0; + + if (timeout) + time = NOUVEAU_TIME_MSEC() - t_start; + } + + return -EBUSY; +} + diff --git a/src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c new file mode 100644 index 0000000000..815046ba85 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c @@ -0,0 +1,271 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +#define PB_BUFMGR_DWORDS (4096 / 2) +#define PB_MIN_USER_DWORDS 2048 + +static int +nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; + + assert((min + 1) <= nvchan->dma->max); + + /* Wait for enough space in push buffer */ + min = min < PB_MIN_USER_DWORDS ? PB_MIN_USER_DWORDS : min; + min += 1; /* a bit extra for the NOP */ + if (nvchan->dma->free < min) + WAIT_RING_CH(chan, min); + + /* Insert NOP, may turn into a jump later */ + RING_SPACE_CH(chan, 1); + nvpb->nop_jump = nvchan->dma->cur; + OUT_RING_CH(chan, 0); + + /* Any remaining space is available to the user */ + nvpb->start = nvchan->dma->cur; + nvpb->size = nvchan->dma->free; + nvpb->base.channel = chan; + nvpb->base.remaining = nvpb->size; + nvpb->base.cur = &nvchan->pushbuf[nvpb->start]; + + /* Create a new fence object for this "frame" */ + nouveau_fence_ref(NULL, &nvpb->fence); + nouveau_fence_new(chan, &nvpb->fence); + + return 0; +} + +int +nouveau_pushbuf_init(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *m = &nvchan->dma_master; + struct nouveau_dma_priv *b = &nvchan->dma_bufmgr; + int i; + + if (!nvchan) + return -EINVAL; + + /* Reassign last bit of push buffer for a "separate" bufmgr + * ring buffer + */ + m->max -= PB_BUFMGR_DWORDS; + m->free -= PB_BUFMGR_DWORDS; + + b->base = m->base + ((m->max + 2) << 2); + b->max = PB_BUFMGR_DWORDS - 2; + b->cur = b->put = 0; + b->free = b->max - b->cur; + + /* Some NOPs just to be safe + *XXX: RING_SKIPS + */ + nvchan->dma = b; + RING_SPACE_CH(chan, 8); + for (i = 0; i < 8; i++) + OUT_RING_CH(chan, 0); + nvchan->dma = m; + + nouveau_pushbuf_space(chan, 0); + chan->pushbuf = &nvchan->pb.base; + + nvchan->pb.buffers = calloc(NOUVEAU_PUSHBUF_MAX_BUFFERS, + sizeof(struct nouveau_pushbuf_bo)); + nvchan->pb.relocs = calloc(NOUVEAU_PUSHBUF_MAX_RELOCS, + sizeof(struct nouveau_pushbuf_reloc)); + return 0; +} + +static uint32_t +nouveau_pushbuf_calc_reloc(struct nouveau_bo *bo, + struct nouveau_pushbuf_reloc *r) +{ + uint32_t push; + + if (r->flags & NOUVEAU_BO_LOW) { + push = bo->offset + r->data; + } else + if (r->flags & NOUVEAU_BO_HIGH) { + push = (bo->offset + r->data) >> 32; + } else { + push = r->data; + } + + if (r->flags & NOUVEAU_BO_OR) { + if (bo->flags & NOUVEAU_BO_VRAM) + push |= r->vor; + else + push |= r->tor; + } + + return push; +} + +/* This would be our TTM "superioctl" */ +int +nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; + int ret, i; + + if (nvpb->base.remaining == nvpb->size) + return 0; + + nouveau_fence_flush(chan); + + nvpb->size -= nvpb->base.remaining; + nvchan->dma->cur += nvpb->size; + nvchan->dma->free -= nvpb->size; + assert(nvchan->dma->cur <= nvchan->dma->max); + + nvchan->dma = &nvchan->dma_bufmgr; + nvchan->pushbuf[nvpb->nop_jump] = 0x20000000 | + (nvchan->dma->base + (nvchan->dma->cur << 2)); + + /* Validate buffers + apply relocations */ + nvchan->user_charge = 0; + for (i = 0; i < nvpb->nr_relocs; i++) { + struct nouveau_pushbuf_reloc *r = &nvpb->relocs[i]; + struct nouveau_pushbuf_bo *pbbo = r->pbbo; + struct nouveau_bo *bo = pbbo->bo; + + /* Validated, mem matches presumed, no relocation necessary */ + if (pbbo->handled & 2) { + if (!(pbbo->handled & 1)) + assert(0); + continue; + } + + /* Not yet validated, do it now */ + if (!(pbbo->handled & 1)) { + ret = nouveau_bo_validate(chan, bo, pbbo->flags); + if (ret) { + assert(0); + return ret; + } + pbbo->handled |= 1; + + if (bo->offset == nouveau_bo(bo)->offset && + bo->flags == nouveau_bo(bo)->flags) { + pbbo->handled |= 2; + continue; + } + bo->offset = nouveau_bo(bo)->offset; + bo->flags = nouveau_bo(bo)->flags; + } + + /* Apply the relocation */ + *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); + } + nvpb->nr_relocs = 0; + + /* Dereference all buffers on validate list */ + for (i = 0; i < nvpb->nr_buffers; i++) { + struct nouveau_pushbuf_bo *pbbo = &nvpb->buffers[i]; + + nouveau_bo(pbbo->bo)->pending = NULL; + nouveau_bo_del(&pbbo->bo); + } + nvpb->nr_buffers = 0; + + /* Switch back to user's ring */ + RING_SPACE_CH(chan, 1); + OUT_RING_CH(chan, 0x20000000 | ((nvpb->start << 2) + + nvchan->dma_master.base)); + nvchan->dma = &nvchan->dma_master; + + /* Fence + kickoff */ + nouveau_fence_emit(nvpb->fence); + FIRE_RING_CH(chan); + + /* Allocate space for next push buffer */ + ret = nouveau_pushbuf_space(chan, min); + assert(!ret); + + return 0; +} + +static struct nouveau_pushbuf_bo * +nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) +{ + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_pushbuf_bo *pbbo; + + if (nvbo->pending) + return nvbo->pending; + + if (nvpb->nr_buffers >= NOUVEAU_PUSHBUF_MAX_BUFFERS) + return NULL; + pbbo = nvpb->buffers + nvpb->nr_buffers++; + nvbo->pending = pbbo; + + nouveau_bo_ref(bo->device, bo->handle, &pbbo->bo); + pbbo->channel = chan; + pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + pbbo->handled = 0; + return pbbo; +} + +int +nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, + struct nouveau_bo *bo, uint32_t data, uint32_t flags, + uint32_t vor, uint32_t tor) +{ + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); + struct nouveau_pushbuf_bo *pbbo; + struct nouveau_pushbuf_reloc *r; + + if (nvpb->nr_relocs >= NOUVEAU_PUSHBUF_MAX_RELOCS) + return -ENOMEM; + + pbbo = nouveau_pushbuf_emit_buffer(chan, bo); + if (!pbbo) + return -ENOMEM; + pbbo->flags |= (flags & NOUVEAU_BO_RDWR); + pbbo->flags &= (flags | NOUVEAU_BO_RDWR); + + r = nvpb->relocs + nvpb->nr_relocs++; + r->pbbo = pbbo; + r->ptr = ptr; + r->flags = flags; + r->data = data; + r->vor = vor; + r->tor = tor; + + if (flags & NOUVEAU_BO_DUMMY) + *(uint32_t *)ptr = 0; + else + *(uint32_t *)ptr = nouveau_pushbuf_calc_reloc(bo, r); + return 0; +} + diff --git a/src/gallium/winsys/drm/nouveau/nouveau_resource.c b/src/gallium/winsys/drm/nouveau/nouveau_resource.c new file mode 100644 index 0000000000..3bbcb5c45e --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_resource.c @@ -0,0 +1,116 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include + +#include "nouveau_drmif.h" +#include "nouveau_local.h" + +int +nouveau_resource_init(struct nouveau_resource **heap, + unsigned start, unsigned size) +{ + struct nouveau_resource *r; + + r = calloc(1, sizeof(struct nouveau_resource)); + if (!r) + return 1; + + r->start = start; + r->size = size; + *heap = r; + return 0; +} + +int +nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, + struct nouveau_resource **res) +{ + struct nouveau_resource *r; + + if (!heap || !size || !res || *res) + return 1; + + while (heap) { + if (!heap->in_use && heap->size >= size) { + r = calloc(1, sizeof(struct nouveau_resource)); + if (!r) + return 1; + + r->start = (heap->start + heap->size) - size; + r->size = size; + r->in_use = 1; + r->priv = priv; + + heap->size -= size; + + r->next = heap->next; + if (heap->next) + heap->next->prev = r; + r->prev = heap; + heap->next = r; + + *res = r; + return 0; + } + + heap = heap->next; + } + + return 1; +} + +void +nouveau_resource_free(struct nouveau_resource **res) +{ + struct nouveau_resource *r; + + if (!res || !*res) + return; + r = *res; + *res = NULL; + + r->in_use = 0; + + if (r->next && !r->next->in_use) { + struct nouveau_resource *new = r->next; + + new->prev = r->prev; + if (r->prev) + r->prev->next = new; + new->size += r->size; + new->start = r->start; + + free(r); + r = new; + } + + if (r->prev && !r->prev->in_use) { + r->prev->next = r->next; + if (r->next) + r->next->prev = r->prev; + r->prev->size += r->size; + free(r); + } + +} diff --git a/src/gallium/winsys/drm/nouveau/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/nouveau_screen.c new file mode 100644 index 0000000000..df1fe7e69b --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_screen.c @@ -0,0 +1,310 @@ +#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 "nouveau_context.h" +#include "nouveau_drm.h" +#include "nouveau_dri.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" + +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 +#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_screen_create(__DRIscreenPrivate *driScrnPriv) +{ + struct nouveau_dri *nv_dri = driScrnPriv->pDevPriv; + struct nouveau_screen *nv_screen; + int ret; + + if (driScrnPriv->devPrivSize != sizeof(struct nouveau_dri)) { + NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n"); + return GL_FALSE; + } + + nv_screen = CALLOC_STRUCT(nouveau_screen); + if (!nv_screen) + return GL_FALSE; + nv_screen->driScrnPriv = driScrnPriv; + driScrnPriv->private = (void *)nv_screen; + + driParseOptionInfo(&nv_screen->option_cache, + __driConfigOptions, __driNConfigOptions); + + if ((ret = nouveau_device_open_existing(&nv_screen->device, 0, + driScrnPriv->fd, 0))) { + NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret); + return GL_FALSE; + } + + nv_screen->front_offset = nv_dri->front_offset; + nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8); + nv_screen->front_cpp = nv_dri->bpp / 8; + nv_screen->front_height = nv_dri->height; + + return GL_TRUE; +} + +static void +nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv) +{ + struct nouveau_screen *nv_screen = driScrnPriv->private; + + driScrnPriv->private = NULL; + FREE(nv_screen); +} + +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 struct __DriverAPIRec +nouveau_api = { + .InitDriver = 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, + .GetSwapInfo = NULL, + .GetMSC = NULL, + .WaitForMSC = NULL, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = nouveau_copy_sub_buffer, + .setTexOffset = NULL +}; + +static __GLcontextModes * +nouveau_fill_in_modes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) +{ + __GLcontextModes * modes; + __GLcontextModes * m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + int i; + + static const struct { + GLenum format; + GLenum type; + } fb_format_array[] = { + { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV }, + { GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV }, + }; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + uint8_t depth_bits_array[4] = { 0, 16, 24, 24 }; + uint8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; + uint8_t msaa_samples_array[1] = { 0 }; + + depth_buffer_factor = 4; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = ((pixel_bits==16) ? 1 : 2) * + depth_buffer_factor * back_buffer_factor * 4; + modes = (*dri_interface->createContextModes)(num_modes, + sizeof(__GLcontextModes)); + m = modes; + + for (i=((pixel_bits==16)?0:1);i<((pixel_bits==16)?1:3);i++) { + if (!driFillInModes(&m, fb_format_array[i].format, + fb_format_array[i].type, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + msaa_samples_array, 1, + GLX_TRUE_COLOR)) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + + if (!driFillInModes(&m, fb_format_array[i].format, + fb_format_array[i].type, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + msaa_samples_array, 1, + GLX_DIRECT_COLOR)) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + } + + return modes; +} +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay *dpy, int scrn, + __DRIscreen *psc, const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + void * pSAREA, int fd, int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) +{ + __DRIscreenPrivate *psp; + 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 }; + struct nouveau_dri *nv_dri = NULL; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("nouveau", + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + if (drm_expected.patch != drm_version->patch) { + fprintf(stderr, "Incompatible DRM patch level.\n" + "Expected: %d\n" "Current : %d\n", + drm_expected.patch, drm_version->patch); + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, + &nouveau_api); + if (psp == NULL) + return NULL; + nv_dri = psp->pDevPriv; + + *driver_modes = nouveau_fill_in_modes(nv_dri->bpp, + (nv_dri->bpp == 16) ? 16 : 24, + (nv_dri->bpp == 16) ? 0 : 8, + 1); + + driInitExtensions(NULL, card_extensions, GL_FALSE); + + return (void *)psp; +} + diff --git a/src/gallium/winsys/drm/nouveau/nouveau_screen.h b/src/gallium/winsys/drm/nouveau/nouveau_screen.h new file mode 100644 index 0000000000..388d6be9bb --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_screen.h @@ -0,0 +1,20 @@ +#ifndef __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_SCREEN_H__ + +#include "xmlconfig.h" + +struct nouveau_screen { + __DRIscreenPrivate *driScrnPriv; + driOptionCache option_cache; + + struct nouveau_device *device; + + uint32_t front_offset; + uint32_t front_pitch; + uint32_t front_cpp; + uint32_t front_height; + + void *nvc; +}; + +#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c new file mode 100644 index 0000000000..70e0104e83 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c @@ -0,0 +1,86 @@ +#include "main/glheader.h" +#include "glapi/glthread.h" +#include + +#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_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" + +void +nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate; + drm_clip_rect_t *pbox; + int nbox, i; + + LOCK_HARDWARE(nv); + if (!dPriv->numClipRects) { + UNLOCK_HARDWARE(nv); + return; + } + pbox = dPriv->pClipRects; + nbox = dPriv->numClipRects; + + nv->surface_copy_prep(nv, nv->frontbuffer, surf); + 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; + + nv->surface_copy(nv, dx, dy, sx, sy, w, h); + } + + FIRE_RING(nv->nvc->channel); + 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; + + surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); + 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; + + surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); + if (surf) { + st_notify_swapbuffers(nvfb->stfb); + nouveau_copy_buffer(dPriv, surf, NULL); + } +} + diff --git a/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h b/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h new file mode 100644 index 0000000000..825d3da6da --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h @@ -0,0 +1,10 @@ +#ifndef __NOUVEAU_SWAPBUFFERS_H__ +#define __NOUVEAU_SWAPBUFFERS_H__ + +extern void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *, + const drm_clip_rect_t *); +extern void nouveau_copy_sub_buffer(__DRIdrawablePrivate *, + int x, int y, int w, int h); +extern void nouveau_swap_buffers(__DRIdrawablePrivate *); + +#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys.c new file mode 100644 index 0000000000..0878840dcc --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_winsys.c @@ -0,0 +1,158 @@ +#include "util/u_memory.h" + +#include "nouveau_context.h" +#include "nouveau_screen.h" +#include "nouveau_winsys_pipe.h" + +#include "nouveau/nouveau_winsys.h" + +static int +nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count, + struct nouveau_notifier **notify) +{ + struct nouveau_context *nv = nvws->nv; + + return nouveau_notifier_alloc(nv->nvc->channel, nv->nvc->next_handle++, + count, notify); +} + +static int +nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass, + struct nouveau_grobj **grobj) +{ + struct nouveau_context *nv = nvws->nv; + struct nouveau_channel *chan = nv->nvc->channel; + int ret; + + ret = nouveau_grobj_alloc(chan, nv->nvc->next_handle++, + grclass, grobj); + if (ret) + return ret; + + assert(nv->nvc->next_subchannel < 7); + BIND_RING(chan, *grobj, nv->nvc->next_subchannel++); + return 0; +} + +static int +nouveau_pipe_surface_copy(struct nouveau_winsys *nvws, struct pipe_surface *dst, + unsigned dx, unsigned dy, struct pipe_surface *src, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_context *nv = nvws->nv; + + if (nv->surface_copy_prep(nv, dst, src)) + return 1; + nv->surface_copy(nv, dx, dy, sx, sy, w, h); + nv->surface_copy_done(nv); + + return 0; +} + +static int +nouveau_pipe_surface_fill(struct nouveau_winsys *nvws, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + if (nvws->nv->surface_fill(nvws->nv, dst, dx, dy, w, h, value)) + return 1; + 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) +{ + return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, + nouveau_buffer(buf)->bo, + data, flags, vor, tor); +} + +static int +nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size, + struct pipe_fence_handle **fence) +{ + if (fence) { + struct nouveau_pushbuf *pb = nvws->channel->pushbuf; + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(pb); + struct nouveau_fence *ref = NULL; + + nouveau_fence_ref(nvpb->fence, &ref); + *fence = (struct pipe_fence_handle *)ref; + } + + return nouveau_pushbuf_flush(nvws->channel, size); +} + +struct pipe_context * +nouveau_pipe_create(struct nouveau_context *nv) +{ + struct nouveau_channel_context *nvc = nv->nvc; + struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); + struct pipe_screen *(*hws_create)(struct pipe_winsys *, + struct nouveau_winsys *); + struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); + struct pipe_winsys *ws; + unsigned chipset = nv->nv_screen->device->chipset; + + if (!nvws) + return NULL; + + switch (chipset & 0xf0) { + case 0x10: + case 0x20: + hws_create = nv10_screen_create; + hw_create = nv10_create; + break; + case 0x30: + hws_create = nv30_screen_create; + hw_create = nv30_create; + break; + case 0x40: + case 0x60: + hws_create = nv40_screen_create; + hw_create = nv40_create; + break; + case 0x50: + case 0x80: + case 0x90: + hws_create = nv50_screen_create; + hw_create = nv50_create; + break; + default: + NOUVEAU_ERR("Unknown chipset NV%02x\n", chipset); + return NULL; + } + + nvws->nv = nv; + nvws->channel = nv->nvc->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->surface_copy = nouveau_pipe_surface_copy; + nvws->surface_fill = nouveau_pipe_surface_fill; + + ws = nouveau_create_pipe_winsys(nv); + + if (!nvc->pscreen) + nvc->pscreen = hws_create(ws, nvws); + nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id); + return nvc->pctx[nv->pctx_id]; +} + diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c new file mode 100644 index 0000000000..5276806de6 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c @@ -0,0 +1,206 @@ +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" + +#include "util/u_memory.h" + +#include "nouveau_context.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" +#include "nouveau_winsys_pipe.h" + +static void +nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, + void *context_private) +{ + struct nouveau_context *nv = context_private; + __DRIdrawablePrivate *dPriv = nv->dri_drawable; + + nouveau_copy_buffer(dPriv, surf, NULL); +} + +static const char * +nouveau_get_name(struct pipe_winsys *pws) +{ + return "Nouveau/DRI"; +} + +static struct pipe_buffer * +nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, + unsigned usage, unsigned size) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_context *nv = nvpws->nv; + struct nouveau_device *dev = nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + uint32_t flags; + + nvbuf = calloc(1, sizeof(*nvbuf)); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 1; + nvbuf->base.alignment = alignment; + nvbuf->base.usage = usage; + nvbuf->base.size = size; + + flags = NOUVEAU_BO_LOCAL; + + if (usage & PIPE_BUFFER_USAGE_PIXEL) { + if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) + flags |= NOUVEAU_BO_GART; + flags |= NOUVEAU_BO_VRAM; + + switch (dev->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 (nv->cap.hw_vertex_buffer) + flags |= NOUVEAU_BO_GART; + } + + if (usage & PIPE_BUFFER_USAGE_INDEX) { + if (nv->cap.hw_index_buffer) + flags |= NOUVEAU_BO_GART; + } + + 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 *pws, void *ptr, unsigned bytes) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_device *dev = nvpws->nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + + nvbuf = calloc(1, sizeof(*nvbuf)); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 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_winsys *ws, struct pipe_buffer *buf) +{ + struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + + nouveau_bo_del(&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_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_buffer(buf); + + nouveau_bo_unmap(nvbuf->bo); +} + +static INLINE struct nouveau_fence * +nouveau_pipe_fence(struct pipe_fence_handle *pfence) +{ + return (struct nouveau_fence *)pfence; +} + +static void +nouveau_pipe_fence_reference(struct pipe_winsys *ws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *pfence) +{ + nouveau_fence_ref((void *)pfence, (void *)ptr); +} + +static int +nouveau_pipe_fence_signalled(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, unsigned flag) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)ws; + struct nouveau_fence *fence = nouveau_pipe_fence(pfence); + + if (nouveau_fence(fence)->signalled == 0) + nouveau_fence_flush(nvpws->nv->nvc->channel); + + return !nouveau_fence(fence)->signalled; +} + +static int +nouveau_pipe_fence_finish(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, unsigned flag) +{ + struct nouveau_fence *fence = nouveau_pipe_fence(pfence); + struct nouveau_fence *ref = NULL; + + nouveau_fence_ref(fence, &ref); + return nouveau_fence_wait(&ref); +} + +struct pipe_winsys * +nouveau_create_pipe_winsys(struct nouveau_context *nv) +{ + struct nouveau_pipe_winsys *nvpws; + struct pipe_winsys *pws; + + nvpws = CALLOC_STRUCT(nouveau_pipe_winsys); + if (!nvpws) + return NULL; + nvpws->nv = nv; + pws = &nvpws->pws; + + pws->flush_frontbuffer = nouveau_flush_frontbuffer; + + pws->buffer_create = nouveau_pipe_bo_create; + pws->buffer_destroy = nouveau_pipe_bo_del; + pws->user_buffer_create = nouveau_pipe_bo_user_create; + pws->buffer_map = nouveau_pipe_bo_map; + pws->buffer_unmap = nouveau_pipe_bo_unmap; + + pws->fence_reference = nouveau_pipe_fence_reference; + pws->fence_signalled = nouveau_pipe_fence_signalled; + pws->fence_finish = nouveau_pipe_fence_finish; + + pws->get_name = nouveau_get_name; + + return &nvpws->pws; +} + diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h new file mode 100644 index 0000000000..6a03ac0d77 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h @@ -0,0 +1,34 @@ +#ifndef NOUVEAU_PIPE_WINSYS_H +#define NOUVEAU_PIPE_WINSYS_H + +#include "pipe/p_context.h" +#include "pipe/p_winsys.h" +#include "nouveau_context.h" + +struct nouveau_pipe_buffer { + struct pipe_buffer base; + struct nouveau_bo *bo; +}; + +static inline struct nouveau_pipe_buffer * +nouveau_buffer(struct pipe_buffer *buf) +{ + return (struct nouveau_pipe_buffer *)buf; +} + +struct nouveau_pipe_winsys { + struct pipe_winsys pws; + + struct nouveau_context *nv; +}; + +extern struct pipe_winsys * +nouveau_create_pipe_winsys(struct nouveau_context *nv); + +struct pipe_context * +nouveau_create_softpipe(struct nouveau_context *nv); + +struct pipe_context * +nouveau_pipe_create(struct nouveau_context *nv); + +#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c new file mode 100644 index 0000000000..704f6c7750 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c @@ -0,0 +1,85 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include "imports.h" + +#include "pipe/p_defines.h" +#include "pipe/p_format.h" +#include "softpipe/sp_winsys.h" + +#include "nouveau_context.h" +#include "nouveau_winsys_pipe.h" + +struct nouveau_softpipe_winsys { + struct softpipe_winsys sws; + struct nouveau_context *nv; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean +nouveau_is_format_supported(struct softpipe_winsys *sws, uint format) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + }; + + return FALSE; +} + +struct pipe_context * +nouveau_create_softpipe(struct nouveau_context *nv) +{ + struct nouveau_softpipe_winsys *nvsws; + struct pipe_screen *pscreen; + struct pipe_winsys *ws; + + ws = nouveau_create_pipe_winsys(nv); + if (!ws) + return NULL; + pscreen = softpipe_create_screen(ws); + + nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys); + if (!nvsws) + return NULL; + + nvsws->sws.is_format_supported = nouveau_is_format_supported; + nvsws->nv = nv; + + return softpipe_create(pscreen, ws, &nvsws->sws); +} + diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c new file mode 100644 index 0000000000..8fa3d106c8 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -0,0 +1,314 @@ +#include "pipe/p_context.h" +#include "pipe/p_format.h" + +#include "nouveau_context.h" + +static INLINE int +nv04_surface_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; + default: + return -1; + } +} + +static INLINE int +nv04_rect_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + default: + return -1; + } +} + +static void +nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct pipe_surface *dst = nv->surf_dst; + struct pipe_surface *src = nv->surf_src; + unsigned dst_offset, src_offset; + + dst_offset = dst->offset + (dy * dst->stride) + (dx * dst->block.size); + src_offset = src->offset + (sy * src->stride) + (sx * src->block.size); + + while (h) { + int count = (h > 2047) ? 2047 : h; + + BEGIN_RING(chan, nv->nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src_offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst_offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); + OUT_RING (chan, src->stride); + OUT_RING (chan, dst->stride); + OUT_RING (chan, w * src->block.size); + OUT_RING (chan, count); + OUT_RING (chan, 0x0101); + OUT_RING (chan, 0); + + h -= count; + src_offset += src->stride * count; + dst_offset += dst->stride * count; + } +} + +static void +nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_channel *chan = nv->nvc->channel; + + BEGIN_RING(chan, nv->nvc->NvImageBlit, 0x0300, 3); + OUT_RING (chan, (sy << 16) | sx); + OUT_RING (chan, (dy << 16) | dx); + OUT_RING (chan, ( h << 16) | w); +} + +static int +nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, + struct pipe_surface *src) +{ + struct nouveau_channel *chan = nv->nvc->channel; + int format; + + if (src->format != dst->format) + return 1; + + /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback + * to NV_MEMORY_TO_MEMORY_FORMAT in this case. + */ + if ((src->offset & 63) || (dst->offset & 63)) { + BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + nv->surface_copy = nv04_surface_copy_m2mf; + nv->surf_dst = dst; + nv->surf_src = src; + return 0; + + } + + if ((format = nv04_surface_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad surface format 0x%x\n", dst->format); + return 1; + } + nv->surface_copy = nv04_surface_copy_blit; + + BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, format); + OUT_RING (chan, (dst->stride << 16) | src->stride); + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + return 0; +} + +static void +nv04_surface_copy_done(struct nouveau_context *nv) +{ + FIRE_RING(nv->nvc->channel); +} + +static int +nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *surf2d = nv->nvc->NvCtxSurf2D; + struct nouveau_grobj *rect = nv->nvc->NvGdiRect; + int cs2d_format, gdirect_format; + + if ((cs2d_format = nv04_surface_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad format = %d\n", dst->format); + return 1; + } + + if ((gdirect_format = nv04_rect_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad format = %d\n", dst->format); + return 1; + } + + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, cs2d_format); + OUT_RING (chan, (dst->stride << 16) | dst->stride); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); + OUT_RING (chan, gdirect_format); + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); + OUT_RING (chan, value); + BEGIN_RING(chan, rect, + NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); + OUT_RING (chan, (dx << 16) | dy); + OUT_RING (chan, ( w << 16) | h); + + FIRE_RING(chan); + return 0; +} + +int +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) +{ + struct nouveau_channel *chan = nvc->channel; + unsigned chipset = nvc->channel->device->chipset, class; + int ret; + + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, 0x39, + &nvc->NvM2MF))) { + NOUVEAU_ERR("Error creating m2mf object: %d\n", ret); + return 1; + } + BIND_RING (chan, nvc->NvM2MF, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + + class = chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : + NV10_CONTEXT_SURFACES_2D; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvCtxSurf2D))) { + NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); + return 1; + } + BIND_RING (chan, nvc->NvCtxSurf2D, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RING (chan, nvc->channel->vram->handle); + OUT_RING (chan, nvc->channel->vram->handle); + + class = chipset < 0x10 ? NV04_IMAGE_BLIT : NV12_IMAGE_BLIT; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvImageBlit))) { + NOUVEAU_ERR("Error creating blit object: %d\n", ret); + return 1; + } + BIND_RING (chan, nvc->NvImageBlit, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); + OUT_RING (chan, nvc->NvCtxSurf2D->handle); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); + OUT_RING (chan, NV04_IMAGE_BLIT_OPERATION_SRCCOPY); + + class = NV04_GDI_RECTANGLE_TEXT; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvGdiRect))) { + NOUVEAU_ERR("Error creating rect object: %d\n", ret); + return 1; + } + BIND_RING (chan, nvc->NvGdiRect, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); + OUT_RING (chan, nvc->NvCtxSurf2D->handle); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); + BEGIN_RING(chan, nvc->NvGdiRect, + NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + + switch (chipset & 0xf0) { + case 0x00: + case 0x10: + class = NV04_SWIZZLED_SURFACE; + break; + case 0x20: + class = NV20_SWIZZLED_SURFACE; + break; + case 0x30: + class = NV30_SWIZZLED_SURFACE; + break; + case 0x40: + case 0x60: + class = NV40_SWIZZLED_SURFACE; + break; + default: + /* Famous last words: this really can't happen.. */ + assert(0); + break; + } + + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvSwzSurf); + if (ret) { + NOUVEAU_ERR("Error creating swizzled surface: %d\n", ret); + return 1; + } + + BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); + OUT_RING (chan, nvc->channel->vram->handle); + + if (chipset < 0x10) { + class = NV04_SCALED_IMAGE_FROM_MEMORY; + } else + if (chipset < 0x40) { + class = NV10_SCALED_IMAGE_FROM_MEMORY; + } else { + class = NV40_SCALED_IMAGE_FROM_MEMORY; + } + + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvSIFM); + if (ret) { + NOUVEAU_ERR("Error creating scaled image object: %d\n", ret); + return 1; + } + + BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); + + return 0; +} + +int +nouveau_surface_init_nv04(struct nouveau_context *nv) +{ + nv->surface_copy_prep = nv04_surface_copy_prep; + nv->surface_copy = nv04_surface_copy_blit; + nv->surface_copy_done = nv04_surface_copy_done; + nv->surface_fill = nv04_surface_fill; + return 0; +} + diff --git a/src/gallium/winsys/drm/nouveau/nv50_surface.c b/src/gallium/winsys/drm/nouveau/nv50_surface.c new file mode 100644 index 0000000000..c8ab7f690f --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nv50_surface.c @@ -0,0 +1,194 @@ +#include "pipe/p_context.h" +#include "pipe/p_format.h" + +#include "nouveau_context.h" + +static INLINE int +nv50_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV50_2D_DST_FORMAT_32BPP; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return NV50_2D_DST_FORMAT_24BPP; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV50_2D_DST_FORMAT_16BPP; + case PIPE_FORMAT_A8_UNORM: + return NV50_2D_DST_FORMAT_8BPP; + default: + return -1; + } +} + +static int +nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; + struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->bo; + int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; + int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); + + surf_format = nv50_format(surf->format); + if (surf_format < 0) + return 1; + + if (!nouveau_bo(bo)->tiled) { + BEGIN_RING(chan, eng2d, mthd, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, mthd + 0x14, 5); + OUT_RING (chan, surf->stride); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + OUT_RELOCh(chan, bo, surf->offset, flags); + OUT_RELOCl(chan, bo, surf->offset, flags); + } else { + BEGIN_RING(chan, eng2d, mthd, 5); + OUT_RING (chan, surf_format); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, mthd + 0x18, 4); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + OUT_RELOCh(chan, bo, surf->offset, flags); + OUT_RELOCl(chan, bo, surf->offset, flags); + } + +#if 0 + if (dst) { + BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + } +#endif + + return 0; +} + +static int +nv50_surface_copy_prep(struct nouveau_context *nv, + struct pipe_surface *dst, struct pipe_surface *src) +{ + int ret; + + assert(src->format == dst->format); + + ret = nv50_surface_set(nv, dst, 1); + if (ret) + return ret; + + ret = nv50_surface_set(nv, src, 0); + if (ret) + return ret; + + return 0; +} + +static void +nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; + + BEGIN_RING(chan, eng2d, 0x088c, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4); + OUT_RING (chan, dx); + OUT_RING (chan, dy); + OUT_RING (chan, w); + OUT_RING (chan, h); + BEGIN_RING(chan, eng2d, 0x08c0, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, 0x08d0, 4); + OUT_RING (chan, 0); + OUT_RING (chan, sx); + OUT_RING (chan, 0); + OUT_RING (chan, sy); +} + +static void +nv50_surface_copy_done(struct nouveau_context *nv) +{ + FIRE_RING(nv->nvc->channel); +} + +static int +nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; + int rect_format, ret; + + rect_format = nv50_format(dst->format); + if (rect_format < 0) + return 1; + + ret = nv50_surface_set(nv, dst, 1); + if (ret) + return ret; + + BEGIN_RING(chan, eng2d, 0x0580, 3); + OUT_RING (chan, 4); + OUT_RING (chan, rect_format); + OUT_RING (chan, value); + + BEGIN_RING(chan, eng2d, NV50_2D_RECT_X1, 4); + OUT_RING (chan, dx); + OUT_RING (chan, dy); + OUT_RING (chan, dx + w); + OUT_RING (chan, dy + h); + + FIRE_RING(chan); + return 0; +} + +int +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) +{ + struct nouveau_channel *chan = nvc->channel; + struct nouveau_grobj *eng2d = NULL; + int ret; + + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d); + if (ret) + return ret; + nvc->Nv2D = eng2d; + + BIND_RING (chan, eng2d, nvc->next_subchannel++); + BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4); + OUT_RING (chan, nvc->sync_notifier->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1); + OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); + BEGIN_RING(chan, eng2d, 0x0290, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, 0x0888, 1); + OUT_RING (chan, 1); + + return 0; +} + +int +nouveau_surface_init_nv50(struct nouveau_context *nv) +{ + nv->surface_copy_prep = nv50_surface_copy_prep; + nv->surface_copy = nv50_surface_copy; + nv->surface_copy_done = nv50_surface_copy_done; + nv->surface_fill = nv50_surface_fill; + return 0; +} + -- cgit v1.2.3 From 284ab5a6127f8b452acaa0e10ac1d9ebc87fac3e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 10 Sep 2008 18:22:00 -0600 Subject: cell: checkpoint commit of new per-fragment processing Do code generation for alpha test, z test, stencil, blend, colormask and framebuffer/tile read/write as a single code block. Ian's previous blend/z/stencil test code is still there but mostly disabled and will be removed soon. --- src/gallium/winsys/xlib/xm_api.c | 7 ++++++- src/gallium/winsys/xlib/xm_winsys.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index b010513107..28bd6ceab4 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -349,12 +349,17 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, if (vis->mesa_visual.depthBits == 0) depthFormat = PIPE_FORMAT_NONE; +#ifdef GALLIUM_CELL /* XXX temporary for Cell! */ + else + depthFormat = PIPE_FORMAT_S8Z24_UNORM; +#else else if (vis->mesa_visual.depthBits <= 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; + depthFormat = PIPE_FORMAT_Z16UNORM; else if (vis->mesa_visual.depthBits <= 24) depthFormat = PIPE_FORMAT_S8Z24_UNORM; else depthFormat = PIPE_FORMAT_Z32_UNORM; +#endif if (vis->mesa_visual.stencilBits == 8) { if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 5e9a1f92f1..c4a30d3702 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -275,6 +275,39 @@ xm_buffer_destroy(struct pipe_winsys *pws, } +/** + * For Cell. Basically, rearrange the pixels/quads from this layout: + * +--+--+--+--+ + * |p0|p1|p2|p3|.... + * +--+--+--+--+ + * + * to this layout: + * +--+--+ + * |p0|p1|.... + * +--+--+ + * |p2|p3| + * +--+--+ + */ +static void +twiddle_tile(uint *tile) +{ + uint tile2[TILE_SIZE * TILE_SIZE]; + int y, x; + + for (y = 0; y < TILE_SIZE; y+=2) { + for (x = 0; x < TILE_SIZE; x+=2) { + int k = 4 * (y/2 * TILE_SIZE/2 + x/2); + tile2[y * TILE_SIZE + (x + 0)] = tile[k]; + tile2[y * TILE_SIZE + (x + 1)] = tile[k+1]; + tile2[(y + 1) * TILE_SIZE + (x + 0)] = tile[k+2]; + tile2[(y + 1) * TILE_SIZE + (x + 1)] = tile[k+3]; + } + } + memcpy(tile, tile2, sizeof(tile2)); +} + + + /** * Display a surface that's in a tiled configuration. That is, all the * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory. @@ -321,6 +354,8 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) ximage->data = (char *) xm_buf->data + offset; + twiddle_tile((uint *) ximage->data); + if (XSHM_ENABLED(xm_buf)) { #if defined(USE_XSHM) && !defined(XFree86Server) XShmPutImage(b->xm_visual->display, b->drawable, b->gc, -- cgit v1.2.3 From fbf1586b36f8fb181ecee6a285c94f11e30005ba Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 11 Sep 2008 12:01:19 -0600 Subject: gallium: typo: s/PIPE_FORMAT_Z16UNORM/PIPE_FORMAT_Z16_UNORM/ --- src/gallium/winsys/xlib/xm_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 28bd6ceab4..d28a6423b9 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -354,7 +354,7 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, depthFormat = PIPE_FORMAT_S8Z24_UNORM; #else else if (vis->mesa_visual.depthBits <= 16) - depthFormat = PIPE_FORMAT_Z16UNORM; + depthFormat = PIPE_FORMAT_Z16_UNORM; else if (vis->mesa_visual.depthBits <= 24) depthFormat = PIPE_FORMAT_S8Z24_UNORM; else -- cgit v1.2.3 From 084ab37b7f34d509af995efaef4615289669f72b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 11 Sep 2008 17:10:10 -0600 Subject: cell: fix tile twidding bug seen in the event of multiple expose events --- src/gallium/winsys/xlib/xm_winsys.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index c4a30d3702..2acbc94fc8 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -289,21 +289,19 @@ xm_buffer_destroy(struct pipe_winsys *pws, * +--+--+ */ static void -twiddle_tile(uint *tile) +twiddle_tile(const uint *tileIn, uint *tileOut) { - uint tile2[TILE_SIZE * TILE_SIZE]; int y, x; for (y = 0; y < TILE_SIZE; y+=2) { for (x = 0; x < TILE_SIZE; x+=2) { int k = 4 * (y/2 * TILE_SIZE/2 + x/2); - tile2[y * TILE_SIZE + (x + 0)] = tile[k]; - tile2[y * TILE_SIZE + (x + 1)] = tile[k+1]; - tile2[(y + 1) * TILE_SIZE + (x + 0)] = tile[k+2]; - tile2[(y + 1) * TILE_SIZE + (x + 1)] = tile[k+3]; + tileOut[y * TILE_SIZE + (x + 0)] = tileIn[k]; + tileOut[y * TILE_SIZE + (x + 1)] = tileIn[k+1]; + tileOut[(y + 1) * TILE_SIZE + (x + 0)] = tileIn[k+2]; + tileOut[(y + 1) * TILE_SIZE + (x + 1)] = tileIn[k+3]; } } - memcpy(tile, tile2, sizeof(tile2)); } @@ -339,6 +337,7 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) for (y = 0; y < surf->height; y += TILE_SIZE) { for (x = 0; x < surf->width; x += TILE_SIZE) { + uint tmpTile[TILE_SIZE * TILE_SIZE]; int tx = x / TILE_SIZE; int ty = y / TILE_SIZE; int offset = ty * tilesPerRow + tx; @@ -352,9 +351,9 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) offset *= 4 * TILE_SIZE * TILE_SIZE; - ximage->data = (char *) xm_buf->data + offset; - - twiddle_tile((uint *) ximage->data); + twiddle_tile((uint *) ((char *) xm_buf->data + offset), + tmpTile); + ximage->data = (char*) tmpTile; if (XSHM_ENABLED(xm_buf)) { #if defined(USE_XSHM) && !defined(XFree86Server) -- cgit v1.2.3 From 3df06470275573f7d1d6eb6ce690f2e7ffa4ced7 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 12 Sep 2008 15:09:44 +0200 Subject: i915simple: A step closer to compiling --- src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c b/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c index 8a18bfd9a4..34ad7eebe1 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c +++ b/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c @@ -94,7 +94,6 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, int i; ASSERT(surf->buffer); - ASSERT(surf->cpp == cpp); DBG(SWAP, "screen pitch %d src surface pitch %d\n", pitch, surf->stride); -- cgit v1.2.3 From d64da83a2c21d17f2f0a6b9b4c8e90df0e993559 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 12 Sep 2008 23:51:39 +1000 Subject: nouveau: rework nouveau_screen for latest and greatest changes --- src/gallium/winsys/drm/nouveau/nouveau_screen.c | 267 ++++++++++-------------- 1 file changed, 110 insertions(+), 157 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/nouveau_screen.c index df1fe7e69b..9489645151 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/drm/nouveau/nouveau_screen.c @@ -64,50 +64,6 @@ static const GLuint __driNConfigOptions = 0; extern const struct dri_extension common_extensions[]; extern const struct dri_extension nv40_extensions[]; -static GLboolean -nouveau_screen_create(__DRIscreenPrivate *driScrnPriv) -{ - struct nouveau_dri *nv_dri = driScrnPriv->pDevPriv; - struct nouveau_screen *nv_screen; - int ret; - - if (driScrnPriv->devPrivSize != sizeof(struct nouveau_dri)) { - NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n"); - return GL_FALSE; - } - - nv_screen = CALLOC_STRUCT(nouveau_screen); - if (!nv_screen) - return GL_FALSE; - nv_screen->driScrnPriv = driScrnPriv; - driScrnPriv->private = (void *)nv_screen; - - driParseOptionInfo(&nv_screen->option_cache, - __driConfigOptions, __driNConfigOptions); - - if ((ret = nouveau_device_open_existing(&nv_screen->device, 0, - driScrnPriv->fd, 0))) { - NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret); - return GL_FALSE; - } - - nv_screen->front_offset = nv_dri->front_offset; - nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8); - nv_screen->front_cpp = nv_dri->bpp / 8; - nv_screen->front_height = nv_dri->height; - - return GL_TRUE; -} - -static void -nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv) -{ - struct nouveau_screen *nv_screen = driScrnPriv->private; - - driScrnPriv->private = NULL; - FREE(nv_screen); -} - static GLboolean nouveau_create_buffer(__DRIscreenPrivate * driScrnPriv, __DRIdrawablePrivate * driDrawPriv, @@ -162,149 +118,146 @@ nouveau_destroy_buffer(__DRIdrawablePrivate * driDrawPriv) free(nvfb); } -static struct __DriverAPIRec -nouveau_api = { - .InitDriver = 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, - .GetSwapInfo = NULL, - .GetMSC = NULL, - .WaitForMSC = NULL, - .WaitForSBC = NULL, - .SwapBuffersMSC = NULL, - .CopySubBuffer = nouveau_copy_sub_buffer, - .setTexOffset = NULL -}; - -static __GLcontextModes * -nouveau_fill_in_modes(unsigned pixel_bits, unsigned depth_bits, +static __DRIconfig ** +nouveau_fill_in_modes(__DRIscreenPrivate *psp, + unsigned pixel_bits, unsigned depth_bits, unsigned stencil_bits, GLboolean have_back_buffer) { - __GLcontextModes * modes; - __GLcontextModes * m; - unsigned num_modes; + __DRIconfig **configs; unsigned depth_buffer_factor; unsigned back_buffer_factor; - int i; - - static const struct { - GLenum format; - GLenum type; - } fb_format_array[] = { - { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 }, - { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV }, - { GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV }, - }; + GLenum fb_format; + GLenum fb_type; - /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't - * support pageflipping at all. - */ static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + GLX_NONE, GLX_SWAP_UNDEFINED_OML, }; - uint8_t depth_bits_array[4] = { 0, 16, 24, 24 }; - uint8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; - uint8_t msaa_samples_array[1] = { 0 }; - - depth_buffer_factor = 4; - back_buffer_factor = (have_back_buffer) ? 3 : 1; - - num_modes = ((pixel_bits==16) ? 1 : 2) * - depth_buffer_factor * back_buffer_factor * 4; - modes = (*dri_interface->createContextModes)(num_modes, - sizeof(__GLcontextModes)); - m = modes; - - for (i=((pixel_bits==16)?0:1);i<((pixel_bits==16)?1:3);i++) { - if (!driFillInModes(&m, fb_format_array[i].format, - fb_format_array[i].type, - depth_bits_array, - stencil_bits_array, - depth_buffer_factor, - back_buffer_modes, - back_buffer_factor, - msaa_samples_array, 1, - GLX_TRUE_COLOR)) { - fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__ ); - return NULL; - } - - if (!driFillInModes(&m, fb_format_array[i].format, - fb_format_array[i].type, - depth_bits_array, - stencil_bits_array, - depth_buffer_factor, - back_buffer_modes, - back_buffer_factor, - msaa_samples_array, 1, - GLX_DIRECT_COLOR)) { - fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__ ); + u_int8_t depth_bits_array[3]; + u_int8_t stencil_bits_array[3]; + + 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; + + 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); + if (configs == NULL) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__); return NULL; - } } - return modes; + return configs; } -PUBLIC void * -__driCreateNewScreen_20050727(__DRInativeDisplay *dpy, int scrn, - __DRIscreen *psc, const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - void * pSAREA, int fd, int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) + +static const __DRIconfig ** +nouveau_screen_create(__DRIscreenPrivate *psp) { - __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 }; - struct nouveau_dri *nv_dri = NULL; - - dri_interface = interface; + int ret; if (!driCheckDriDdxDrmVersions2("nouveau", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { + &psp->dri_version, &dri_expected, + &psp->ddx_version, &ddx_expected, + &psp->drm_version, &drm_expected)) { return NULL; } - if (drm_expected.patch != drm_version->patch) { + if (drm_expected.patch != psp->drm_version.patch) { fprintf(stderr, "Incompatible DRM patch level.\n" "Expected: %d\n" "Current : %d\n", - drm_expected.patch, drm_version->patch); + drm_expected.patch, psp->drm_version.patch); return NULL; } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, - &nouveau_api); - if (psp == NULL) - return NULL; - nv_dri = psp->pDevPriv; + driInitExtensions(NULL, card_extensions, GL_FALSE); - *driver_modes = nouveau_fill_in_modes(nv_dri->bpp, - (nv_dri->bpp == 16) ? 16 : 24, - (nv_dri->bpp == 16) ? 0 : 8, - 1); + if (psp->devPrivSize != sizeof(struct nouveau_dri)) { + NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n"); + return GL_FALSE; + } - driInitExtensions(NULL, card_extensions, GL_FALSE); + nv_screen = CALLOC_STRUCT(nouveau_screen); + if (!nv_screen) + return GL_FALSE; + nv_screen->driScrnPriv = psp; + psp->private = (void *)nv_screen; + + driParseOptionInfo(&nv_screen->option_cache, + __driConfigOptions, __driNConfigOptions); + + if ((ret = nouveau_device_open_existing(&nv_screen->device, 0, + psp->fd, 0))) { + NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret); + return GL_FALSE; + } - return (void *)psp; + nv_screen->front_offset = nv_dri->front_offset; + nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8); + nv_screen->front_cpp = nv_dri->bpp / 8; + nv_screen->front_height = nv_dri->height; + + 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! */ +}; + -- cgit v1.2.3 From 6b50fd27b85bc0d060ead13e6c656dd64c9a2978 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 8 Sep 2008 21:05:49 -0400 Subject: g3dvl: Clean up Makefile deps. --- src/gallium/winsys/g3dvl/nouveau/Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 7fa29d2f5f..5d11bde322 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -34,15 +34,16 @@ LIBS += -ldriclient -ldrm -lnv10 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate ############################################# -.PHONY = all clean +.PHONY = all clean libdriclient all: ${TARGET} -${TARGET}: ${OBJECTS} +${TARGET}: ${OBJECTS} libdriclient + $(CC) ${LDFLAGS} -shared -o $@ ${OBJECTS} ${LIBS} + +libdriclient: cd ${DRIDIR}/src; ${MAKE} - $(CC) ${LDFLAGS} -shared -o $@ $^ ${LIBS} clean: cd ${DRIDIR}/src; ${MAKE} clean rm -rf ${OBJECTS} ${TARGET} - -- cgit v1.2.3 From 59f23e92e24b93eb48f4e0552dd8e397aefd1714 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 12 Sep 2008 13:22:43 -0400 Subject: g3dvl: Update softlinks to nouveau winsys files, related fixes. --- src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_context.c | 37 ++++---- src/gallium/winsys/g3dvl/nouveau/nouveau_device.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_local.h | 2 +- .../winsys/g3dvl/nouveau/nouveau_notifier.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c | 2 +- .../winsys/g3dvl/nouveau/nouveau_resource.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c | 13 ++- src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c | 2 +- .../winsys/g3dvl/nouveau/nouveau_winsys_pipe.c | 11 +-- .../winsys/g3dvl/nouveau/nouveau_winsys_pipe.h | 2 +- .../winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nv04_surface.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nv50_surface.c | 2 +- src/gallium/winsys/g3dvl/xsp_winsys.c | 105 ++++++++++----------- 22 files changed, 99 insertions(+), 103 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c index 73ac4a4171..1005282dd4 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_bo.c \ No newline at end of file +../../drm/nouveau/nouveau_bo.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c index 6c9b2c48d8..5af8202950 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_channel.c \ No newline at end of file +../../drm/nouveau/nouveau_channel.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c index 5e173c7672..06a61fcda3 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c @@ -1,7 +1,7 @@ #include "pipe/p_defines.h" #include "pipe/p_context.h" #include "pipe/p_screen.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "nouveau_context.h" #include "nouveau_dri.h" @@ -150,7 +150,7 @@ nouveau_context_create(dri_context_t *dri_context) fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); fb_bo->drm.offset = nv_screen->front_offset; fb_bo->drm.flags = NOUVEAU_MEM_FB; - fb_bo->drm.size = nv_screen->front_pitch * + fb_bo->drm.size = nv_screen->front_pitch * nv_screen->front_height; fb_bo->refcount = 1; fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; @@ -280,7 +280,7 @@ nouveau_context_bind(struct nouveau_context *nv, dri_drawable_t *dri_drawable) { assert(nv); assert(dri_drawable); - + if (nv->dri_drawable != dri_drawable) { nv->dri_drawable = dri_drawable; @@ -294,9 +294,9 @@ int nouveau_context_unbind(struct nouveau_context *nv) { assert(nv); - + nv->dri_drawable = NULL; - + return 0; } @@ -306,20 +306,20 @@ int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) { struct nouveau_context *nv; dri_drawable_t *dri_drawable; - + nv = pipe->priv; - + driCreateDrawable(nv->nv_screen->dri_screen, drawable, &dri_drawable); - + nouveau_context_bind(nv, dri_drawable); - + return 0; } int unbind_pipe_drawable(struct pipe_context *pipe) { nouveau_context_unbind(pipe->priv); - + return 0; } @@ -329,15 +329,15 @@ struct pipe_context* create_pipe_context(Display *display, int screen) dri_framebuffer_t dri_framebuf; dri_context_t *dri_context; struct nouveau_context *nv; - + driCreateScreen(display, screen, &dri_screen, &dri_framebuf); driCreateContext(dri_screen, XDefaultVisual(display, screen), &dri_context); - + nouveau_screen_create(dri_screen, &dri_framebuf); nouveau_context_create(dri_context); - + nv = dri_context->private; - + return nv->nvc->pctx[nv->pctx_id]; } @@ -348,15 +348,15 @@ int destroy_pipe_context(struct pipe_context *pipe) struct nouveau_context *nv; dri_screen_t *dri_screen; dri_context_t *dri_context; - + assert(pipe); - + screen = pipe->screen; winsys = pipe->winsys; nv = pipe->priv; dri_context = nv->dri_context; dri_screen = dri_context->dri_screen; - + pipe->destroy(pipe); screen->destroy(screen); free(winsys); @@ -365,7 +365,6 @@ int destroy_pipe_context(struct pipe_context *pipe) nouveau_screen_destroy(dri_screen); driDestroyContext(dri_context); driDestroyScreen(dri_screen); - + return 0; } - diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c index 47d52dafa8..63f1fa040c 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_device.c \ No newline at end of file +../../drm/nouveau/nouveau_device.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c index 45078c964f..cd0d32e537 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_dma.c \ No newline at end of file +../../drm/nouveau/nouveau_dma.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h index 6b9ec77741..e6c7d4bc96 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h @@ -1 +1 @@ -../../dri/nouveau/nouveau_dma.h \ No newline at end of file +../../drm/nouveau/nouveau_dma.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h index 0e6c9fce35..c8f9dbdc3a 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h @@ -1 +1 @@ -../../dri/nouveau/nouveau_dri.h \ No newline at end of file +../../drm/nouveau/nouveau_dri.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h index 473b7d4812..27082c9d34 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h @@ -1 +1 @@ -../../dri/nouveau/nouveau_drmif.h \ No newline at end of file +../../drm/nouveau/nouveau_drmif.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c index ef1f0c6afe..51a50527e6 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_fence.c \ No newline at end of file +../../drm/nouveau/nouveau_fence.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c index 428186544c..db17c72e6d 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_grobj.c \ No newline at end of file +../../drm/nouveau/nouveau_grobj.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h index 6b878aad22..4e9d3042cb 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h @@ -1 +1 @@ -../../dri/nouveau/nouveau_local.h \ No newline at end of file +../../drm/nouveau/nouveau_local.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c index 3024a612a7..703bc3ce4a 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_notifier.c \ No newline at end of file +../../drm/nouveau/nouveau_notifier.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c index dae31d9799..4ac137cada 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_pushbuf.c \ No newline at end of file +../../drm/nouveau/nouveau_pushbuf.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c index e0d71e9d2b..2241af328f 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_resource.c \ No newline at end of file +../../drm/nouveau/nouveau_resource.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c index daea3fff68..f80d00050c 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c @@ -1,5 +1,5 @@ #include "pipe/p_context.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "nouveau_context.h" #include #include "nouveau_dri.h" @@ -23,11 +23,11 @@ int nouveau_check_dri_drm_ddx(dri_version_t *dri, dri_version_t *drm, dri_versio static const dri_version_t ddx_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; static const dri_version_t dri_expected = {4, 0, 0}; static const dri_version_t drm_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; - + assert(dri); assert(drm); assert(ddx); - + if (dri->major != dri_expected.major || dri->minor < dri_expected.minor) { NOUVEAU_ERR("Unexpected DRI version.\n"); @@ -43,17 +43,17 @@ int nouveau_check_dri_drm_ddx(dri_version_t *dri, dri_version_t *drm, dri_versio NOUVEAU_ERR("Unexpected DDX version.\n"); return 1; } - + return 0; } int nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf) -{ +{ struct nouveau_dri *nv_dri = dri_framebuf->private; struct nouveau_screen *nv_screen; int ret; - + if (nouveau_check_dri_drm_ddx(&dri_screen->dri, &dri_screen->drm, &dri_screen->ddx)) return 1; @@ -89,4 +89,3 @@ nouveau_screen_destroy(dri_screen_t *dri_screen) FREE(nv_screen); } - diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c index 43de49b98b..ce4052d557 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_winsys.c \ No newline at end of file +../../drm/nouveau/nouveau_winsys.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c index b835bd5760..5d5380c250 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c @@ -1,7 +1,7 @@ #include "pipe/p_winsys.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "util/u_memory.h" #include "nouveau_context.h" #include "nouveau_local.h" @@ -29,7 +29,7 @@ static struct pipe_surface * nouveau_surface_alloc(struct pipe_winsys *ws) { struct pipe_surface *surf; - + surf = CALLOC_STRUCT(pipe_surface); if (!surf) return NULL; @@ -59,10 +59,10 @@ nouveau_surface_alloc_storage ) { const unsigned int ALIGNMENT = 256; - + assert(pws); assert(surface); - + surface->width = width; surface->height = height; surface->format = format; @@ -72,7 +72,7 @@ nouveau_surface_alloc_storage surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); surface->usage = flags; surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * surface->nblocksy); - + return 0; } @@ -258,4 +258,3 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv) return &nvpws->pws; } - diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h index 264716fef0..9d9460883e 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h @@ -1 +1 @@ -../../dri/nouveau/nouveau_winsys_pipe.h \ No newline at end of file +../../drm/nouveau/nouveau_winsys_pipe.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c index 83faccde96..ec613ecbf6 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_winsys_softpipe.c \ No newline at end of file +../../drm/nouveau/nouveau_winsys_softpipe.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c b/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c index e05f0671d6..4455d8f924 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c +++ b/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c @@ -1 +1 @@ -../../dri/nouveau/nv04_surface.c \ No newline at end of file +../../drm/nouveau/nv04_surface.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c b/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c index 3850748229..19f102001e 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c +++ b/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c @@ -1 +1 @@ -../../dri/nouveau/nv50_surface.c \ No newline at end of file +../../drm/nouveau/nv50_surface.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index 0100fe37bd..42e7841df8 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -2,8 +2,8 @@ #include #include #include -#include #include +#include #include /* pipe_winsys implementation */ @@ -33,79 +33,79 @@ struct xsp_buffer static struct pipe_buffer* xsp_buffer_create(struct pipe_winsys *pws, unsigned alignment, unsigned usage, unsigned size) { struct xsp_buffer *buffer; - + assert(pws); - + buffer = calloc(1, sizeof(struct xsp_buffer)); buffer->base.refcount = 1; buffer->base.alignment = alignment; buffer->base.usage = usage; buffer->base.size = size; buffer->data = align_malloc(size, alignment); - + return (struct pipe_buffer*)buffer; } static struct pipe_buffer* xsp_user_buffer_create(struct pipe_winsys *pws, void *data, unsigned size) { struct xsp_buffer *buffer; - + assert(pws); - + buffer = calloc(1, sizeof(struct xsp_buffer)); buffer->base.refcount = 1; buffer->base.size = size; buffer->is_user_buffer = TRUE; buffer->data = data; - + return (struct pipe_buffer*)buffer; } static void* xsp_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buffer, unsigned flags) { struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; - + assert(pws); assert(buffer); - + xsp_buf->mapped_data = xsp_buf->data; - + return xsp_buf->mapped_data; } static void xsp_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buffer) { struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; - + assert(pws); assert(buffer); - + xsp_buf->mapped_data = NULL; } static void xsp_buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buffer) { struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; - + assert(pws); assert(buffer); - + if (!xsp_buf->is_user_buffer) align_free(xsp_buf->data); - + free(xsp_buf); } static struct pipe_surface* xsp_surface_alloc(struct pipe_winsys *pws) { struct pipe_surface *surface; - + assert(pws); - + surface = calloc(1, sizeof(struct pipe_surface)); surface->refcount = 1; surface->winsys = pws; - + return surface; } @@ -127,10 +127,10 @@ static int xsp_surface_alloc_storage ) { const unsigned int ALIGNMENT = 1; - + assert(pws); assert(surface); - + surface->width = width; surface->height = height; surface->format = format; @@ -140,28 +140,28 @@ static int xsp_surface_alloc_storage surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); surface->usage = flags; surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * surface->nblocksy); - + return 0; } static void xsp_surface_release(struct pipe_winsys *pws, struct pipe_surface **surface) { struct pipe_surface *s; - + assert(pws); assert(surface); assert(*surface); - + s = *surface; - + s->refcount--; - + if (s->refcount == 0) { pipe_buffer_reference(pws, &s->buffer, NULL); free(s); } - + *surface = NULL; } @@ -176,7 +176,7 @@ static int xsp_fence_signalled(struct pipe_winsys *pws, struct pipe_fence_handle { assert(pws); assert(fence); - + return 0; } @@ -184,30 +184,30 @@ static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *f { assert(pws); assert(fence); - + return 0; } static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private) -{ +{ struct xsp_pipe_winsys *xsp_winsys; struct xsp_context *xsp_context; - + assert(pws); assert(surface); assert(context_private); - + xsp_winsys = (struct xsp_pipe_winsys*)pws; xsp_context = (struct xsp_context*)context_private; - + if (!xsp_context->drawable_bound) return; - + xsp_winsys->fbimage.width = surface->width; xsp_winsys->fbimage.height = surface->height; xsp_winsys->fbimage.bytes_per_line = surface->width * (xsp_winsys->fbimage.bits_per_pixel >> 3); xsp_winsys->fbimage.data = pipe_surface_map(surface, 0); - + XPutImage ( xsp_context->display, @@ -236,25 +236,25 @@ static const char* xsp_get_name(struct pipe_winsys *pws) int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) { struct xsp_context *xsp_context; - + assert(pipe); - + xsp_context = pipe->priv; xsp_context->drawable = drawable; xsp_context->drawable_bound = 1; - + return 0; } int unbind_pipe_drawable(struct pipe_context *pipe) { struct xsp_context *xsp_context; - + assert(pipe); - + xsp_context = pipe->priv; xsp_context->drawable_bound = 0; - + return 0; } @@ -264,9 +264,9 @@ struct pipe_context* create_pipe_context(Display *display, int screen) struct xsp_context *xsp_context; struct pipe_screen *sp_screen; struct pipe_context *sp_pipe; - + assert(display); - + xsp_winsys = calloc(1, sizeof(struct xsp_pipe_winsys)); xsp_winsys->base.buffer_create = xsp_buffer_create; xsp_winsys->base.user_buffer_create = xsp_user_buffer_create; @@ -281,7 +281,7 @@ struct pipe_context* create_pipe_context(Display *display, int screen) xsp_winsys->base.fence_finish = xsp_fence_finish; xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer; xsp_winsys->base.get_name = xsp_get_name; - + { /* XXX: Can't use the returned XImage* directly, since we don't have control over winsys destruction @@ -299,22 +299,22 @@ struct pipe_context* create_pipe_context(Display *display, int screen) 32, 0 ); - + memcpy(&xsp_winsys->fbimage, template, sizeof(XImage)); XInitImage(&xsp_winsys->fbimage); - + XDestroyImage(template); } - + sp_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); sp_pipe = softpipe_create(sp_screen, (struct pipe_winsys*)xsp_winsys, NULL); - + xsp_context = calloc(1, sizeof(struct xsp_context)); xsp_context->display = display; xsp_context->screen = screen; - + sp_pipe->priv = xsp_context; - + return sp_pipe; } @@ -322,16 +322,15 @@ int destroy_pipe_context(struct pipe_context *pipe) { struct pipe_screen *screen; struct pipe_winsys *winsys; - + assert(pipe); - + screen = pipe->screen; winsys = pipe->winsys; free(pipe->priv); pipe->destroy(pipe); screen->destroy(screen); free(winsys); - + return 0; } - -- cgit v1.2.3 From 73193b7735eca10fd6a3bd7f43cdee72d3976175 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 12 Sep 2008 11:35:22 -0600 Subject: cell: fix twiddled tile display for XSHM. Fixed blank window problem. --- src/gallium/winsys/xlib/xm_winsys.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 2acbc94fc8..3334af175b 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -349,19 +349,26 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) if (x + w > surf->width) w = surf->width - x; - offset *= 4 * TILE_SIZE * TILE_SIZE; - - twiddle_tile((uint *) ((char *) xm_buf->data + offset), - tmpTile); - ximage->data = (char*) tmpTile; + /* offset in pixels */ + offset *= TILE_SIZE * TILE_SIZE; if (XSHM_ENABLED(xm_buf)) { + ximage->data = (char *) xm_buf->data + 4 * offset; + /* make copy of tile data */ + memcpy(tmpTile, (uint *) ximage->data, sizeof(tmpTile)); + /* twiddle from temp to ximage in shared memory */ + twiddle_tile(tmpTile, (uint *) ximage->data); + /* display image in shared memory */ #if defined(USE_XSHM) && !defined(XFree86Server) XShmPutImage(b->xm_visual->display, b->drawable, b->gc, ximage, 0, 0, x, y, w, h, False); #endif } else { + /* twiddel from ximage buffer to temp tile */ + twiddle_tile((uint *) xm_buf->data + offset, tmpTile); + /* display temp tile data */ + ximage->data = (char *) tmpTile; XPutImage(b->xm_visual->display, b->drawable, b->gc, ximage, 0, 0, x, y, w, h); } -- cgit v1.2.3 From 44e53b37a02933f238b438e5dc3a2891da5eb51a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 12 Sep 2008 11:35:22 -0600 Subject: cell: fix twiddled tile display for XSHM. Fixed blank window problem. --- src/gallium/winsys/xlib/xm_winsys.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 2acbc94fc8..3334af175b 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -349,19 +349,26 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) if (x + w > surf->width) w = surf->width - x; - offset *= 4 * TILE_SIZE * TILE_SIZE; - - twiddle_tile((uint *) ((char *) xm_buf->data + offset), - tmpTile); - ximage->data = (char*) tmpTile; + /* offset in pixels */ + offset *= TILE_SIZE * TILE_SIZE; if (XSHM_ENABLED(xm_buf)) { + ximage->data = (char *) xm_buf->data + 4 * offset; + /* make copy of tile data */ + memcpy(tmpTile, (uint *) ximage->data, sizeof(tmpTile)); + /* twiddle from temp to ximage in shared memory */ + twiddle_tile(tmpTile, (uint *) ximage->data); + /* display image in shared memory */ #if defined(USE_XSHM) && !defined(XFree86Server) XShmPutImage(b->xm_visual->display, b->drawable, b->gc, ximage, 0, 0, x, y, w, h, False); #endif } else { + /* twiddel from ximage buffer to temp tile */ + twiddle_tile((uint *) xm_buf->data + offset, tmpTile); + /* display temp tile data */ + ximage->data = (char *) tmpTile; XPutImage(b->xm_visual->display, b->drawable, b->gc, ximage, 0, 0, x, y, w, h); } -- cgit v1.2.3 From 56c22687e139e8fede6f7ea4d524699364dda07c Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 12 Sep 2008 15:10:43 -0400 Subject: g3dvl: Use winsys_buffer_reference() instead of pipe_buffer_reference(). Old pipe_buffer_reference() renamed winsys_buffer_reference(), new pipe_buffer_reference() expects a screen. --- src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c | 2 +- src/gallium/winsys/g3dvl/xsp_winsys.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c index 5d5380c250..4f6ac9cad0 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c @@ -84,7 +84,7 @@ nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s) *s = NULL; if (--surf->refcount <= 0) { if (surf->buffer) - pipe_buffer_reference(ws, &surf->buffer, NULL); + winsys_buffer_reference(ws, &surf->buffer, NULL); free(surf); } } diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index 42e7841df8..68be2c2ea3 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -158,7 +158,7 @@ static void xsp_surface_release(struct pipe_winsys *pws, struct pipe_surface **s if (s->refcount == 0) { - pipe_buffer_reference(pws, &s->buffer, NULL); + winsys_buffer_reference(pws, &s->buffer, NULL); free(s); } -- cgit v1.2.3 From 4c9cd725d54edf9baacef83d94c6487c7d592090 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 15 Sep 2008 17:55:09 +0200 Subject: i915simple: dri winsys does now compile and works Glxgears hits an assert, but tri works --- src/gallium/winsys/drm/intel/dri/intel_screen.c | 387 +++++++++++++++--------- 1 file changed, 242 insertions(+), 145 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/dri/intel_screen.c b/src/gallium/winsys/drm/intel/dri/intel_screen.c index 3a486481f5..3465f8a4d9 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_screen.c +++ b/src/gallium/winsys/drm/intel/dri/intel_screen.c @@ -113,7 +113,118 @@ static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; extern const struct dri_extension card_extensions[]; +static GLboolean +intel_get_param(__DRIscreenPrivate *psp, int param, int *value) +{ + int ret; + struct drm_i915_getparam gp; + gp.param = param; + gp.value = value; + + ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drm_i915_getparam: %d\n", ret); + return GL_FALSE; + } + + return GL_TRUE; +} + +static void +intelSetTexOffset(__DRIcontext *pDRICtx, int texname, + unsigned long long offset, int depth, uint pitch) +{ + abort(); +#if 0 + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct st_texture_object *stObj = st_texture_object(tObj); + + if (!stObj) + return; + + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); + + stObj->imageOverride = GL_TRUE; + stObj->depthOverride = depth; + stObj->pitchOverride = pitch; + + if (offset) + stObj->textureOffset = offset; +#endif +} + + +#if 0 +static void +intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv, + __DRIcontextPrivate *pcp, + __DRIDrawableConfigEvent *event) +{ + (void) dPriv; + (void) pcp; + (void) event; +} +#endif + +#if 0 +static void +intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, + __DRIcontextPrivate *pcp, + __DRIBufferAttachEvent *ba) +{ + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + + switch (ba->buffer.attachment) { + case DRI_DRAWABLE_BUFFER_FRONT_LEFT: + intelScreen->front.width = dPriv->w; + intelScreen->front.height = dPriv->h; + intelScreen->front.cpp = ba->buffer.cpp; + intelScreen->front.pitch = ba->buffer.pitch; + driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); + driBOSetReferenced(intelScreen->front.buffer, ba->buffer.handle); + break; + + case DRI_DRAWABLE_BUFFER_BACK_LEFT: + case DRI_DRAWABLE_BUFFER_DEPTH: + case DRI_DRAWABLE_BUFFER_STENCIL: + case DRI_DRAWABLE_BUFFER_ACCUM: + /* anything ?? */ + break; + + default: + fprintf(stderr, "unhandled buffer attach event, attachment type %d\n", + ba->buffer.attachment); + return; + } +} +#endif + +static const __DRItexOffsetExtension intelTexOffsetExtension = { + { __DRI_TEX_OFFSET }, + intelSetTexOffset, +}; + +#if 0 +static const __DRItexBufferExtension intelTexBufferExtension = { + { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, + intelSetTexBuffer, +}; +#endif + +static const __DRIextension *intelScreenExtensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + &intelTexOffsetExtension.base, +// &intelTexBufferExtension.base, + NULL +}; static void @@ -232,7 +343,8 @@ intelCreatePools(__DRIscreenPrivate * sPriv) intelScreen->havePools = GL_TRUE; - intelUpdateScreenRotation(sPriv, intelScreen->sarea); + if (intelScreen->sarea) + intelUpdateScreenRotation(sPriv, intelScreen->sarea); return GL_TRUE; } @@ -253,10 +365,12 @@ intel_flush_frontbuffer( struct pipe_winsys *winsys, struct pipe_surface *surf, void *context_private) { - struct intel_context *intel = (struct intel_context *) context_private; - __DRIdrawablePrivate *dPriv = intel->driDrawable; + //struct intel_context *intel = (struct intel_context *) context_private; + //__DRIdrawablePrivate *dPriv = intel->driDrawable; - intelDisplaySurface(dPriv, surf, NULL); + //assert((int)"Doesn't work currently" & 0); + + //intelDisplaySurface(dPriv, surf, NULL); } static boolean @@ -265,11 +379,6 @@ intelInitDriver(__DRIscreenPrivate * sPriv) struct intel_screen *intelScreen; I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> - getProcAddress("glxEnableExtension")); - void *const psc = sPriv->psc->screenConfigs; - if (sPriv->devPrivSize != sizeof(I830DRIRec)) { fprintf(stderr, "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); @@ -286,28 +395,19 @@ intelInitDriver(__DRIscreenPrivate * sPriv) __driConfigOptions, __driNConfigOptions); sPriv->private = (void *) intelScreen; - intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + - gDRIPriv->sarea_priv_offset); - intelScreen->deviceID = gDRIPriv->deviceID; - intelScreen->front.cpp = gDRIPriv->cpp; - intelScreen->drmMinor = sPriv->drmMinor; + gDRIPriv->sarea_priv_offset); - assert(gDRIPriv->bitsPerPixel == 16 || - gDRIPriv->bitsPerPixel == 32); + intelScreen->deviceID = gDRIPriv->deviceID; + intelScreen->front.cpp = gDRIPriv->cpp; + intelScreen->drmMinor = sPriv->drm_version.minor; intelUpdateScreenRotation(sPriv, intelScreen->sarea); if (0) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - if (glx_enable_extension != NULL) { - (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); - (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); - (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); - } + sPriv->extensions = intelScreenExtensions; intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; intelScreen->base.base.get_name = intel_get_name; @@ -406,65 +506,19 @@ intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) return 0; } - -static void -intelSetTexOffset(__DRIcontext *pDRICtx, int texname, - unsigned long long offset, int depth, uint pitch) +static __DRIconfig ** +intelFillInModes(__DRIscreenPrivate *psp, + unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) { - abort(); -#if 0 - struct intel_context *intel = (struct intel_context*) - ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; - struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); - struct st_texture_object *stObj = st_texture_object(tObj); - - if (!stObj) - return; - - if (stObj->pt) - st->pipe->texture_release(intel->st->pipe, &stObj->pt); - - stObj->imageOverride = GL_TRUE; - stObj->depthOverride = depth; - stObj->pitchOverride = pitch; - - if (offset) - stObj->textureOffset = offset; -#endif -} - - -static const struct __DriverAPIRec intelAPI = { - .InitDriver = intelInitDriver, - .DestroyScreen = intelDestroyScreen, - .CreateContext = intelCreateContext, - .DestroyContext = intelDestroyContext, - .CreateBuffer = intelCreateBuffer, - .DestroyBuffer = intelDestroyBuffer, - .SwapBuffers = intelSwapBuffers, - .MakeCurrent = intelMakeCurrent, - .UnbindContext = intelUnbindContext, - .GetSwapInfo = intelGetSwapInfo, - .GetMSC = driGetMSC32, - .WaitForMSC = driWaitForMSC32, - .WaitForSBC = NULL, - .SwapBuffersMSC = NULL, - .CopySubBuffer = intelCopySubBuffer, - .setTexOffset = intelSetTexOffset, -}; - - -static __GLcontextModes * -intelFillInModes(unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, boolean have_back_buffer) -{ - __GLcontextModes *modes; + __DRIconfig **configs; __GLcontextModes *m; unsigned num_modes; unsigned depth_buffer_factor; unsigned back_buffer_factor; GLenum fb_format; GLenum fb_type; + int i; /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't * support pageflipping at all. @@ -508,100 +562,143 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; } - modes = - (*dri_interface->createContextModes) (num_modes, - sizeof(__GLcontextModes)); - m = modes; - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, msaa_samples_array, 1, GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, msaa_samples_array, 1, GLX_DIRECT_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + configs = driCreateConfigs(fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor); + if (configs == NULL) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; } /* Mark the visual as slow if there are "fake" stencil bits. */ - for (m = modes; m != NULL; m = m->next) { + for (i = 0; configs[i]; i++) { + m = &configs[i]->modes; if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { m->visualRating = GLX_SLOW_CONFIG; } } - return modes; + return configs; } - /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. + * + * \todo maybe fold this into intelInitDriver * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \return the __GLcontextModes supported by this driver */ -PUBLIC void * -__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, - __DRIscreen * psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) +static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; - static const __DRIversion ddx_expected = { 1, 7, 0 }; +#ifdef I915 + static const __DRIversion ddx_expected = { 1, 5, 0 }; +#else + static const __DRIversion ddx_expected = { 1, 6, 0 }; +#endif static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 7, 0 }; - - dri_interface = interface; + static const __DRIversion drm_expected = { 1, 5, 0 }; + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; if (!driCheckDriDdxDrmVersions2("i915", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { + &psp->dri_version, &dri_expected, + &psp->ddx_version, &ddx_expected, + &psp->drm_version, &drm_expected)) { return NULL; } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &intelAPI); - - if (psp != NULL) { - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - *driver_modes = intelFillInModes(dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, 1); - - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create - * is called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions(NULL, card_extensions, GL_FALSE); + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + //intelInitExtensions(NULL, GL_TRUE); + + if (!intelInitDriver(psp)) + return NULL; + + psp->extensions = intelScreenExtensions; + + return (const __DRIconfig **) + intelFillInModes(psp, dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); +} + +/** + * This is the driver specific part of the createNewScreen entry point. + * + * \return the __GLcontextModes supported by this driver + */ +static const +__DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp) +{ + struct intel_screen *intelScreen; + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + //intelInitExtensions(NULL, GL_TRUE); + + /* Allocate the private area */ + intelScreen = CALLOC_STRUCT(intel_screen); + if (!intelScreen) { + fprintf(stderr, "\nERROR! Allocating private area failed\n"); + return GL_FALSE; } + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); + + psp->private = (void *) intelScreen; - return (void *) psp; + intelScreen->drmMinor = psp->drm_version.minor; + + /* Determine chipset ID? */ + if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID, + &intelScreen->deviceID)) + return GL_FALSE; + + psp->extensions = intelScreenExtensions; + + intel_be_init_device(&intelScreen->base, psp->fd, intelScreen->deviceID); + intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; + intelScreen->base.base.get_name = intel_get_name; + + return driConcatConfigs(intelFillInModes(psp, 16, 16, 0, 1), + intelFillInModes(psp, 32, 24, 8, 1)); } +const struct __DriverAPIRec driDriverAPI = { + .InitScreen = intelInitScreen, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetDrawableMSC = driDrawableGetMSC32, + .WaitForMSC = driWaitForMSC32, + .CopySubBuffer = intelCopySubBuffer, + + //.InitScreen2 = intelInitScreen2, + //.HandleDrawableConfig = intelHandleDrawableConfig, + //.HandleBufferAttach = intelHandleBufferAttach, +}; -- cgit v1.2.3 From c6dc1bf6e08b264681d3230cac08bd7d8ee6c964 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 19 Sep 2008 14:16:19 +0200 Subject: i915simple: Fix extentions being loaded --- src/gallium/winsys/drm/intel/dri/intel_screen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/dri/intel_screen.c b/src/gallium/winsys/drm/intel/dri/intel_screen.c index 3465f8a4d9..a0cb1472a9 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_screen.c +++ b/src/gallium/winsys/drm/intel/dri/intel_screen.c @@ -619,6 +619,7 @@ static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp) * * Hello chicken. Hello egg. How are you two today? */ + driInitExtensions( NULL, card_extensions, GL_FALSE ); //intelInitExtensions(NULL, GL_TRUE); if (!intelInitDriver(psp)) -- cgit v1.2.3 From 82623bf2e515a862a69c8bce351a2bcb6937589c Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 19 Sep 2008 14:46:24 +0200 Subject: i915simple: Front flushing does work --- src/gallium/winsys/drm/intel/dri/intel_screen.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/dri/intel_screen.c b/src/gallium/winsys/drm/intel/dri/intel_screen.c index a0cb1472a9..6f94e642c1 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_screen.c +++ b/src/gallium/winsys/drm/intel/dri/intel_screen.c @@ -365,12 +365,10 @@ intel_flush_frontbuffer( struct pipe_winsys *winsys, struct pipe_surface *surf, void *context_private) { - //struct intel_context *intel = (struct intel_context *) context_private; - //__DRIdrawablePrivate *dPriv = intel->driDrawable; + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; - //assert((int)"Doesn't work currently" & 0); - - //intelDisplaySurface(dPriv, surf, NULL); + intelDisplaySurface(dPriv, surf, NULL); } static boolean -- cgit v1.2.3 From d3172cddbf814b0ce6877faff9a7d73b99272faa Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Fri, 19 Sep 2008 14:13:57 +0100 Subject: fix for MSAA --- src/gallium/winsys/drm/intel/dri/intel_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/dri/intel_screen.c b/src/gallium/winsys/drm/intel/dri/intel_screen.c index 6f94e642c1..113f62f03a 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_screen.c +++ b/src/gallium/winsys/drm/intel/dri/intel_screen.c @@ -563,7 +563,7 @@ intelFillInModes(__DRIscreenPrivate *psp, configs = driCreateConfigs(fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, - back_buffer_factor); + back_buffer_factor, NULL, 0); if (configs == NULL) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); -- cgit v1.2.3 From 89f47d1645c9f8a61de59792a85d1f380c0b3524 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 19 Sep 2008 15:25:29 +0200 Subject: i915simple: Use defined MSAA array --- src/gallium/winsys/drm/intel/dri/intel_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/dri/intel_screen.c b/src/gallium/winsys/drm/intel/dri/intel_screen.c index 113f62f03a..78b9a6db05 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_screen.c +++ b/src/gallium/winsys/drm/intel/dri/intel_screen.c @@ -563,7 +563,7 @@ intelFillInModes(__DRIscreenPrivate *psp, configs = driCreateConfigs(fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, - back_buffer_factor, NULL, 0); + back_buffer_factor, msaa_samples_array, 1); if (configs == NULL) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); -- cgit v1.2.3 From 44d5e607c7a8794007a29a5e2399f98615ec8def Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 19 Sep 2008 10:41:03 -0600 Subject: cell: disable XShmPutImage for tiled surface for now Multiple displays of same surface data causes pixels to get scrambled. --- src/gallium/winsys/xlib/xm_winsys.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 3334af175b..acb5ad8f71 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -352,7 +352,7 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) /* offset in pixels */ offset *= TILE_SIZE * TILE_SIZE; - if (XSHM_ENABLED(xm_buf)) { + if (0 && XSHM_ENABLED(xm_buf)) { ximage->data = (char *) xm_buf->data + 4 * offset; /* make copy of tile data */ memcpy(tmpTile, (uint *) ximage->data, sizeof(tmpTile)); @@ -365,7 +365,7 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) #endif } else { - /* twiddel from ximage buffer to temp tile */ + /* twiddle from ximage buffer to temp tile */ twiddle_tile((uint *) xm_buf->data + offset, tmpTile); /* display temp tile data */ ximage->data = (char *) tmpTile; -- cgit v1.2.3 From da85a94d99cfbd8f094a475fb2272efb4e87b9a9 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 21 Sep 2008 14:12:04 +0200 Subject: nouveau: init scaled_image_from_memory object for swizzled surface upload --- src/gallium/winsys/drm/nouveau/nv04_surface.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c index 8fa3d106c8..36c913a732 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -298,6 +298,22 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) } BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); + OUT_RING (chan, nvc->channel->vram->handle); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); + OUT_RING (chan, nvc->NvSwzSurf); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_PATTERN, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_ROP, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_BETA1, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_BETA4, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); return 0; } -- cgit v1.2.3 From e9c722b660ee8fc0aa73335d447f1dd8bced6fe2 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Fri, 26 Sep 2008 14:19:18 +0100 Subject: st: change from ** to * for st_unreference_framebuffer() --- src/gallium/winsys/drm/intel/dri/intel_screen.c | 2 +- src/gallium/winsys/drm/intel/egl/intel_device.c | 2 +- src/gallium/winsys/egl_xlib/egl_xlib.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/dri/intel_screen.c b/src/gallium/winsys/drm/intel/dri/intel_screen.c index 78b9a6db05..ed75368982 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_screen.c +++ b/src/gallium/winsys/drm/intel/dri/intel_screen.c @@ -485,7 +485,7 @@ intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) { struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv); assert(intelfb->stfb); - st_unreference_framebuffer(&intelfb->stfb); + st_unreference_framebuffer(intelfb->stfb); free(intelfb); } diff --git a/src/gallium/winsys/drm/intel/egl/intel_device.c b/src/gallium/winsys/drm/intel/egl/intel_device.c index b9649cbec7..1964745c99 100644 --- a/src/gallium/winsys/drm/intel/egl/intel_device.c +++ b/src/gallium/winsys/drm/intel/egl/intel_device.c @@ -131,7 +131,7 @@ intel_destroy_drawable(struct egl_drm_drawable *drawable) drawable->priv = NULL; assert(intelfb->stfb); - st_unreference_framebuffer(&intelfb->stfb); + st_unreference_framebuffer(intelfb->stfb); free(intelfb); return TRUE; } diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index e9f821d276..477d766925 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -537,7 +537,7 @@ xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) } else { XFreeGC(surf->Dpy, surf->Gc); - st_unreference_framebuffer(&surf->Framebuffer); + st_unreference_framebuffer(surf->Framebuffer); free(surf); } return EGL_TRUE; -- cgit v1.2.3 From 2882a2db7a766c60bb231978ea829632438dd8a4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 30 Sep 2008 12:06:56 +1000 Subject: nouveau: some small API changes --- src/gallium/winsys/drm/nouveau/nouveau_screen.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/nouveau_screen.c index 9489645151..c6d0c53588 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/drm/nouveau/nouveau_screen.c @@ -114,7 +114,7 @@ nouveau_destroy_buffer(__DRIdrawablePrivate * driDrawPriv) struct nouveau_framebuffer *nvfb; nvfb = (struct nouveau_framebuffer *)driDrawPriv->driverPrivate; - st_unreference_framebuffer(&nvfb->stfb); + st_unreference_framebuffer(nvfb->stfb); free(nvfb); } @@ -133,8 +133,9 @@ nouveau_fill_in_modes(__DRIscreenPrivate *psp, GLX_NONE, GLX_SWAP_UNDEFINED_OML, }; - u_int8_t depth_bits_array[3]; - u_int8_t stencil_bits_array[3]; + 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; @@ -148,9 +149,10 @@ nouveau_fill_in_modes(__DRIscreenPrivate *psp, 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; @@ -167,7 +169,7 @@ nouveau_fill_in_modes(__DRIscreenPrivate *psp, configs = driCreateConfigs(fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, - back_buffer_factor); + back_buffer_factor, msaa_samples_array, 1); if (configs == NULL) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); -- cgit v1.2.3 From af59f767a03da4dd434a6d655e3d0bc05feb298a Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 7 Oct 2008 21:47:45 +0200 Subject: nouveau: first draft of swizzle texture upload to vram --- src/gallium/winsys/drm/nouveau/nv04_surface.c | 83 +++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c index 36c913a732..5bf89e1952 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -3,6 +3,32 @@ #include "nouveau_context.h" +static INLINE int log2i(int i) +{ + int r = 0; + + if (i & 0xffff0000) { + i >>= 16; + r += 16; + } + if (i & 0x0000ff00) { + i >>= 8; + r += 8; + } + if (i & 0x000000f0) { + i >>= 4; + r += 4; + } + if (i & 0x0000000c) { + i >>= 2; + r += 2; + } + if (i & 0x00000002) { + r += 1; + } + return r; +} + static INLINE int nv04_surface_format(enum pipe_format format) { @@ -81,6 +107,56 @@ nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, OUT_RING (chan, ( h << 16) | w); } +static int +nv04_surface_copy_prep_swizzled(struct nouveau_context *nv, + struct pipe_surface *dst, + struct pipe_surface *src) +{ + struct nouveau_channel *chan = nv->nvc->channel; + + BEGIN_RING(chan, nv->nvc->NvSwzSurf, + NV04_SWIZZLED_SURFACE_FORMAT, 2); + /* FIXME: read destination format from somewhere */ + OUT_RING (chan, + NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8 + | (log2i(dst->width)<height)<buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 13); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); + /* FIXME: read source format from somewhere */ + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); + OUT_RING (chan, 0); + OUT_RING (chan, (src->height<<16) | src->width); + OUT_RING (chan, 0); + OUT_RING (chan, (src->height<<16) | src->width); + OUT_RING (chan, 1<<20); + OUT_RING (chan, 1<<20); + OUT_RING (chan, (src->height<<16) | src->width); + OUT_RING (chan, + src->stride + | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER + | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RING (chan, 0); + + BEGIN_RING(chan, nv->nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + nv->surface_copy = nv04_surface_copy_m2mf; + nv->surf_dst = dst; + nv->surf_src = src; + return 0; +} + static int nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, struct pipe_surface *src) @@ -91,6 +167,13 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, if (src->format != dst->format) return 1; + /* Setup transfer to swizzle the texture to vram if needed */ + /* FIXME/TODO: check proper limits of this operation */ + if (nouveau_buffer(dst->buffer)->bo->flags & NOUVEAU_BO_SWIZZLED) { + /* FIXME: Disable it for the moment */ + /*return nv04_surface_copy_prep_swizzled(nv, dst, src);*/ + } + /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback * to NV_MEMORY_TO_MEMORY_FORMAT in this case. */ -- cgit v1.2.3 From 06c43beee08052bae3832586559889d74fb538b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 23 Oct 2008 10:27:39 +0200 Subject: scons: Don't hardcode any drivers for the xlib winsys, just pick suitable ones. --- src/gallium/winsys/xlib/SConscript | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 324fbef306..3aef3b6ced 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -5,8 +5,7 @@ Import('*') if env['platform'] == 'linux' \ and 'mesa' in env['statetrackers'] \ - and 'softpipe' in env['drivers'] \ - and 'i965simple' in env['drivers'] \ + and ('softpipe' or 'i915simple' or 'trace') in env['drivers'] \ and not env['dri']: env = env.Clone() @@ -22,15 +21,20 @@ if env['platform'] == 'linux' \ 'xfonts.c', 'xm_api.c', 'xm_winsys.c', - 'xm_winsys_aub.c', - 'brw_aub.c', ] + + drivers = []; + + if 'softpipe' in env['drivers']: + drivers += [softpipe] + + if 'i965simple' in env['drivers']: + drivers += [i965simple] + sources += [ + 'brw_aub.c', + 'xm_winsys_aub.c', + ] - drivers = [ - softpipe, - i965simple, - ] - if 'trace' in env['drivers']: env.Append(CPPDEFINES = 'GALLIUM_TRACE') drivers += [trace] -- cgit v1.2.3 From 64a9908816a95849557678c8cab6071aa086f7e2 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 5 Nov 2008 16:49:48 +0100 Subject: i915: Remove faulty assert --- src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c b/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c index 8a18bfd9a4..34ad7eebe1 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c +++ b/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c @@ -94,7 +94,6 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, int i; ASSERT(surf->buffer); - ASSERT(surf->cpp == cpp); DBG(SWAP, "screen pitch %d src surface pitch %d\n", pitch, surf->stride); -- cgit v1.2.3 From 0da43322bbc6ead4eeb1b9fe079a33e0d57bece5 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 8 Nov 2008 18:32:33 +0200 Subject: Nouveau: build, link and use nv20. Signed-off-by: Pekka Paalanen --- src/gallium/winsys/drm/nouveau/Makefile | 1 + src/gallium/winsys/drm/nouveau/nouveau_winsys.c | 5 ++++- src/gallium/winsys/g3dvl/nouveau/Makefile | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile index be630ff6d1..81562ca78d 100644 --- a/src/gallium/winsys/drm/nouveau/Makefile +++ b/src/gallium/winsys/drm/nouveau/Makefile @@ -10,6 +10,7 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.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 diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys.c index 0878840dcc..364340e1d3 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/drm/nouveau/nouveau_winsys.c @@ -101,10 +101,13 @@ nouveau_pipe_create(struct nouveau_context *nv) switch (chipset & 0xf0) { case 0x10: - case 0x20: hws_create = nv10_screen_create; hw_create = nv10_create; break; + case 0x20: + hws_create = nv20_screen_create; + hw_create = nv20_create; + break; case 0x30: hws_create = nv30_screen_create; hw_create = nv30_create; diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 5d11bde322..ff43327778 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -26,11 +26,12 @@ LDFLAGS += -L${DRMDIR}/lib \ -L${GALLIUMDIR}/auxiliary/rtasm \ -L${GALLIUMDIR}/auxiliary/cso_cache \ -L${GALLIUMDIR}/drivers/nv10 \ + -L${GALLIUMDIR}/drivers/nv20 \ -L${GALLIUMDIR}/drivers/nv30 \ -L${GALLIUMDIR}/drivers/nv40 \ -L${GALLIUMDIR}/drivers/nv50 -LIBS += -ldriclient -ldrm -lnv10 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm +LIBS += -ldriclient -ldrm -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm ############################################# -- cgit v1.2.3 From 66eacb3fed6bc1926e1925b164b7168a6e0a82d5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 10 Nov 2008 15:58:03 +1100 Subject: nouveau: pass object handle not pointer to GPU... --- src/gallium/winsys/drm/nouveau/nv04_surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c index 5bf89e1952..d08955de71 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -386,7 +386,7 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); OUT_RING (chan, nvc->channel->vram->handle); BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); - OUT_RING (chan, nvc->NvSwzSurf); + OUT_RING (chan, nvc->NvSwzSurf->handle); BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_PATTERN, 1); OUT_RING (chan, 0); BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_ROP, 1); -- cgit v1.2.3 From 56ef0aeda5d23bf0c6147fd9d20d61abd18207af Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sat, 15 Nov 2008 12:10:32 +0100 Subject: i915: Silence warning --- src/gallium/winsys/drm/intel/egl/intel_egl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/egl/intel_egl.c b/src/gallium/winsys/drm/intel/egl/intel_egl.c index 3204ed3131..ed464076ee 100644 --- a/src/gallium/winsys/drm/intel/egl/intel_egl.c +++ b/src/gallium/winsys/drm/intel/egl/intel_egl.c @@ -565,7 +565,7 @@ static struct drm_mode_modeinfo * drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) { int i; - struct drm_mode_modeinfo *m; + struct drm_mode_modeinfo *m = NULL; for (i = 0; i < connector->count_modes; i++) { m = &connector->modes[i]; -- cgit v1.2.3 From 6cf59e1293c5777ba5675e6315cbfad3211f9260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 18 Nov 2008 19:13:32 +0900 Subject: scons: Support MinGW32 cross compiler. To build an alternative opengl32.dll with Gallium's software-rasterizer from a debian-based distribution run: sudo apt-get install mingw32 scons platform=windows toolchain=crossmingw machine=x86 winsys=gdi dri=no --- src/gallium/winsys/gdi/SConscript | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript index 170fdf5127..dce81ec1ca 100644 --- a/src/gallium/winsys/gdi/SConscript +++ b/src/gallium/winsys/gdi/SConscript @@ -13,6 +13,12 @@ if env['platform'] == 'windows': '#src/mesa/main', ]) + env.Append(CPPDEFINES = [ + '__GL_EXPORTS', + 'BUILD_GL32', + '_GNU_H_WINDOWS32_DEFINES', + ]) + sources = [ 'opengl32.def', 'wgl.c', -- cgit v1.2.3 From 15b92b09e0f066a9d38c445b80b33193a8d9ea14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 18 Nov 2008 19:13:32 +0900 Subject: scons: Support MinGW32 cross compiler. To build an alternative opengl32.dll with Gallium's software-rasterizer from a debian-based distribution run: sudo apt-get install mingw32 scons platform=windows toolchain=crossmingw machine=x86 winsys=gdi dri=no --- src/gallium/winsys/gdi/SConscript | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript index 170fdf5127..dce81ec1ca 100644 --- a/src/gallium/winsys/gdi/SConscript +++ b/src/gallium/winsys/gdi/SConscript @@ -13,6 +13,12 @@ if env['platform'] == 'windows': '#src/mesa/main', ]) + env.Append(CPPDEFINES = [ + '__GL_EXPORTS', + 'BUILD_GL32', + '_GNU_H_WINDOWS32_DEFINES', + ]) + sources = [ 'opengl32.def', 'wgl.c', -- cgit v1.2.3 From 76624096617c7218d828c5de9c02e70d578c37c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 21 Nov 2008 05:25:31 +0900 Subject: gdi: Reimplement using the WGL statetracker. --- src/gallium/winsys/gdi/SConscript | 20 +- src/gallium/winsys/gdi/colors.h | 29 - src/gallium/winsys/gdi/gdi_softpipe_winsys.c | 344 +++++++++++ src/gallium/winsys/gdi/opengl32.def | 859 --------------------------- src/gallium/winsys/gdi/wgl.c | 701 ---------------------- src/gallium/winsys/gdi/wmesa.c | 823 ------------------------- src/gallium/winsys/gdi/wmesadef.h | 40 -- 7 files changed, 352 insertions(+), 2464 deletions(-) delete mode 100644 src/gallium/winsys/gdi/colors.h create mode 100644 src/gallium/winsys/gdi/gdi_softpipe_winsys.c delete mode 100644 src/gallium/winsys/gdi/opengl32.def delete mode 100644 src/gallium/winsys/gdi/wgl.c delete mode 100644 src/gallium/winsys/gdi/wmesa.c delete mode 100644 src/gallium/winsys/gdi/wmesadef.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript index dce81ec1ca..b463fa6505 100644 --- a/src/gallium/winsys/gdi/SConscript +++ b/src/gallium/winsys/gdi/SConscript @@ -8,32 +8,28 @@ if env['platform'] == 'windows': env = env.Clone() env.Append(CPPPATH = [ - '#src/mesa/glapi', - '#src/mesa', - '#src/mesa/main', + '#src/mesa/state_tracker/wgl', ]) env.Append(CPPDEFINES = [ - '__GL_EXPORTS', - 'BUILD_GL32', - '_GNU_H_WINDOWS32_DEFINES', ]) sources = [ - 'opengl32.def', - 'wgl.c', - 'wmesa.c', + '#src/mesa/state_tracker/wgl/opengl32.def', + 'gdi_softpipe_winsys.c', ] drivers = [ softpipe, ] - env.Append(LIBS = ['gdi32', 'user32']) + env.Append(LIBS = [ + 'gdi32', + 'user32' + ]) - # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions env.SharedLibrary( target ='opengl32', source = sources, - LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], + LIBS = wgl + glapi + mesa + drivers + auxiliaries + env['LIBS'], ) diff --git a/src/gallium/winsys/gdi/colors.h b/src/gallium/winsys/gdi/colors.h deleted file mode 100644 index 03e512c1fa..0000000000 --- a/src/gallium/winsys/gdi/colors.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Values for wmesa->pixelformat: */ - -#define PF_8A8B8G8R 3 /* 32-bit TrueColor: 8-A, 8-B, 8-G, 8-R */ -#define PF_8R8G8B 4 /* 32-bit TrueColor: 8-R, 8-G, 8-B */ -#define PF_5R6G5B 5 /* 16-bit TrueColor: 5-R, 6-G, 5-B bits */ -#define PF_DITHER8 6 /* Dithered RGB using a lookup table */ -#define PF_LOOKUP 7 /* Undithered RGB using a lookup table */ -#define PF_GRAYSCALE 10 /* Grayscale or StaticGray */ -#define PF_BADFORMAT 11 -#define PF_INDEX8 12 - - -#define BGR8(r,g,b) (unsigned)(((BYTE)((b & 0xc0) | ((g & 0xe0)>>2) | \ - ((r & 0xe0)>>5)))) - -/* Windows uses 5,5,5 for 16-bit */ -#define BGR16(r,g,b) ( (((unsigned short)b ) >> 3) | \ - (((unsigned short)g & 0xf8) << 2) | \ - (((unsigned short)r & 0xf8) << 7) ) - -#define BGR24(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)| \ - ((WORD)((BYTE)(g))<<8))| \ - (((DWORD)(BYTE)(r))<<16))) - -#define BGR32(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)| \ - ((WORD)((BYTE)(g))<<8))| \ - (((DWORD)(BYTE)(r))<<16))) - - diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c new file mode 100644 index 0000000000..e66ce48f2d --- /dev/null +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -0,0 +1,344 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * @file + * Softpipe support. + * + * @author Keith Whitwell + * @author Brian Paul + * @author Jose Fonseca + */ + + +#include + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "softpipe/sp_winsys.h" +#include "stw_winsys.h" + + +struct gdi_softpipe_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; +}; + + +/** Cast wrapper */ +static INLINE struct gdi_softpipe_buffer * +gdi_softpipe_buffer( struct pipe_buffer *buf ) +{ + return (struct gdi_softpipe_buffer *)buf; +} + + +static void * +gdi_softpipe_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags) +{ + struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf); + gdi_softpipe_buf->mapped = gdi_softpipe_buf->data; + return gdi_softpipe_buf->mapped; +} + + +static void +gdi_softpipe_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf); + gdi_softpipe_buf->mapped = NULL; +} + + +static void +gdi_softpipe_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct gdi_softpipe_buffer *oldBuf = gdi_softpipe_buffer(buf); + + if (oldBuf->data) { + if (!oldBuf->userBuffer) + align_free(oldBuf->data); + + oldBuf->data = NULL; + } + + FREE(oldBuf); +} + + +static const char * +gdi_softpipe_get_name(struct pipe_winsys *winsys) +{ + return "softpipe"; +} + + +static struct pipe_buffer * +gdi_softpipe_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct gdi_softpipe_buffer *buffer = CALLOC_STRUCT(gdi_softpipe_buffer); + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + buffer->data = align_malloc(size, alignment); + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +gdi_softpipe_user_buffer_create(struct pipe_winsys *winsys, + void *ptr, + unsigned bytes) +{ + struct gdi_softpipe_buffer *buffer; + + buffer = CALLOC_STRUCT(gdi_softpipe_buffer); + if(!buffer) + return NULL; + + buffer->base.refcount = 1; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + + +static int +gdi_softpipe_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->stride * surf->nblocksy); + if(!surf->buffer) + return -1; + + return 0; +} + + +static struct pipe_surface * +gdi_softpipe_surface_alloc(struct pipe_winsys *winsys) +{ + struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); + + assert(winsys); + + surface->refcount = 1; + surface->winsys = winsys; + + return surface; +} + + +static void +gdi_softpipe_surface_release(struct pipe_winsys *winsys, + struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + assert(!surf->texture); + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + winsys_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + +static void +gdi_softpipe_dummy_flush_frontbuffer(struct pipe_winsys *winsys, + struct pipe_surface *surface, + void *context_private) +{ + assert(0); +} + + +static void +gdi_softpipe_fence_reference(struct pipe_winsys *winsys, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +gdi_softpipe_fence_signalled(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +gdi_softpipe_fence_finish(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static void +gdi_softpipe_destroy(struct pipe_winsys *winsys) +{ + FREE(winsys); +} + + +static struct pipe_screen * +gdi_softpipe_screen_create(void) +{ + static struct pipe_winsys *winsys; + struct pipe_screen *screen; + + winsys = CALLOC_STRUCT(pipe_winsys); + if(!winsys) + return NULL; + + winsys->destroy = gdi_softpipe_destroy; + + winsys->buffer_create = gdi_softpipe_buffer_create; + winsys->user_buffer_create = gdi_softpipe_user_buffer_create; + winsys->buffer_map = gdi_softpipe_buffer_map; + winsys->buffer_unmap = gdi_softpipe_buffer_unmap; + winsys->buffer_destroy = gdi_softpipe_buffer_destroy; + + winsys->surface_alloc = gdi_softpipe_surface_alloc; + winsys->surface_alloc_storage = gdi_softpipe_surface_alloc_storage; + winsys->surface_release = gdi_softpipe_surface_release; + + winsys->fence_reference = gdi_softpipe_fence_reference; + winsys->fence_signalled = gdi_softpipe_fence_signalled; + winsys->fence_finish = gdi_softpipe_fence_finish; + + winsys->flush_frontbuffer = gdi_softpipe_dummy_flush_frontbuffer; + winsys->get_name = gdi_softpipe_get_name; + + screen = softpipe_create_screen(winsys); + if(!screen) + gdi_softpipe_destroy(winsys); + + return screen; +} + + +static struct pipe_context * +gdi_softpipe_context_create(struct pipe_screen *screen) +{ + return softpipe_create(screen, screen->winsys, NULL); +} + + +static void +gdi_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, + struct pipe_surface *surface, + HDC hDC) +{ + struct gdi_softpipe_buffer *buffer; + BITMAPINFO bmi; + + buffer = gdi_softpipe_buffer(surface->buffer); + + memset(&bmi, 0, sizeof(BITMAPINFO)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = surface->stride / pf_get_size(surface->format); + bmi.bmiHeader.biHeight= -surface->height; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = pf_get_bits(surface->format); + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = 0; + bmi.bmiHeader.biXPelsPerMeter = 0; + bmi.bmiHeader.biYPelsPerMeter = 0; + bmi.bmiHeader.biClrUsed = 0; + bmi.bmiHeader.biClrImportant = 0; + + StretchDIBits(hDC, + 0, 0, surface->width, surface->height, + 0, 0, surface->width, surface->height, + buffer->data, &bmi, 0, SRCCOPY); +} + + +const struct stw_winsys stw_winsys = { + &gdi_softpipe_screen_create, + &gdi_softpipe_context_create, + &gdi_softpipe_flush_frontbuffer +}; diff --git a/src/gallium/winsys/gdi/opengl32.def b/src/gallium/winsys/gdi/opengl32.def deleted file mode 100644 index 54e72f57b1..0000000000 --- a/src/gallium/winsys/gdi/opengl32.def +++ /dev/null @@ -1,859 +0,0 @@ -; DO NOT EDIT - This file generated automatically by mesadef.py script -;DESCRIPTION 'Mesa (OpenGL work-alike) for Win32' -VERSION 6.5 -; -; Module definition file for Mesa (OPENGL32.DLL) -; -; Note: The OpenGL functions use the STDCALL -; function calling convention. Microsoft's -; OPENGL32 uses this convention and so must the -; Mesa OPENGL32 so that the Mesa DLL can be used -; as a drop-in replacement. -; -; The linker exports STDCALL entry points with -; 'decorated' names; e.g., _glBegin@0, where the -; trailing number is the number of bytes of -; parameter data pushed onto the stack. The -; callee is responsible for popping this data -; off the stack, usually via a RETF n instruction. -; -; However, the Microsoft OPENGL32.DLL does not export -; the decorated names, even though the calling convention -; is STDCALL. So, this module definition file is -; needed to force the Mesa OPENGL32.DLL to export the -; symbols in the same manner as the Microsoft DLL. -; Were it not for this problem, this file would not -; be needed (for the gl* functions) since the entry -; points are compiled with dllexport declspec. -; -; However, this file is still needed to export "internal" -; Mesa symbols for the benefit of the OSMESA32.DLL. -; -EXPORTS - glNewList - glEndList - glCallList - glCallLists - glDeleteLists - glGenLists - glListBase - glBegin - glBitmap - glColor3b - glColor3bv - glColor3d - glColor3dv - glColor3f - glColor3fv - glColor3i - glColor3iv - glColor3s - glColor3sv - glColor3ub - glColor3ubv - glColor3ui - glColor3uiv - glColor3us - glColor3usv - glColor4b - glColor4bv - glColor4d - glColor4dv - glColor4f - glColor4fv - glColor4i - glColor4iv - glColor4s - glColor4sv - glColor4ub - glColor4ubv - glColor4ui - glColor4uiv - glColor4us - glColor4usv - glEdgeFlag - glEdgeFlagv - glEnd - glIndexd - glIndexdv - glIndexf - glIndexfv - glIndexi - glIndexiv - glIndexs - glIndexsv - glNormal3b - glNormal3bv - glNormal3d - glNormal3dv - glNormal3f - glNormal3fv - glNormal3i - glNormal3iv - glNormal3s - glNormal3sv - glRasterPos2d - glRasterPos2dv - glRasterPos2f - glRasterPos2fv - glRasterPos2i - glRasterPos2iv - glRasterPos2s - glRasterPos2sv - glRasterPos3d - glRasterPos3dv - glRasterPos3f - glRasterPos3fv - glRasterPos3i - glRasterPos3iv - glRasterPos3s - glRasterPos3sv - glRasterPos4d - glRasterPos4dv - glRasterPos4f - glRasterPos4fv - glRasterPos4i - glRasterPos4iv - glRasterPos4s - glRasterPos4sv - glRectd - glRectdv - glRectf - glRectfv - glRecti - glRectiv - glRects - glRectsv - glTexCoord1d - glTexCoord1dv - glTexCoord1f - glTexCoord1fv - glTexCoord1i - glTexCoord1iv - glTexCoord1s - glTexCoord1sv - glTexCoord2d - glTexCoord2dv - glTexCoord2f - glTexCoord2fv - glTexCoord2i - glTexCoord2iv - glTexCoord2s - glTexCoord2sv - glTexCoord3d - glTexCoord3dv - glTexCoord3f - glTexCoord3fv - glTexCoord3i - glTexCoord3iv - glTexCoord3s - glTexCoord3sv - glTexCoord4d - glTexCoord4dv - glTexCoord4f - glTexCoord4fv - glTexCoord4i - glTexCoord4iv - glTexCoord4s - glTexCoord4sv - glVertex2d - glVertex2dv - glVertex2f - glVertex2fv - glVertex2i - glVertex2iv - glVertex2s - glVertex2sv - glVertex3d - glVertex3dv - glVertex3f - glVertex3fv - glVertex3i - glVertex3iv - glVertex3s - glVertex3sv - glVertex4d - glVertex4dv - glVertex4f - glVertex4fv - glVertex4i - glVertex4iv - glVertex4s - glVertex4sv - glClipPlane - glColorMaterial - glCullFace - glFogf - glFogfv - glFogi - glFogiv - glFrontFace - glHint - glLightf - glLightfv - glLighti - glLightiv - glLightModelf - glLightModelfv - glLightModeli - glLightModeliv - glLineStipple - glLineWidth - glMaterialf - glMaterialfv - glMateriali - glMaterialiv - glPointSize - glPolygonMode - glPolygonStipple - glScissor - glShadeModel - glTexParameterf - glTexParameterfv - glTexParameteri - glTexParameteriv - glTexImage1D - glTexImage2D - glTexEnvf - glTexEnvfv - glTexEnvi - glTexEnviv - glTexGend - glTexGendv - glTexGenf - glTexGenfv - glTexGeni - glTexGeniv - glFeedbackBuffer - glSelectBuffer - glRenderMode - glInitNames - glLoadName - glPassThrough - glPopName - glPushName - glDrawBuffer - glClear - glClearAccum - glClearIndex - glClearColor - glClearStencil - glClearDepth - glStencilMask - glColorMask - glDepthMask - glIndexMask - glAccum - glDisable - glEnable - glFinish - glFlush - glPopAttrib - glPushAttrib - glMap1d - glMap1f - glMap2d - glMap2f - glMapGrid1d - glMapGrid1f - glMapGrid2d - glMapGrid2f - glEvalCoord1d - glEvalCoord1dv - glEvalCoord1f - glEvalCoord1fv - glEvalCoord2d - glEvalCoord2dv - glEvalCoord2f - glEvalCoord2fv - glEvalMesh1 - glEvalPoint1 - glEvalMesh2 - glEvalPoint2 - glAlphaFunc - glBlendFunc - glLogicOp - glStencilFunc - glStencilOp - glDepthFunc - glPixelZoom - glPixelTransferf - glPixelTransferi - glPixelStoref - glPixelStorei - glPixelMapfv - glPixelMapuiv - glPixelMapusv - glReadBuffer - glCopyPixels - glReadPixels - glDrawPixels - glGetBooleanv - glGetClipPlane - glGetDoublev - glGetError - glGetFloatv - glGetIntegerv - glGetLightfv - glGetLightiv - glGetMapdv - glGetMapfv - glGetMapiv - glGetMaterialfv - glGetMaterialiv - glGetPixelMapfv - glGetPixelMapuiv - glGetPixelMapusv - glGetPolygonStipple - glGetString - glGetTexEnvfv - glGetTexEnviv - glGetTexGendv - glGetTexGenfv - glGetTexGeniv - glGetTexImage - glGetTexParameterfv - glGetTexParameteriv - glGetTexLevelParameterfv - glGetTexLevelParameteriv - glIsEnabled - glIsList - glDepthRange - glFrustum - glLoadIdentity - glLoadMatrixf - glLoadMatrixd - glMatrixMode - glMultMatrixf - glMultMatrixd - glOrtho - glPopMatrix - glPushMatrix - glRotated - glRotatef - glScaled - glScalef - glTranslated - glTranslatef - glViewport - glArrayElement - glColorPointer - glDisableClientState - glDrawArrays - glDrawElements - glEdgeFlagPointer - glEnableClientState - glGetPointerv - glIndexPointer - glInterleavedArrays - glNormalPointer - glTexCoordPointer - glVertexPointer - glPolygonOffset - glCopyTexImage1D - glCopyTexImage2D - glCopyTexSubImage1D - glCopyTexSubImage2D - glTexSubImage1D - glTexSubImage2D - glAreTexturesResident - glBindTexture - glDeleteTextures - glGenTextures - glIsTexture - glPrioritizeTextures - glIndexub - glIndexubv - glPopClientAttrib - glPushClientAttrib - glBlendColor - glBlendEquation - glDrawRangeElements - glColorTable - glColorTableParameterfv - glColorTableParameteriv - glCopyColorTable - glGetColorTable - glGetColorTableParameterfv - glGetColorTableParameteriv - glColorSubTable - glCopyColorSubTable - glConvolutionFilter1D - glConvolutionFilter2D - glConvolutionParameterf - glConvolutionParameterfv - glConvolutionParameteri - glConvolutionParameteriv - glCopyConvolutionFilter1D - glCopyConvolutionFilter2D - glGetConvolutionFilter - glGetConvolutionParameterfv - glGetConvolutionParameteriv - glGetSeparableFilter - glSeparableFilter2D - glGetHistogram - glGetHistogramParameterfv - glGetHistogramParameteriv - glGetMinmax - glGetMinmaxParameterfv - glGetMinmaxParameteriv - glHistogram - glMinmax - glResetHistogram - glResetMinmax - glTexImage3D - glTexSubImage3D - glCopyTexSubImage3D - glActiveTextureARB - glClientActiveTextureARB - glMultiTexCoord1dARB - glMultiTexCoord1dvARB - glMultiTexCoord1fARB - glMultiTexCoord1fvARB - glMultiTexCoord1iARB - glMultiTexCoord1ivARB - glMultiTexCoord1sARB - glMultiTexCoord1svARB - glMultiTexCoord2dARB - glMultiTexCoord2dvARB - glMultiTexCoord2fARB - glMultiTexCoord2fvARB - glMultiTexCoord2iARB - glMultiTexCoord2ivARB - glMultiTexCoord2sARB - glMultiTexCoord2svARB - glMultiTexCoord3dARB - glMultiTexCoord3dvARB - glMultiTexCoord3fARB - glMultiTexCoord3fvARB - glMultiTexCoord3iARB - glMultiTexCoord3ivARB - glMultiTexCoord3sARB - glMultiTexCoord3svARB - glMultiTexCoord4dARB - glMultiTexCoord4dvARB - glMultiTexCoord4fARB - glMultiTexCoord4fvARB - glMultiTexCoord4iARB - glMultiTexCoord4ivARB - glMultiTexCoord4sARB - glMultiTexCoord4svARB - glLoadTransposeMatrixfARB - glLoadTransposeMatrixdARB - glMultTransposeMatrixfARB - glMultTransposeMatrixdARB - glSampleCoverageARB - glCompressedTexImage3DARB - glCompressedTexImage2DARB - glCompressedTexImage1DARB - glCompressedTexSubImage3DARB - glCompressedTexSubImage2DARB - glCompressedTexSubImage1DARB - glGetCompressedTexImageARB - glActiveTexture - glClientActiveTexture - glMultiTexCoord1d - glMultiTexCoord1dv - glMultiTexCoord1f - glMultiTexCoord1fv - glMultiTexCoord1i - glMultiTexCoord1iv - glMultiTexCoord1s - glMultiTexCoord1sv - glMultiTexCoord2d - glMultiTexCoord2dv - glMultiTexCoord2f - glMultiTexCoord2fv - glMultiTexCoord2i - glMultiTexCoord2iv - glMultiTexCoord2s - glMultiTexCoord2sv - glMultiTexCoord3d - glMultiTexCoord3dv - glMultiTexCoord3f - glMultiTexCoord3fv - glMultiTexCoord3i - glMultiTexCoord3iv - glMultiTexCoord3s - glMultiTexCoord3sv - glMultiTexCoord4d - glMultiTexCoord4dv - glMultiTexCoord4f - glMultiTexCoord4fv - glMultiTexCoord4i - glMultiTexCoord4iv - glMultiTexCoord4s - glMultiTexCoord4sv - glLoadTransposeMatrixf - glLoadTransposeMatrixd - glMultTransposeMatrixf - glMultTransposeMatrixd - glSampleCoverage - glCompressedTexImage3D - glCompressedTexImage2D - glCompressedTexImage1D - glCompressedTexSubImage3D - glCompressedTexSubImage2D - glCompressedTexSubImage1D - glGetCompressedTexImage - glBlendColorEXT - glPolygonOffsetEXT - glTexImage3DEXT - glTexSubImage3DEXT - glTexSubImage1DEXT - glTexSubImage2DEXT - glCopyTexImage1DEXT - glCopyTexImage2DEXT - glCopyTexSubImage1DEXT - glCopyTexSubImage2DEXT - glCopyTexSubImage3DEXT - glAreTexturesResidentEXT - glBindTextureEXT - glDeleteTexturesEXT - glGenTexturesEXT - glIsTextureEXT - glPrioritizeTexturesEXT - glArrayElementEXT - glColorPointerEXT - glDrawArraysEXT - glEdgeFlagPointerEXT - glGetPointervEXT - glIndexPointerEXT - glNormalPointerEXT - glTexCoordPointerEXT - glVertexPointerEXT - glBlendEquationEXT - glPointParameterfEXT - glPointParameterfvEXT - glPointParameterfARB - glPointParameterfvARB - glColorTableEXT - glGetColorTableEXT - glGetColorTableParameterivEXT - glGetColorTableParameterfvEXT - glLockArraysEXT - glUnlockArraysEXT - glDrawRangeElementsEXT - glSecondaryColor3bEXT - glSecondaryColor3bvEXT - glSecondaryColor3dEXT - glSecondaryColor3dvEXT - glSecondaryColor3fEXT - glSecondaryColor3fvEXT - glSecondaryColor3iEXT - glSecondaryColor3ivEXT - glSecondaryColor3sEXT - glSecondaryColor3svEXT - glSecondaryColor3ubEXT - glSecondaryColor3ubvEXT - glSecondaryColor3uiEXT - glSecondaryColor3uivEXT - glSecondaryColor3usEXT - glSecondaryColor3usvEXT - glSecondaryColorPointerEXT - glMultiDrawArraysEXT - glMultiDrawElementsEXT - glFogCoordfEXT - glFogCoordfvEXT - glFogCoorddEXT - glFogCoorddvEXT - glFogCoordPointerEXT - glBlendFuncSeparateEXT - glFlushVertexArrayRangeNV - glVertexArrayRangeNV - glCombinerParameterfvNV - glCombinerParameterfNV - glCombinerParameterivNV - glCombinerParameteriNV - glCombinerInputNV - glCombinerOutputNV - glFinalCombinerInputNV - glGetCombinerInputParameterfvNV - glGetCombinerInputParameterivNV - glGetCombinerOutputParameterfvNV - glGetCombinerOutputParameterivNV - glGetFinalCombinerInputParameterfvNV - glGetFinalCombinerInputParameterivNV - glResizeBuffersMESA - glWindowPos2dMESA - glWindowPos2dvMESA - glWindowPos2fMESA - glWindowPos2fvMESA - glWindowPos2iMESA - glWindowPos2ivMESA - glWindowPos2sMESA - glWindowPos2svMESA - glWindowPos3dMESA - glWindowPos3dvMESA - glWindowPos3fMESA - glWindowPos3fvMESA - glWindowPos3iMESA - glWindowPos3ivMESA - glWindowPos3sMESA - glWindowPos3svMESA - glWindowPos4dMESA - glWindowPos4dvMESA - glWindowPos4fMESA - glWindowPos4fvMESA - glWindowPos4iMESA - glWindowPos4ivMESA - glWindowPos4sMESA - glWindowPos4svMESA - glWindowPos2dARB - glWindowPos2fARB - glWindowPos2iARB - glWindowPos2sARB - glWindowPos2dvARB - glWindowPos2fvARB - glWindowPos2ivARB - glWindowPos2svARB - glWindowPos3dARB - glWindowPos3fARB - glWindowPos3iARB - glWindowPos3sARB - glWindowPos3dvARB - glWindowPos3fvARB - glWindowPos3ivARB - glWindowPos3svARB - glAreProgramsResidentNV - glBindProgramNV - glDeleteProgramsNV - glExecuteProgramNV - glGenProgramsNV - glGetProgramParameterdvNV - glGetProgramParameterfvNV - glGetProgramivNV - glGetProgramStringNV - glGetTrackMatrixivNV - glGetVertexAttribdvNV - glGetVertexAttribfvNV - glGetVertexAttribivNV - glGetVertexAttribPointervNV - glIsProgramNV - glLoadProgramNV - glProgramParameter4dNV - glProgramParameter4dvNV - glProgramParameter4fNV - glProgramParameter4fvNV - glProgramParameters4dvNV - glProgramParameters4fvNV - glRequestResidentProgramsNV - glTrackMatrixNV - glVertexAttribPointerNV - glVertexAttrib1dNV - glVertexAttrib1dvNV - glVertexAttrib1fNV - glVertexAttrib1fvNV - glVertexAttrib1sNV - glVertexAttrib1svNV - glVertexAttrib2dNV - glVertexAttrib2dvNV - glVertexAttrib2fNV - glVertexAttrib2fvNV - glVertexAttrib2sNV - glVertexAttrib2svNV - glVertexAttrib3dNV - glVertexAttrib3dvNV - glVertexAttrib3fNV - glVertexAttrib3fvNV - glVertexAttrib3sNV - glVertexAttrib3svNV - glVertexAttrib4dNV - glVertexAttrib4dvNV - glVertexAttrib4fNV - glVertexAttrib4fvNV - glVertexAttrib4sNV - glVertexAttrib4svNV - glVertexAttrib4ubNV - glVertexAttrib4ubvNV - glVertexAttribs1dvNV - glVertexAttribs1fvNV - glVertexAttribs1svNV - glVertexAttribs2dvNV - glVertexAttribs2fvNV - glVertexAttribs2svNV - glVertexAttribs3dvNV - glVertexAttribs3fvNV - glVertexAttribs3svNV - glVertexAttribs4dvNV - glVertexAttribs4fvNV - glVertexAttribs4svNV - glVertexAttribs4ubvNV - glPointParameteriNV - glPointParameterivNV - glFogCoordf - glFogCoordfv - glFogCoordd - glFogCoorddv - glFogCoordPointer - glMultiDrawArrays - glMultiDrawElements - glPointParameterf - glPointParameterfv - glPointParameteri - glPointParameteriv - glSecondaryColor3b - glSecondaryColor3bv - glSecondaryColor3d - glSecondaryColor3dv - glSecondaryColor3f - glSecondaryColor3fv - glSecondaryColor3i - glSecondaryColor3iv - glSecondaryColor3s - glSecondaryColor3sv - glSecondaryColor3ub - glSecondaryColor3ubv - glSecondaryColor3ui - glSecondaryColor3uiv - glSecondaryColor3us - glSecondaryColor3usv - glSecondaryColorPointer - glWindowPos2d - glWindowPos2dv - glWindowPos2f - glWindowPos2fv - glWindowPos2i - glWindowPos2iv - glWindowPos2s - glWindowPos2sv - glWindowPos3d - glWindowPos3dv - glWindowPos3f - glWindowPos3fv - glWindowPos3i - glWindowPos3iv - glWindowPos3s - glWindowPos3sv - glVertexAttrib1sARB - glVertexAttrib1fARB - glVertexAttrib1dARB - glVertexAttrib2sARB - glVertexAttrib2fARB - glVertexAttrib2dARB - glVertexAttrib3sARB - glVertexAttrib3fARB - glVertexAttrib3dARB - glVertexAttrib4sARB - glVertexAttrib4fARB - glVertexAttrib4dARB - glVertexAttrib4NubARB - glVertexAttrib1svARB - glVertexAttrib1fvARB - glVertexAttrib1dvARB - glVertexAttrib2svARB - glVertexAttrib2fvARB - glVertexAttrib2dvARB - glVertexAttrib3svARB - glVertexAttrib3fvARB - glVertexAttrib3dvARB - glVertexAttrib4bvARB - glVertexAttrib4svARB - glVertexAttrib4ivARB - glVertexAttrib4ubvARB - glVertexAttrib4usvARB - glVertexAttrib4uivARB - glVertexAttrib4fvARB - glVertexAttrib4dvARB - glVertexAttrib4NbvARB - glVertexAttrib4NsvARB - glVertexAttrib4NivARB - glVertexAttrib4NubvARB - glVertexAttrib4NusvARB - glVertexAttrib4NuivARB - glVertexAttribPointerARB - glEnableVertexAttribArrayARB - glDisableVertexAttribArrayARB - glProgramStringARB - glBindProgramARB - glDeleteProgramsARB - glGenProgramsARB - glIsProgramARB - glProgramEnvParameter4dARB - glProgramEnvParameter4dvARB - glProgramEnvParameter4fARB - glProgramEnvParameter4fvARB - glProgramLocalParameter4dARB - glProgramLocalParameter4dvARB - glProgramLocalParameter4fARB - glProgramLocalParameter4fvARB - glGetProgramEnvParameterdvARB - glGetProgramEnvParameterfvARB - glGetProgramLocalParameterdvARB - glGetProgramLocalParameterfvARB - glGetProgramivARB - glGetProgramStringARB - glGetVertexAttribdvARB - glGetVertexAttribfvARB - glGetVertexAttribivARB - glGetVertexAttribPointervARB - glProgramNamedParameter4fNV - glProgramNamedParameter4dNV - glProgramNamedParameter4fvNV - glProgramNamedParameter4dvNV - glGetProgramNamedParameterfvNV - glGetProgramNamedParameterdvNV - glBindBufferARB - glBufferDataARB - glBufferSubDataARB - glDeleteBuffersARB - glGenBuffersARB - glGetBufferParameterivARB - glGetBufferPointervARB - glGetBufferSubDataARB - glIsBufferARB - glMapBufferARB - glUnmapBufferARB - glGenQueriesARB - glDeleteQueriesARB - glIsQueryARB - glBeginQueryARB - glEndQueryARB - glGetQueryivARB - glGetQueryObjectivARB - glGetQueryObjectuivARB - glBindBuffer - glBufferData - glBufferSubData - glDeleteBuffers - glGenBuffers - glGetBufferParameteriv - glGetBufferPointerv - glGetBufferSubData - glIsBuffer - glMapBuffer - glUnmapBuffer - glGenQueries - glDeleteQueries - glIsQuery - glBeginQuery - glEndQuery - glGetQueryiv - glGetQueryObjectiv - glGetQueryObjectuiv -; -; WGL API - wglChoosePixelFormat - wglCopyContext - wglCreateContext - wglCreateLayerContext - wglDeleteContext - wglDescribeLayerPlane - wglDescribePixelFormat - wglGetCurrentContext - wglGetCurrentDC - wglGetLayerPaletteEntries - wglGetPixelFormat - wglGetProcAddress - wglMakeCurrent - wglRealizeLayerPalette - wglSetLayerPaletteEntries - wglSetPixelFormat - wglShareLists - wglSwapBuffers - wglSwapLayerBuffers - wglUseFontBitmapsA - wglUseFontBitmapsW - wglUseFontOutlinesA - wglUseFontOutlinesW - wglGetExtensionsStringARB diff --git a/src/gallium/winsys/gdi/wgl.c b/src/gallium/winsys/gdi/wgl.c deleted file mode 100644 index 3ce470480d..0000000000 --- a/src/gallium/winsys/gdi/wgl.c +++ /dev/null @@ -1,701 +0,0 @@ -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* - * File name : wgl.c - * WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru - * Some things originated from the 3Dfx WGL functions - */ - -/* - * This file contains the implementation of the wgl* functions for - * Mesa on Windows. Since these functions are provided by Windows in - * GDI/OpenGL, we must supply our versions that work with Mesa here. - */ - - -/* We're essentially building part of GDI here, so define this so that - * we get the right export linkage. */ -#ifdef __MINGW32__ - -#include -#include -#include -#include - -# if defined(BUILD_GL32) -# define WINGDIAPI __declspec(dllexport) -# else -# define __W32API_USE_DLLIMPORT__ -# endif - -#include -#include "GL/mesa_wgl.h" -#include - -#else - -#define _GDI32_ -#include - -#endif - -#include "glapi.h" -#include "GL/wmesa.h" /* protos for wmesa* functions */ - -/* - * Pixel Format Descriptors - */ - -/* Extend the PFD to include DB flag */ -struct __pixelformat__ -{ - PIXELFORMATDESCRIPTOR pfd; - GLboolean doubleBuffered; -}; - -/* These are the PFD's supported by this driver. */ -struct __pixelformat__ pfd[] = -{ - /* Double Buffer, alpha */ - { - { - sizeof(PIXELFORMATDESCRIPTOR), 1, - PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| - PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, - PFD_TYPE_RGBA, - 24, - 8, 0, - 8, 8, - 8, 16, - 8, 24, - 0, 0, 0, 0, 0, - 16, 8, - 0, 0, 0, - 0, 0, 0 - }, - GL_TRUE - }, - /* Single Buffer, alpha */ - { - { - sizeof(PIXELFORMATDESCRIPTOR), 1, - PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| - PFD_GENERIC_FORMAT, - PFD_TYPE_RGBA, - 24, - 8, 0, - 8, 8, - 8, 16, - 8, 24, - 0, 0, 0, 0, 0, - 16, 8, - 0, 0, 0, - 0, 0, 0 - }, - GL_FALSE - }, - /* Double Buffer, no alpha */ - { - { - sizeof(PIXELFORMATDESCRIPTOR), 1, - PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| - PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, - PFD_TYPE_RGBA, - 24, - 8, 0, - 8, 8, - 8, 16, - 0, 0, - 0, 0, 0, 0, 0, - 16, 8, - 0, 0, 0, - 0, 0, 0 - }, - GL_TRUE - }, - /* Single Buffer, no alpha */ - { - { - sizeof(PIXELFORMATDESCRIPTOR), 1, - PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| - PFD_GENERIC_FORMAT, - PFD_TYPE_RGBA, - 24, - 8, 0, - 8, 8, - 8, 16, - 0, 0, - 0, 0, 0, 0, 0, - 16, 8, - 0, 0, 0, - 0, 0, 0 - }, - GL_FALSE - }, -}; - -int npfd = sizeof(pfd) / sizeof(pfd[0]); - - -/* - * Contexts - */ - -typedef struct { - WMesaContext ctx; -} MesaWglCtx; - -#define MESAWGL_CTX_MAX_COUNT 20 - -static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT]; - -static unsigned ctx_count = 0; -static int ctx_current = -1; -static unsigned curPFD = 0; - -static HDC CurrentHDC = 0; - - -WINGDIAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc) -{ - int i = 0; - if (!ctx_count) { - for(i=0;inSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1) - { - SetLastError(0); - return(0); - } - for(i = 0; i < npfd;i++) - { - delta = 0; - if( - (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) && - !(pfd[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW)) - continue; - if( - (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) && - !(pfd[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP)) - continue; - if( - (ppfd->dwFlags & PFD_SUPPORT_GDI) && - !(pfd[i].pfd.dwFlags & PFD_SUPPORT_GDI)) - continue; - if( - (ppfd->dwFlags & PFD_SUPPORT_OPENGL) && - !(pfd[i].pfd.dwFlags & PFD_SUPPORT_OPENGL)) - continue; - if( - !(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) && - ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != - (pfd[i].pfd.dwFlags & PFD_DOUBLEBUFFER))) - continue; - if( - !(ppfd->dwFlags & PFD_STEREO_DONTCARE) && - ((ppfd->dwFlags & PFD_STEREO) != - (pfd[i].pfd.dwFlags & PFD_STEREO))) - continue; - if(ppfd->iPixelType != pfd[i].pfd.iPixelType) - delta++; - if(ppfd->cAlphaBits != pfd[i].pfd.cAlphaBits) - delta++; - if(delta < bestdelta) - { - best = i + 1; - bestdelta = delta; - if(bestdelta == 0) - break; - } - } - if(best == -1) - { - SetLastError(0); - return(0); - } - return(best); -} - -WINGDIAPI int GLAPIENTRY wglDescribePixelFormat(HDC hdc, - int iPixelFormat, - UINT nBytes, - LPPIXELFORMATDESCRIPTOR ppfd) -{ - (void) hdc; - - if(ppfd == NULL) - return(npfd); - if(iPixelFormat < 1 || iPixelFormat > npfd || - nBytes != sizeof(PIXELFORMATDESCRIPTOR)) - { - SetLastError(0); - return(0); - } - *ppfd = pfd[iPixelFormat - 1].pfd; - return(npfd); -} - -WINGDIAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc) -{ - PROC p = (PROC) _glapi_get_proc_address((const char *) lpszProc); - if (p) - return p; - - SetLastError(0); - return(NULL); -} - -WINGDIAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc) -{ - (void) hdc; - if(curPFD == 0) { - SetLastError(0); - return(0); - } - return(curPFD); -} - -WINGDIAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat, - const PIXELFORMATDESCRIPTOR *ppfd) -{ - (void) hdc; - - if(iPixelFormat < 1 || iPixelFormat > npfd || - ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) { - SetLastError(0); - return(FALSE); - } - curPFD = iPixelFormat; - return(TRUE); -} - -WINGDIAPI BOOL GLAPIENTRY wglSwapBuffers(HDC hdc) -{ - WMesaSwapBuffers(hdc); - return TRUE; -} - -static FIXED FixedFromDouble(double d) -{ - long l = (long) (d * 65536L); - return *(FIXED *) (void *) &l; -} - - -/* -** This is cribbed from FX/fxwgl.c, and seems to implement support -** for bitmap fonts where the wglUseFontBitmapsA() code implements -** support for outline fonts. In combination they hopefully give -** fairly generic support for fonts. -*/ -static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar, - DWORD numChars, DWORD listBase) -{ -#define VERIFY(a) a - - TEXTMETRIC metric; - BITMAPINFO *dibInfo; - HDC bitDevice; - COLORREF tempColor; - int i; - - VERIFY(GetTextMetrics(fontDevice, &metric)); - - dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1); - dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - dibInfo->bmiHeader.biPlanes = 1; - dibInfo->bmiHeader.biBitCount = 1; - dibInfo->bmiHeader.biCompression = BI_RGB; - - bitDevice = CreateCompatibleDC(fontDevice); - - /* Swap fore and back colors so the bitmap has the right polarity */ - tempColor = GetBkColor(bitDevice); - SetBkColor(bitDevice, GetTextColor(bitDevice)); - SetTextColor(bitDevice, tempColor); - - /* Place chars based on base line */ - VERIFY(SetTextAlign(bitDevice, TA_BASELINE) != GDI_ERROR ? 1 : 0); - - for(i = 0; i < (int)numChars; i++) { - SIZE size; - char curChar; - int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res; - HBITMAP bitObject; - HGDIOBJ origBmap; - unsigned char *bmap; - - curChar = (char)(i + firstChar); - - /* Find how high/wide this character is */ - VERIFY(GetTextExtentPoint32(bitDevice, (LPCWSTR)&curChar, 1, &size)); - - /* Create the output bitmap */ - charWidth = size.cx; - charHeight = size.cy; - /* Round up to the next multiple of 32 bits */ - bmapWidth = ((charWidth + 31) / 32) * 32; - bmapHeight = charHeight; - bitObject = CreateCompatibleBitmap(bitDevice, - bmapWidth, - bmapHeight); - /* VERIFY(bitObject); */ - - /* Assign the output bitmap to the device */ - origBmap = SelectObject(bitDevice, bitObject); - (void) VERIFY(origBmap); - - VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) ); - - /* Use our source font on the device */ - VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT))); - - /* Draw the character */ - VERIFY(TextOut(bitDevice, 0, metric.tmAscent, (LPCWSTR)&curChar, 1)); - - /* Unselect our bmap object */ - VERIFY(SelectObject(bitDevice, origBmap)); - - /* Convert the display dependant representation to a 1 bit deep DIB */ - numBytes = (bmapWidth * bmapHeight) / 8; - bmap = (unsigned char *)malloc(numBytes); - dibInfo->bmiHeader.biWidth = bmapWidth; - dibInfo->bmiHeader.biHeight = bmapHeight; - res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap, - dibInfo, - DIB_RGB_COLORS); - /* VERIFY(res); */ - - /* Create the GL object */ - glNewList(i + listBase, GL_COMPILE); - glBitmap(bmapWidth, bmapHeight, 0.0, (GLfloat)metric.tmDescent, - (GLfloat)charWidth, 0.0, - bmap); - glEndList(); - /* CheckGL(); */ - - /* Destroy the bmap object */ - DeleteObject(bitObject); - - /* Deallocate the bitmap data */ - free(bmap); - } - - /* Destroy the DC */ - VERIFY(DeleteDC(bitDevice)); - - free(dibInfo); - - return TRUE; -#undef VERIFY -} - -WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsA(HDC hdc, DWORD first, - DWORD count, DWORD listBase) -{ - int i; - GLuint font_list; - DWORD size; - GLYPHMETRICS gm; - HANDLE hBits; - LPSTR lpBits; - MAT2 mat; - int success = TRUE; - - if (count == 0) - return FALSE; - - font_list = listBase; - - mat.eM11 = FixedFromDouble(1); - mat.eM12 = FixedFromDouble(0); - mat.eM21 = FixedFromDouble(0); - mat.eM22 = FixedFromDouble(-1); - - memset(&gm,0,sizeof(gm)); - - /* - ** If we can't get the glyph outline, it may be because this is a fixed - ** font. Try processing it that way. - */ - if( GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat) - == GDI_ERROR ) { - return wglUseFontBitmaps_FX( hdc, first, count, listBase ); - } - - /* - ** Otherwise process all desired characters. - */ - for (i = 0; i < (int)count; i++) { - DWORD err; - - glNewList( font_list+i, GL_COMPILE ); - - /* allocate space for the bitmap/outline */ - size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, - &gm, 0, NULL, &mat); - if (size == GDI_ERROR) { - glEndList( ); - err = GetLastError(); - success = FALSE; - continue; - } - - hBits = GlobalAlloc(GHND, size+1); - lpBits = GlobalLock(hBits); - - err = - GetGlyphOutline(hdc, /* handle to device context */ - first + i, /* character to query */ - GGO_BITMAP, /* format of data to return */ - &gm, /* ptr to structure for metrics*/ - size, /* size of buffer for data */ - lpBits, /* pointer to buffer for data */ - &mat /* pointer to transformation */ - /* matrix structure */ - ); - - if (err == GDI_ERROR) { - GlobalUnlock(hBits); - GlobalFree(hBits); - - glEndList( ); - err = GetLastError(); - success = FALSE; - continue; - } - - glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY, - (GLfloat)-gm.gmptGlyphOrigin.x, - (GLfloat)gm.gmptGlyphOrigin.y, - (GLfloat)gm.gmCellIncX, - (GLfloat)gm.gmCellIncY, - (const GLubyte * )lpBits); - - GlobalUnlock(hBits); - GlobalFree(hBits); - - glEndList( ); - } - - return success; -} - - - -/* NOT IMPLEMENTED YET */ -WINGDIAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc, - HGLRC hglrcDst, - UINT mask) -{ - (void) hglrcSrc; (void) hglrcDst; (void) mask; - return(FALSE); -} - -WINGDIAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc, - int iLayerPlane) -{ - (void) hdc; (void) iLayerPlane; - SetLastError(0); - return(NULL); -} - -WINGDIAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1, - HGLRC hglrc2) -{ - (void) hglrc1; (void) hglrc2; - return(TRUE); -} - - -WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc, - DWORD first, - DWORD count, - DWORD listBase) -{ - (void) hdc; (void) first; (void) count; (void) listBase; - return FALSE; -} - -WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc, - DWORD first, - DWORD count, - DWORD listBase, - FLOAT deviation, - FLOAT extrusion, - int format, - LPGLYPHMETRICSFLOAT lpgmf) -{ - (void) hdc; (void) first; (void) count; - (void) listBase; (void) deviation; (void) extrusion; (void) format; - (void) lpgmf; - SetLastError(0); - return(FALSE); -} - -WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc, - DWORD first, - DWORD count, - DWORD listBase, - FLOAT deviation, - FLOAT extrusion, - int format, - LPGLYPHMETRICSFLOAT lpgmf) -{ - (void) hdc; (void) first; (void) count; - (void) listBase; (void) deviation; (void) extrusion; (void) format; - (void) lpgmf; - SetLastError(0); - return(FALSE); -} - -WINGDIAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc, - int iPixelFormat, - int iLayerPlane, - UINT nBytes, - LPLAYERPLANEDESCRIPTOR plpd) -{ - (void) hdc; (void) iPixelFormat; (void) iLayerPlane; - (void) nBytes; (void) plpd; - SetLastError(0); - return(FALSE); -} - -WINGDIAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc, - int iLayerPlane, - int iStart, - int cEntries, - CONST COLORREF *pcr) -{ - (void) hdc; (void) iLayerPlane; (void) iStart; - (void) cEntries; (void) pcr; - SetLastError(0); - return(0); -} - -WINGDIAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc, - int iLayerPlane, - int iStart, - int cEntries, - COLORREF *pcr) -{ - (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr; - SetLastError(0); - return(0); -} - -WINGDIAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc, - int iLayerPlane, - BOOL bRealize) -{ - (void) hdc; (void) iLayerPlane; (void) bRealize; - SetLastError(0); - return(FALSE); -} - -WINGDIAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc, - UINT fuPlanes) -{ - (void) hdc; (void) fuPlanes; - SetLastError(0); - return(FALSE); -} - -WINGDIAPI const char * GLAPIENTRY wglGetExtensionsStringARB(HDC hdc) -{ - return "WGL_ARB_extensions_string"; -} diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c deleted file mode 100644 index ed3dd2b927..0000000000 --- a/src/gallium/winsys/gdi/wmesa.c +++ /dev/null @@ -1,823 +0,0 @@ -/* - * Windows (Win32/Win64) device driver for Mesa - * - */ - -#include "mtypes.h" -#include -#include "wmesadef.h" - -#undef Elements - -#include "pipe/p_winsys.h" -#include "pipe/p_format.h" -#include "pipe/p_context.h" -#include "pipe/p_inlines.h" -#include "util/u_memory.h" -#include "softpipe/sp_winsys.h" -#include "glapi/glapi.h" -#include "colors.h" - -extern GLvisual * -_mesa_create_visual( GLboolean rgbFlag, - GLboolean dbFlag, - GLboolean stereoFlag, - GLint redBits, - GLint greenBits, - GLint blueBits, - GLint alphaBits, - GLint indexBits, - GLint depthBits, - GLint stencilBits, - GLint accumRedBits, - GLint accumGreenBits, - GLint accumBlueBits, - GLint accumAlphaBits, - GLint numSamples ); - -/* linked list of our Framebuffers (windows) */ -WMesaFramebuffer FirstFramebuffer = NULL; - -struct wmesa_pipe_winsys -{ - struct pipe_winsys base; -}; - -/** - * Choose the pixel format for the given visual. - * This will tell the gallium driver how to pack pixel data into - * drawing surfaces. - */ -static GLuint -choose_pixel_format(GLvisual *v) -{ -#if 1 - return PIPE_FORMAT_A8R8G8B8_UNORM; -#else - if ( GET_REDMASK(v) == 0x0000ff - && GET_GREENMASK(v) == 0x00ff00 - && GET_BLUEMASK(v) == 0xff0000 - && v->BitsPerPixel == 32) { - if (CHECK_BYTE_ORDER(v)) { - /* no byteswapping needed */ - return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */; - } - else { - return PIPE_FORMAT_R8G8B8A8_UNORM; - } - } - else if ( GET_REDMASK(v) == 0xff0000 - && GET_GREENMASK(v) == 0x00ff00 - && GET_BLUEMASK(v) == 0x0000ff - && v->BitsPerPixel == 32) { - if (CHECK_BYTE_ORDER(v)) { - /* no byteswapping needed */ - return PIPE_FORMAT_A8R8G8B8_UNORM; - } - else { - return PIPE_FORMAT_B8G8R8A8_UNORM; - } - } - else if ( GET_REDMASK(v) == 0xf800 - && GET_GREENMASK(v) == 0x07e0 - && GET_BLUEMASK(v) == 0x001f - && CHECK_BYTE_ORDER(v) - && v->BitsPerPixel == 16) { - /* 5-6-5 RGB */ - return PIPE_FORMAT_R5G6B5_UNORM; - } - -printf("BITS %d\n",v->BitsPerPixel); - assert(0); - return 0; -#endif -} - -/* - * Determine the pixel format based on the pixel size. - */ -static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC) -{ - /* Only 16 and 32 bit targets are supported now */ - assert(pwfb->cColorBits == 0 || - pwfb->cColorBits == 16 || - pwfb->cColorBits == 32); - - switch(pwfb->cColorBits){ - case 8: - pwfb->pixelformat = PF_INDEX8; - break; - case 16: - pwfb->pixelformat = PF_5R6G5B; - break; - case 32: - pwfb->pixelformat = PF_8R8G8B; - break; - default: - pwfb->pixelformat = PF_BADFORMAT; - } -} - -/** - * Create a new WMesaFramebuffer object which will correspond to the - * given HDC (Window handle). - */ -WMesaFramebuffer -wmesa_new_framebuffer(HDC hdc, GLvisual *visual, GLuint width, GLuint height) -{ - WMesaFramebuffer pwfb - = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer)); - if (pwfb) { - enum pipe_format colorFormat, depthFormat, stencilFormat; - - /* determine PIPE_FORMATs for buffers */ - colorFormat = choose_pixel_format(visual); - - if (visual->depthBits == 0) - depthFormat = PIPE_FORMAT_NONE; - else if (visual->depthBits <= 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (visual->depthBits <= 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_Z32_UNORM; - - if (visual->stencilBits == 8) { - if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) - stencilFormat = depthFormat; - else - stencilFormat = PIPE_FORMAT_S8_UNORM; - } - else { - stencilFormat = PIPE_FORMAT_NONE; - } - - pwfb->stfb = st_create_framebuffer(visual, - colorFormat, depthFormat, stencilFormat, - width, height, - (void *) pwfb); - - pwfb->cColorBits = GetDeviceCaps(hdc, BITSPIXEL); - - pwfb->hDC = hdc; - /* insert at head of list */ - pwfb->next = FirstFramebuffer; - FirstFramebuffer = pwfb; - } - return pwfb; -} - -/** - * Given an hdc, free the corresponding WMesaFramebuffer - */ -void -wmesa_free_framebuffer(HDC hdc) -{ - WMesaFramebuffer pwfb, prev; - for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { - if (pwfb->hDC == hdc) - break; - prev = pwfb; - } - if (pwfb) { - if (pwfb == FirstFramebuffer) - FirstFramebuffer = pwfb->next; - else - prev->next = pwfb->next; - free(pwfb); - } -} - -/** - * Given an hdc, return the corresponding WMesaFramebuffer - */ -WMesaFramebuffer -wmesa_lookup_framebuffer(HDC hdc) -{ - WMesaFramebuffer pwfb; - for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { - if (pwfb->hDC == hdc) - return pwfb; - } - return NULL; -} - - -/** - * Given a GLframebuffer, return the corresponding WMesaFramebuffer. - */ -static WMesaFramebuffer wmesa_framebuffer(GLframebuffer *fb) -{ - return (WMesaFramebuffer) fb; -} - - -/** - * Given a GLcontext, return the corresponding WMesaContext. - */ -static WMesaContext wmesa_context(const GLcontext *ctx) -{ - return (WMesaContext) ctx; -} - -/** - * Find the width and height of the window named by hdc. - */ -static void -get_window_size(HDC hdc, GLuint *width, GLuint *height) -{ - if (WindowFromDC(hdc)) { - RECT rect; - GetClientRect(WindowFromDC(hdc), &rect); - *width = rect.right - rect.left; - *height = rect.bottom - rect.top; - } - else { /* Memory context */ - /* From contributed code - use the size of the desktop - * for the size of a memory context (?) */ - *width = GetDeviceCaps(hdc, HORZRES); - *height = GetDeviceCaps(hdc, VERTRES); - } -} - -/** - * Low-level OS/window system memory buffer - */ -struct wm_buffer -{ - struct pipe_buffer base; - boolean userBuffer; /** Is this a user-space buffer? */ - void *data; - void *mapped; -}; - -struct wmesa_surface -{ - struct pipe_surface surface; - - int no_swap; -}; - - -/** Cast wrapper */ -static INLINE struct wmesa_surface * -wmesa_surface(struct pipe_surface *ps) -{ -// assert(0); - return (struct wmesa_surface *) ps; -} - -/** - * Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque - * buffer pointer... - */ -static INLINE struct wm_buffer * -wm_buffer( struct pipe_buffer *buf ) -{ - return (struct wm_buffer *)buf; -} - - - -/* Most callbacks map direcly onto dri_bufmgr operations: - */ -static void * -wm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, - unsigned flags) -{ - struct wm_buffer *wm_buf = wm_buffer(buf); - wm_buf->mapped = wm_buf->data; - return wm_buf->mapped; -} - -static void -wm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) -{ - struct wm_buffer *wm_buf = wm_buffer(buf); - wm_buf->mapped = NULL; -} - -static void -wm_buffer_destroy(struct pipe_winsys *pws, - struct pipe_buffer *buf) -{ - struct wm_buffer *oldBuf = wm_buffer(buf); - - if (oldBuf->data) { - { - if (!oldBuf->userBuffer) { - align_free(oldBuf->data); - } - } - - oldBuf->data = NULL; - } - - free(oldBuf); -} - - -static void -wm_flush_frontbuffer(struct pipe_winsys *pws, - struct pipe_surface *surf, - void *context_private) -{ - WMesaContext pwc = context_private; - WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(pwc->hDC); - struct wm_buffer *wm_buf; - BITMAPINFO bmi, *pbmi; - - wm_buf = wm_buffer(surf->buffer); - - pbmi = &bmi; - memset(pbmi, 0, sizeof(BITMAPINFO)); - pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pbmi->bmiHeader.biWidth = pwfb->stfb->Base.Width; - pbmi->bmiHeader.biHeight= -((long)pwfb->stfb->Base.Height); - pbmi->bmiHeader.biPlanes = 1; - pbmi->bmiHeader.biBitCount = pwfb->cColorBits; - pbmi->bmiHeader.biCompression = BI_RGB; - pbmi->bmiHeader.biSizeImage = 0; - pbmi->bmiHeader.biXPelsPerMeter = 0; - pbmi->bmiHeader.biYPelsPerMeter = 0; - pbmi->bmiHeader.biClrUsed = 0; - pbmi->bmiHeader.biClrImportant = 0; - - StretchDIBits(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, wm_buf->data, pbmi, 0, SRCCOPY); -} - - - -static const char * -wm_get_name(struct pipe_winsys *pws) -{ - return "gdi"; -} - -static struct pipe_buffer * -wm_buffer_create(struct pipe_winsys *pws, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct wm_buffer *buffer = CALLOC_STRUCT(wm_buffer); - - buffer->base.refcount = 1; - buffer->base.alignment = alignment; - buffer->base.usage = usage; - buffer->base.size = size; - - if (buffer->data == NULL) { - /* align to 16-byte multiple for Cell */ - buffer->data = align_malloc(size, max(alignment, 16)); - } - - return &buffer->base; -} - - -/** - * Create buffer which wraps user-space data. - */ -static struct pipe_buffer * -wm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) -{ - struct wm_buffer *buffer = CALLOC_STRUCT(wm_buffer); - buffer->base.refcount = 1; - buffer->base.size = bytes; - buffer->userBuffer = TRUE; - buffer->data = ptr; - - return &buffer->base; -} - - - -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - -static int -wm_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, - unsigned width, unsigned height, - enum pipe_format format, - unsigned flags, - unsigned tex_usage) -{ - const unsigned alignment = 64; - - surf->width = width; - surf->height = height; - surf->format = format; - pf_get_block(format, &surf->block); - surf->nblocksx = pf_get_nblocksx(&surf->block, width); - surf->nblocksy = pf_get_nblocksy(&surf->block, height); - surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->nblocksy * surf->stride); - if(!surf->buffer) - return -1; - - return 0; -} - - -/** - * Called via winsys->surface_alloc() to create new surfaces. - */ -static struct pipe_surface * -wm_surface_alloc(struct pipe_winsys *ws) -{ - struct wmesa_surface *wms = CALLOC_STRUCT(wmesa_surface); - static boolean no_swap = 0; - static boolean firsttime = 1; - - if (firsttime) { - no_swap = getenv("SP_NO_RAST") != NULL; - firsttime = 0; - } - - assert(ws); - - wms->surface.refcount = 1; - wms->surface.winsys = ws; - - wms->no_swap = no_swap; - - return &wms->surface; -} - -static void -wm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - winsys_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; -} - - -/* - * Fence functions - basically nothing to do, as we don't create any actual - * fence objects. - */ - -static void -wm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence) -{ -} - - -static int -wm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - -static int -wm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - - -struct pipe_winsys * -wmesa_get_pipe_winsys(GLvisual *visual) -{ - static struct wmesa_pipe_winsys *ws = NULL; - - if (!ws) { - ws = CALLOC_STRUCT(wmesa_pipe_winsys); - - /* Fill in this struct with callbacks that pipe will need to - * communicate with the window system, buffer manager, etc. - */ - ws->base.buffer_create = wm_buffer_create; - ws->base.user_buffer_create = wm_user_buffer_create; - ws->base.buffer_map = wm_buffer_map; - ws->base.buffer_unmap = wm_buffer_unmap; - ws->base.buffer_destroy = wm_buffer_destroy; - - ws->base.surface_alloc = wm_surface_alloc; - ws->base.surface_alloc_storage = wm_surface_alloc_storage; - ws->base.surface_release = wm_surface_release; - - ws->base.fence_reference = wm_fence_reference; - ws->base.fence_signalled = wm_fence_signalled; - ws->base.fence_finish = wm_fence_finish; - - ws->base.flush_frontbuffer = wm_flush_frontbuffer; - ws->base.get_name = wm_get_name; - } - - return &ws->base; -} - - - -/**********************************************************************/ -/***** WMESA Functions *****/ -/**********************************************************************/ - -WMesaContext WMesaCreateContext(HDC hDC, - HPALETTE* Pal, - GLboolean rgb_flag, - GLboolean db_flag, - GLboolean alpha_flag) -{ - WMesaContext c; - struct pipe_winsys *pws; - struct pipe_context *pipe; - struct pipe_screen *screen; - GLint red_bits, green_bits, blue_bits, alpha_bits; - GLvisual *visual; - - (void) Pal; - - /* Indexed mode not supported */ - if (!rgb_flag) - return NULL; - - /* Allocate wmesa context */ - c = CALLOC_STRUCT(wmesa_context); - if (!c) - return NULL; - - c->hDC = hDC; - - /* Get data for visual */ - /* Dealing with this is actually a bit of overkill because Mesa will end - * up treating all color component size requests less than 8 by using - * a single byte per channel. In addition, the interface to the span - * routines passes colors as an entire byte per channel anyway, so there - * is nothing to be saved by telling the visual to be 16 bits if the device - * is 16 bits. That is, Mesa is going to compute colors down to 8 bits per - * channel anyway. - * But we go through the motions here anyway. - */ - c->cColorBits = GetDeviceCaps(c->hDC, BITSPIXEL); - - switch (c->cColorBits) { - case 16: - red_bits = green_bits = blue_bits = 5; - alpha_bits = 0; - break; - default: - red_bits = green_bits = blue_bits = 8; - alpha_bits = 8; - break; - } - /* Create visual based on flags */ - visual = _mesa_create_visual(rgb_flag, - db_flag, /* db_flag */ - GL_FALSE, /* stereo */ - red_bits, green_bits, blue_bits, /* color RGB */ - alpha_flag ? alpha_bits : 0, /* color A */ - 0, /* index bits */ - DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */ - 8, /* stencil_bits */ - 16,16,16, /* accum RGB */ - alpha_flag ? 16 : 0, /* accum A */ - 1); /* num samples */ - - if (!visual) { - _mesa_free(c); - return NULL; - } - - pws = wmesa_get_pipe_winsys(visual); - - screen = softpipe_create_screen(pws); - - if (!screen) { - _mesa_free(c); - return NULL; - } - - pipe = softpipe_create(screen, pws, NULL); - - if (!pipe) { - /* FIXME - free screen */ - _mesa_free(c); - return NULL; - } - - pipe->priv = c; - - c->st = st_create_context(pipe, visual, NULL); - - c->st->ctx->DriverCtx = c; - - return c; -} - - -void WMesaDestroyContext( WMesaContext pwc ) -{ - GLcontext *ctx = pwc->st->ctx; - WMesaFramebuffer pwfb; - GET_CURRENT_CONTEXT(cur_ctx); - - if (cur_ctx == ctx) { - /* unbind current if deleting current context */ - WMesaMakeCurrent(NULL, NULL); - } - - /* clean up frame buffer resources */ - pwfb = wmesa_lookup_framebuffer(pwc->hDC); - if (pwfb) { - wmesa_free_framebuffer(pwc->hDC); - } - - /* Release for device, not memory contexts */ - if (WindowFromDC(pwc->hDC) != NULL) - { - ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC); - } - - st_destroy_context(pwc->st); - _mesa_free(pwc); -} - - -void WMesaMakeCurrent(WMesaContext c, HDC hdc) -{ - GLuint width = 0, height = 0; - WMesaFramebuffer pwfb; - - { - /* return if already current */ - GET_CURRENT_CONTEXT(ctx); - WMesaContext pwc = wmesa_context(ctx); - if (pwc && c == pwc && pwc->hDC == hdc) - return; - } - - pwfb = wmesa_lookup_framebuffer(hdc); - - if (hdc) { - get_window_size(hdc, &width, &height); - } - - /* Lazy creation of framebuffers */ - if (c && !pwfb && (hdc != 0)) { - GLvisual *visual = &c->st->ctx->Visual; - - pwfb = wmesa_new_framebuffer(hdc, visual, width, height); - } - - if (c && pwfb) { - st_make_current(c->st, pwfb->stfb, pwfb->stfb); - - st_resize_framebuffer(pwfb->stfb, width, height); - } - else { - /* Detach */ - st_make_current( NULL, NULL, NULL ); - } -} - - -void WMesaSwapBuffers( HDC hdc ) -{ - struct pipe_surface *surf; - struct wm_buffer *wm_buf; - WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc); - BITMAPINFO bmi, *pbmi; - - if (!pwfb) { - _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc"); - return; - } - - - /* If we're swapping the buffer associated with the current context - * we have to flush any pending rendering commands first. - */ - st_notify_swapbuffers(pwfb->stfb); - - surf = st_get_framebuffer_surface(pwfb->stfb, ST_SURFACE_BACK_LEFT); - wm_buf = wm_buffer(surf->buffer); - - pbmi = &bmi; - memset(pbmi, 0, sizeof(BITMAPINFO)); - pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pbmi->bmiHeader.biWidth = pwfb->stfb->Base.Width; - pbmi->bmiHeader.biHeight= -((long)pwfb->stfb->Base.Height); - pbmi->bmiHeader.biPlanes = 1; - pbmi->bmiHeader.biBitCount = pwfb->cColorBits; - pbmi->bmiHeader.biCompression = BI_RGB; - pbmi->bmiHeader.biSizeImage = 0; - pbmi->bmiHeader.biXPelsPerMeter = 0; - pbmi->bmiHeader.biYPelsPerMeter = 0; - pbmi->bmiHeader.biClrUsed = 0; - pbmi->bmiHeader.biClrImportant = 0; - - StretchDIBits(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, wm_buf->data, pbmi, 0, SRCCOPY); - - { - GLuint width = 0, height = 0; - - get_window_size(pwfb->hDC, &width, &height); - - st_resize_framebuffer(pwfb->stfb, width, height); - } -} - -/* This is hopefully a temporary hack to define some needed dispatch - * table entries. Hopefully, I'll find a better solution. The - * dispatch table generation scripts ought to be making these dummy - * stubs as well. */ -#if !defined(__MINGW32__) || !defined(GL_NO_STDCALL) -void gl_dispatch_stub_543(void){} -void gl_dispatch_stub_544(void){} -void gl_dispatch_stub_545(void){} -void gl_dispatch_stub_546(void){} -void gl_dispatch_stub_547(void){} -void gl_dispatch_stub_548(void){} -void gl_dispatch_stub_549(void){} -void gl_dispatch_stub_550(void){} -void gl_dispatch_stub_551(void){} -void gl_dispatch_stub_552(void){} -void gl_dispatch_stub_553(void){} -void gl_dispatch_stub_554(void){} -void gl_dispatch_stub_555(void){} -void gl_dispatch_stub_556(void){} -void gl_dispatch_stub_557(void){} -void gl_dispatch_stub_558(void){} -void gl_dispatch_stub_559(void){} -void gl_dispatch_stub_560(void){} -void gl_dispatch_stub_561(void){} -void gl_dispatch_stub_565(void){} -void gl_dispatch_stub_566(void){} -void gl_dispatch_stub_577(void){} -void gl_dispatch_stub_578(void){} -void gl_dispatch_stub_603(void){} -void gl_dispatch_stub_645(void){} -void gl_dispatch_stub_646(void){} -void gl_dispatch_stub_647(void){} -void gl_dispatch_stub_648(void){} -void gl_dispatch_stub_649(void){} -void gl_dispatch_stub_650(void){} -void gl_dispatch_stub_651(void){} -void gl_dispatch_stub_652(void){} -void gl_dispatch_stub_653(void){} -void gl_dispatch_stub_733(void){} -void gl_dispatch_stub_734(void){} -void gl_dispatch_stub_735(void){} -void gl_dispatch_stub_736(void){} -void gl_dispatch_stub_737(void){} -void gl_dispatch_stub_738(void){} -void gl_dispatch_stub_744(void){} -void gl_dispatch_stub_745(void){} -void gl_dispatch_stub_746(void){} -void gl_dispatch_stub_760(void){} -void gl_dispatch_stub_761(void){} -void gl_dispatch_stub_763(void){} -void gl_dispatch_stub_765(void){} -void gl_dispatch_stub_766(void){} -void gl_dispatch_stub_767(void){} -void gl_dispatch_stub_768(void){} - -void gl_dispatch_stub_562(void){} -void gl_dispatch_stub_563(void){} -void gl_dispatch_stub_564(void){} -void gl_dispatch_stub_567(void){} -void gl_dispatch_stub_568(void){} -void gl_dispatch_stub_569(void){} -void gl_dispatch_stub_580(void){} -void gl_dispatch_stub_581(void){} -void gl_dispatch_stub_606(void){} -void gl_dispatch_stub_654(void){} -void gl_dispatch_stub_655(void){} -void gl_dispatch_stub_656(void){} -void gl_dispatch_stub_739(void){} -void gl_dispatch_stub_740(void){} -void gl_dispatch_stub_741(void){} -void gl_dispatch_stub_748(void){} -void gl_dispatch_stub_749(void){} -void gl_dispatch_stub_769(void){} -void gl_dispatch_stub_770(void){} -void gl_dispatch_stub_771(void){} -void gl_dispatch_stub_772(void){} -void gl_dispatch_stub_773(void){} - -#endif diff --git a/src/gallium/winsys/gdi/wmesadef.h b/src/gallium/winsys/gdi/wmesadef.h deleted file mode 100644 index fb8ce30a08..0000000000 --- a/src/gallium/winsys/gdi/wmesadef.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef WMESADEF_H -#define WMESADEF_H -#ifdef __MINGW32__ -#include -#endif -#if 0 -#include "context.h" -#endif -#include "state_tracker/st_context.h" -#include "state_tracker/st_public.h" - - -/** - * The Windows Mesa rendering context, derived from GLcontext. - */ -struct wmesa_context { - struct st_context *st; - HDC hDC; - BYTE cColorBits; -}; - -/** - * Windows framebuffer, derived from gl_framebuffer - */ -struct wmesa_framebuffer -{ - struct st_framebuffer *stfb; - HDC hDC; - int pixelformat; - BYTE cColorBits; - HDC dib_hDC; - HBITMAP hbmDIB; - HBITMAP hOldBitmap; - PBYTE pbPixels; - struct wmesa_framebuffer *next; -}; - -typedef struct wmesa_framebuffer *WMesaFramebuffer; - -#endif /* WMESADEF_H */ -- cgit v1.2.3 From dbcfc0dcde4eee248812881d32b134fd733212d2 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sun, 30 Nov 2008 20:54:02 +0200 Subject: Nouveau: minor winsys API fix Signed-off-by: Pekka Paalanen --- src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c index 704f6c7750..68aade829d 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c +++ b/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c @@ -47,7 +47,8 @@ struct nouveau_softpipe_winsys { * Return list of surface formats supported by this driver. */ static boolean -nouveau_is_format_supported(struct softpipe_winsys *sws, uint format) +nouveau_is_format_supported(struct softpipe_winsys *sws, + enum pipe_format format) { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: -- cgit v1.2.3 From a6b7c0bcbebb7532b6728500a868b7c985e3f822 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 1 Dec 2008 22:24:19 -0500 Subject: nouveau: nv04-nv40 linear <-> swizzled conversion. --- src/gallium/winsys/drm/nouveau/nv04_surface.c | 151 +++++++++++++------------- 1 file changed, 78 insertions(+), 73 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c index d08955de71..4f37af7927 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -37,7 +37,11 @@ nv04_surface_format(enum pipe_format format) return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; case PIPE_FORMAT_R5G6B5_UNORM: return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; + case PIPE_FORMAT_R16_SNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y16; + case PIPE_FORMAT_X8R8G8B8_UNORM: case PIPE_FORMAT_A8R8G8B8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8; case PIPE_FORMAT_Z24S8_UNORM: return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; default: @@ -61,6 +65,69 @@ nv04_rect_format(enum pipe_format format) } } +static INLINE int +nv04_scaled_image_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A1R5G5B5_UNORM: + return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5; + case PIPE_FORMAT_A8R8G8B8_UNORM: + return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8; + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_R16_SNORM: + return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; + default: + return -1; + } +} + +static void +nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct pipe_surface *dst = nv->surf_dst; + struct pipe_surface *src = nv->surf_src; + + BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 2); + OUT_RING (chan, nv04_surface_format(dst->format) | + log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT | + log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); + OUT_RING (chan, nv->nvc->NvSwzSurf->handle); + + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); + OUT_RING (chan, nv04_scaled_image_format(src->format)); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); + OUT_RING (chan, 0); + OUT_RING (chan, h << 16 | w); + OUT_RING (chan, 0); + OUT_RING (chan, h << 16 | w); + OUT_RING (chan, 1 << 20); + OUT_RING (chan, 1 << 20); + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); + OUT_RING (chan, h << 16 | w); + OUT_RING (chan, src->stride | + NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | + NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RING (chan, 0); +} + static void nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h) @@ -107,56 +174,6 @@ nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, OUT_RING (chan, ( h << 16) | w); } -static int -nv04_surface_copy_prep_swizzled(struct nouveau_context *nv, - struct pipe_surface *dst, - struct pipe_surface *src) -{ - struct nouveau_channel *chan = nv->nvc->channel; - - BEGIN_RING(chan, nv->nvc->NvSwzSurf, - NV04_SWIZZLED_SURFACE_FORMAT, 2); - /* FIXME: read destination format from somewhere */ - OUT_RING (chan, - NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8 - | (log2i(dst->width)<height)<buffer)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 13); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); - /* FIXME: read source format from somewhere */ - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); - OUT_RING (chan, 0); - OUT_RING (chan, (src->height<<16) | src->width); - OUT_RING (chan, 0); - OUT_RING (chan, (src->height<<16) | src->width); - OUT_RING (chan, 1<<20); - OUT_RING (chan, 1<<20); - OUT_RING (chan, (src->height<<16) | src->width); - OUT_RING (chan, - src->stride - | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER - | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RING (chan, 0); - - BEGIN_RING(chan, nv->nvc->NvM2MF, - NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - nv->surface_copy = nv04_surface_copy_m2mf; - nv->surf_dst = dst; - nv->surf_src = src; - return 0; -} - static int nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, struct pipe_surface *src) @@ -169,9 +186,17 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, /* Setup transfer to swizzle the texture to vram if needed */ /* FIXME/TODO: check proper limits of this operation */ - if (nouveau_buffer(dst->buffer)->bo->flags & NOUVEAU_BO_SWIZZLED) { - /* FIXME: Disable it for the moment */ - /*return nv04_surface_copy_prep_swizzled(nv, dst, src);*/ + if (src->texture && dst->texture) { + unsigned int src_linear = src->texture->tex_usage & + NOUVEAU_TEXTURE_USAGE_LINEAR; + unsigned int dst_linear = dst->texture->tex_usage & + NOUVEAU_TEXTURE_USAGE_LINEAR; + if (src_linear ^ dst_linear) { + nv->surface_copy = nv04_surface_copy_swizzle; + nv->surf_dst = dst; + nv->surf_src = src; + return 0; + } } /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback @@ -359,10 +384,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) } BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); - OUT_RING (chan, nvc->channel->vram->handle); if (chipset < 0x10) { class = NV04_SCALED_IMAGE_FROM_MEMORY; @@ -381,22 +402,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) } BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); - OUT_RING (chan, nvc->channel->vram->handle); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); - OUT_RING (chan, nvc->NvSwzSurf->handle); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_PATTERN, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_ROP, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_BETA1, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_BETA4, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); return 0; } -- cgit v1.2.3 From 6b4776df35c46892d7701072b8c03cb1cf2d6f01 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 1 Dec 2008 23:48:29 -0500 Subject: nouveau: Use swizzled textures & render targets on nv40 when possible. --- src/gallium/winsys/drm/nouveau/nv04_surface.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c index 4f37af7927..1178620240 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -35,10 +35,9 @@ nv04_surface_format(enum pipe_format format) switch (format) { case PIPE_FORMAT_A8_UNORM: return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; + case PIPE_FORMAT_R16_SNORM: case PIPE_FORMAT_R5G6B5_UNORM: return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; - case PIPE_FORMAT_R16_SNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_Y16; case PIPE_FORMAT_X8R8G8B8_UNORM: case PIPE_FORMAT_A8R8G8B8_UNORM: return NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8; -- cgit v1.2.3 From 4371a24c320f3d26f07effa0c3e862078762c942 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Tue, 2 Dec 2008 16:12:49 -0500 Subject: nouveau: Calc pitch for swizzled textures appropriately. --- src/gallium/winsys/drm/nouveau/nv04_surface.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c index 1178620240..68338eb814 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -84,12 +84,15 @@ nv04_scaled_image_format(enum pipe_format format) static void nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h) + unsigned sx, unsigned sy, unsigned w, unsigned h) { struct nouveau_channel *chan = nv->nvc->channel; struct pipe_surface *dst = nv->surf_dst; struct pipe_surface *src = nv->surf_src; + /* POT or GTFO */ + assert(!(w & (w - 1)) && !(h & (h - 1))); + BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); -- cgit v1.2.3 From 99b862cd77fb088d0b2e62c6c15ecef82ec4fb80 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 10 Dec 2008 18:00:36 -0700 Subject: gallium: restore default_depth_bits() call in xlib winsys This was accidentally disabled in a long-ago commit. --- src/gallium/winsys/xlib/fakeglx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c index 2c0075e934..a56e63572a 100644 --- a/src/gallium/winsys/xlib/fakeglx.c +++ b/src/gallium/winsys/xlib/fakeglx.c @@ -419,7 +419,7 @@ static XMesaVisual create_glx_visual( Display *dpy, XVisualInfo *visinfo ) { int vislevel; - GLint zBits = 24; /*default_depth_bits();*/ + GLint zBits = default_depth_bits(); GLint accBits = default_accum_bits(); GLboolean alphaFlag = default_alpha_bits() > 0; @@ -1289,7 +1289,7 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) double_flag = GL_TRUE; if (vis->depth > 8) rgb_flag = GL_TRUE; - depth_size = 24; /*default_depth_bits();*/ + depth_size = default_depth_bits(); stencil_size = STENCIL_BITS; /* XXX accum??? */ } -- cgit v1.2.3 From e9e43321eeec31f1034272af094d90dde80f967d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 21 Nov 2008 05:25:31 +0900 Subject: gdi: Reimplement using the WGL statetracker. --- src/gallium/winsys/gdi/SConscript | 20 +- src/gallium/winsys/gdi/colors.h | 29 - src/gallium/winsys/gdi/gdi_softpipe_winsys.c | 344 +++++++++++ src/gallium/winsys/gdi/opengl32.def | 859 --------------------------- src/gallium/winsys/gdi/wgl.c | 701 ---------------------- src/gallium/winsys/gdi/wmesa.c | 823 ------------------------- src/gallium/winsys/gdi/wmesadef.h | 40 -- 7 files changed, 352 insertions(+), 2464 deletions(-) delete mode 100644 src/gallium/winsys/gdi/colors.h create mode 100644 src/gallium/winsys/gdi/gdi_softpipe_winsys.c delete mode 100644 src/gallium/winsys/gdi/opengl32.def delete mode 100644 src/gallium/winsys/gdi/wgl.c delete mode 100644 src/gallium/winsys/gdi/wmesa.c delete mode 100644 src/gallium/winsys/gdi/wmesadef.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript index dce81ec1ca..b463fa6505 100644 --- a/src/gallium/winsys/gdi/SConscript +++ b/src/gallium/winsys/gdi/SConscript @@ -8,32 +8,28 @@ if env['platform'] == 'windows': env = env.Clone() env.Append(CPPPATH = [ - '#src/mesa/glapi', - '#src/mesa', - '#src/mesa/main', + '#src/mesa/state_tracker/wgl', ]) env.Append(CPPDEFINES = [ - '__GL_EXPORTS', - 'BUILD_GL32', - '_GNU_H_WINDOWS32_DEFINES', ]) sources = [ - 'opengl32.def', - 'wgl.c', - 'wmesa.c', + '#src/mesa/state_tracker/wgl/opengl32.def', + 'gdi_softpipe_winsys.c', ] drivers = [ softpipe, ] - env.Append(LIBS = ['gdi32', 'user32']) + env.Append(LIBS = [ + 'gdi32', + 'user32' + ]) - # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions env.SharedLibrary( target ='opengl32', source = sources, - LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], + LIBS = wgl + glapi + mesa + drivers + auxiliaries + env['LIBS'], ) diff --git a/src/gallium/winsys/gdi/colors.h b/src/gallium/winsys/gdi/colors.h deleted file mode 100644 index 03e512c1fa..0000000000 --- a/src/gallium/winsys/gdi/colors.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Values for wmesa->pixelformat: */ - -#define PF_8A8B8G8R 3 /* 32-bit TrueColor: 8-A, 8-B, 8-G, 8-R */ -#define PF_8R8G8B 4 /* 32-bit TrueColor: 8-R, 8-G, 8-B */ -#define PF_5R6G5B 5 /* 16-bit TrueColor: 5-R, 6-G, 5-B bits */ -#define PF_DITHER8 6 /* Dithered RGB using a lookup table */ -#define PF_LOOKUP 7 /* Undithered RGB using a lookup table */ -#define PF_GRAYSCALE 10 /* Grayscale or StaticGray */ -#define PF_BADFORMAT 11 -#define PF_INDEX8 12 - - -#define BGR8(r,g,b) (unsigned)(((BYTE)((b & 0xc0) | ((g & 0xe0)>>2) | \ - ((r & 0xe0)>>5)))) - -/* Windows uses 5,5,5 for 16-bit */ -#define BGR16(r,g,b) ( (((unsigned short)b ) >> 3) | \ - (((unsigned short)g & 0xf8) << 2) | \ - (((unsigned short)r & 0xf8) << 7) ) - -#define BGR24(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)| \ - ((WORD)((BYTE)(g))<<8))| \ - (((DWORD)(BYTE)(r))<<16))) - -#define BGR32(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)| \ - ((WORD)((BYTE)(g))<<8))| \ - (((DWORD)(BYTE)(r))<<16))) - - diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c new file mode 100644 index 0000000000..e66ce48f2d --- /dev/null +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -0,0 +1,344 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * @file + * Softpipe support. + * + * @author Keith Whitwell + * @author Brian Paul + * @author Jose Fonseca + */ + + +#include + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "softpipe/sp_winsys.h" +#include "stw_winsys.h" + + +struct gdi_softpipe_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; +}; + + +/** Cast wrapper */ +static INLINE struct gdi_softpipe_buffer * +gdi_softpipe_buffer( struct pipe_buffer *buf ) +{ + return (struct gdi_softpipe_buffer *)buf; +} + + +static void * +gdi_softpipe_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags) +{ + struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf); + gdi_softpipe_buf->mapped = gdi_softpipe_buf->data; + return gdi_softpipe_buf->mapped; +} + + +static void +gdi_softpipe_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf); + gdi_softpipe_buf->mapped = NULL; +} + + +static void +gdi_softpipe_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct gdi_softpipe_buffer *oldBuf = gdi_softpipe_buffer(buf); + + if (oldBuf->data) { + if (!oldBuf->userBuffer) + align_free(oldBuf->data); + + oldBuf->data = NULL; + } + + FREE(oldBuf); +} + + +static const char * +gdi_softpipe_get_name(struct pipe_winsys *winsys) +{ + return "softpipe"; +} + + +static struct pipe_buffer * +gdi_softpipe_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct gdi_softpipe_buffer *buffer = CALLOC_STRUCT(gdi_softpipe_buffer); + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + buffer->data = align_malloc(size, alignment); + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +gdi_softpipe_user_buffer_create(struct pipe_winsys *winsys, + void *ptr, + unsigned bytes) +{ + struct gdi_softpipe_buffer *buffer; + + buffer = CALLOC_STRUCT(gdi_softpipe_buffer); + if(!buffer) + return NULL; + + buffer->base.refcount = 1; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + + +static int +gdi_softpipe_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->stride * surf->nblocksy); + if(!surf->buffer) + return -1; + + return 0; +} + + +static struct pipe_surface * +gdi_softpipe_surface_alloc(struct pipe_winsys *winsys) +{ + struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); + + assert(winsys); + + surface->refcount = 1; + surface->winsys = winsys; + + return surface; +} + + +static void +gdi_softpipe_surface_release(struct pipe_winsys *winsys, + struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + assert(!surf->texture); + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + winsys_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + +static void +gdi_softpipe_dummy_flush_frontbuffer(struct pipe_winsys *winsys, + struct pipe_surface *surface, + void *context_private) +{ + assert(0); +} + + +static void +gdi_softpipe_fence_reference(struct pipe_winsys *winsys, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +gdi_softpipe_fence_signalled(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +gdi_softpipe_fence_finish(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static void +gdi_softpipe_destroy(struct pipe_winsys *winsys) +{ + FREE(winsys); +} + + +static struct pipe_screen * +gdi_softpipe_screen_create(void) +{ + static struct pipe_winsys *winsys; + struct pipe_screen *screen; + + winsys = CALLOC_STRUCT(pipe_winsys); + if(!winsys) + return NULL; + + winsys->destroy = gdi_softpipe_destroy; + + winsys->buffer_create = gdi_softpipe_buffer_create; + winsys->user_buffer_create = gdi_softpipe_user_buffer_create; + winsys->buffer_map = gdi_softpipe_buffer_map; + winsys->buffer_unmap = gdi_softpipe_buffer_unmap; + winsys->buffer_destroy = gdi_softpipe_buffer_destroy; + + winsys->surface_alloc = gdi_softpipe_surface_alloc; + winsys->surface_alloc_storage = gdi_softpipe_surface_alloc_storage; + winsys->surface_release = gdi_softpipe_surface_release; + + winsys->fence_reference = gdi_softpipe_fence_reference; + winsys->fence_signalled = gdi_softpipe_fence_signalled; + winsys->fence_finish = gdi_softpipe_fence_finish; + + winsys->flush_frontbuffer = gdi_softpipe_dummy_flush_frontbuffer; + winsys->get_name = gdi_softpipe_get_name; + + screen = softpipe_create_screen(winsys); + if(!screen) + gdi_softpipe_destroy(winsys); + + return screen; +} + + +static struct pipe_context * +gdi_softpipe_context_create(struct pipe_screen *screen) +{ + return softpipe_create(screen, screen->winsys, NULL); +} + + +static void +gdi_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, + struct pipe_surface *surface, + HDC hDC) +{ + struct gdi_softpipe_buffer *buffer; + BITMAPINFO bmi; + + buffer = gdi_softpipe_buffer(surface->buffer); + + memset(&bmi, 0, sizeof(BITMAPINFO)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = surface->stride / pf_get_size(surface->format); + bmi.bmiHeader.biHeight= -surface->height; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = pf_get_bits(surface->format); + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = 0; + bmi.bmiHeader.biXPelsPerMeter = 0; + bmi.bmiHeader.biYPelsPerMeter = 0; + bmi.bmiHeader.biClrUsed = 0; + bmi.bmiHeader.biClrImportant = 0; + + StretchDIBits(hDC, + 0, 0, surface->width, surface->height, + 0, 0, surface->width, surface->height, + buffer->data, &bmi, 0, SRCCOPY); +} + + +const struct stw_winsys stw_winsys = { + &gdi_softpipe_screen_create, + &gdi_softpipe_context_create, + &gdi_softpipe_flush_frontbuffer +}; diff --git a/src/gallium/winsys/gdi/opengl32.def b/src/gallium/winsys/gdi/opengl32.def deleted file mode 100644 index 54e72f57b1..0000000000 --- a/src/gallium/winsys/gdi/opengl32.def +++ /dev/null @@ -1,859 +0,0 @@ -; DO NOT EDIT - This file generated automatically by mesadef.py script -;DESCRIPTION 'Mesa (OpenGL work-alike) for Win32' -VERSION 6.5 -; -; Module definition file for Mesa (OPENGL32.DLL) -; -; Note: The OpenGL functions use the STDCALL -; function calling convention. Microsoft's -; OPENGL32 uses this convention and so must the -; Mesa OPENGL32 so that the Mesa DLL can be used -; as a drop-in replacement. -; -; The linker exports STDCALL entry points with -; 'decorated' names; e.g., _glBegin@0, where the -; trailing number is the number of bytes of -; parameter data pushed onto the stack. The -; callee is responsible for popping this data -; off the stack, usually via a RETF n instruction. -; -; However, the Microsoft OPENGL32.DLL does not export -; the decorated names, even though the calling convention -; is STDCALL. So, this module definition file is -; needed to force the Mesa OPENGL32.DLL to export the -; symbols in the same manner as the Microsoft DLL. -; Were it not for this problem, this file would not -; be needed (for the gl* functions) since the entry -; points are compiled with dllexport declspec. -; -; However, this file is still needed to export "internal" -; Mesa symbols for the benefit of the OSMESA32.DLL. -; -EXPORTS - glNewList - glEndList - glCallList - glCallLists - glDeleteLists - glGenLists - glListBase - glBegin - glBitmap - glColor3b - glColor3bv - glColor3d - glColor3dv - glColor3f - glColor3fv - glColor3i - glColor3iv - glColor3s - glColor3sv - glColor3ub - glColor3ubv - glColor3ui - glColor3uiv - glColor3us - glColor3usv - glColor4b - glColor4bv - glColor4d - glColor4dv - glColor4f - glColor4fv - glColor4i - glColor4iv - glColor4s - glColor4sv - glColor4ub - glColor4ubv - glColor4ui - glColor4uiv - glColor4us - glColor4usv - glEdgeFlag - glEdgeFlagv - glEnd - glIndexd - glIndexdv - glIndexf - glIndexfv - glIndexi - glIndexiv - glIndexs - glIndexsv - glNormal3b - glNormal3bv - glNormal3d - glNormal3dv - glNormal3f - glNormal3fv - glNormal3i - glNormal3iv - glNormal3s - glNormal3sv - glRasterPos2d - glRasterPos2dv - glRasterPos2f - glRasterPos2fv - glRasterPos2i - glRasterPos2iv - glRasterPos2s - glRasterPos2sv - glRasterPos3d - glRasterPos3dv - glRasterPos3f - glRasterPos3fv - glRasterPos3i - glRasterPos3iv - glRasterPos3s - glRasterPos3sv - glRasterPos4d - glRasterPos4dv - glRasterPos4f - glRasterPos4fv - glRasterPos4i - glRasterPos4iv - glRasterPos4s - glRasterPos4sv - glRectd - glRectdv - glRectf - glRectfv - glRecti - glRectiv - glRects - glRectsv - glTexCoord1d - glTexCoord1dv - glTexCoord1f - glTexCoord1fv - glTexCoord1i - glTexCoord1iv - glTexCoord1s - glTexCoord1sv - glTexCoord2d - glTexCoord2dv - glTexCoord2f - glTexCoord2fv - glTexCoord2i - glTexCoord2iv - glTexCoord2s - glTexCoord2sv - glTexCoord3d - glTexCoord3dv - glTexCoord3f - glTexCoord3fv - glTexCoord3i - glTexCoord3iv - glTexCoord3s - glTexCoord3sv - glTexCoord4d - glTexCoord4dv - glTexCoord4f - glTexCoord4fv - glTexCoord4i - glTexCoord4iv - glTexCoord4s - glTexCoord4sv - glVertex2d - glVertex2dv - glVertex2f - glVertex2fv - glVertex2i - glVertex2iv - glVertex2s - glVertex2sv - glVertex3d - glVertex3dv - glVertex3f - glVertex3fv - glVertex3i - glVertex3iv - glVertex3s - glVertex3sv - glVertex4d - glVertex4dv - glVertex4f - glVertex4fv - glVertex4i - glVertex4iv - glVertex4s - glVertex4sv - glClipPlane - glColorMaterial - glCullFace - glFogf - glFogfv - glFogi - glFogiv - glFrontFace - glHint - glLightf - glLightfv - glLighti - glLightiv - glLightModelf - glLightModelfv - glLightModeli - glLightModeliv - glLineStipple - glLineWidth - glMaterialf - glMaterialfv - glMateriali - glMaterialiv - glPointSize - glPolygonMode - glPolygonStipple - glScissor - glShadeModel - glTexParameterf - glTexParameterfv - glTexParameteri - glTexParameteriv - glTexImage1D - glTexImage2D - glTexEnvf - glTexEnvfv - glTexEnvi - glTexEnviv - glTexGend - glTexGendv - glTexGenf - glTexGenfv - glTexGeni - glTexGeniv - glFeedbackBuffer - glSelectBuffer - glRenderMode - glInitNames - glLoadName - glPassThrough - glPopName - glPushName - glDrawBuffer - glClear - glClearAccum - glClearIndex - glClearColor - glClearStencil - glClearDepth - glStencilMask - glColorMask - glDepthMask - glIndexMask - glAccum - glDisable - glEnable - glFinish - glFlush - glPopAttrib - glPushAttrib - glMap1d - glMap1f - glMap2d - glMap2f - glMapGrid1d - glMapGrid1f - glMapGrid2d - glMapGrid2f - glEvalCoord1d - glEvalCoord1dv - glEvalCoord1f - glEvalCoord1fv - glEvalCoord2d - glEvalCoord2dv - glEvalCoord2f - glEvalCoord2fv - glEvalMesh1 - glEvalPoint1 - glEvalMesh2 - glEvalPoint2 - glAlphaFunc - glBlendFunc - glLogicOp - glStencilFunc - glStencilOp - glDepthFunc - glPixelZoom - glPixelTransferf - glPixelTransferi - glPixelStoref - glPixelStorei - glPixelMapfv - glPixelMapuiv - glPixelMapusv - glReadBuffer - glCopyPixels - glReadPixels - glDrawPixels - glGetBooleanv - glGetClipPlane - glGetDoublev - glGetError - glGetFloatv - glGetIntegerv - glGetLightfv - glGetLightiv - glGetMapdv - glGetMapfv - glGetMapiv - glGetMaterialfv - glGetMaterialiv - glGetPixelMapfv - glGetPixelMapuiv - glGetPixelMapusv - glGetPolygonStipple - glGetString - glGetTexEnvfv - glGetTexEnviv - glGetTexGendv - glGetTexGenfv - glGetTexGeniv - glGetTexImage - glGetTexParameterfv - glGetTexParameteriv - glGetTexLevelParameterfv - glGetTexLevelParameteriv - glIsEnabled - glIsList - glDepthRange - glFrustum - glLoadIdentity - glLoadMatrixf - glLoadMatrixd - glMatrixMode - glMultMatrixf - glMultMatrixd - glOrtho - glPopMatrix - glPushMatrix - glRotated - glRotatef - glScaled - glScalef - glTranslated - glTranslatef - glViewport - glArrayElement - glColorPointer - glDisableClientState - glDrawArrays - glDrawElements - glEdgeFlagPointer - glEnableClientState - glGetPointerv - glIndexPointer - glInterleavedArrays - glNormalPointer - glTexCoordPointer - glVertexPointer - glPolygonOffset - glCopyTexImage1D - glCopyTexImage2D - glCopyTexSubImage1D - glCopyTexSubImage2D - glTexSubImage1D - glTexSubImage2D - glAreTexturesResident - glBindTexture - glDeleteTextures - glGenTextures - glIsTexture - glPrioritizeTextures - glIndexub - glIndexubv - glPopClientAttrib - glPushClientAttrib - glBlendColor - glBlendEquation - glDrawRangeElements - glColorTable - glColorTableParameterfv - glColorTableParameteriv - glCopyColorTable - glGetColorTable - glGetColorTableParameterfv - glGetColorTableParameteriv - glColorSubTable - glCopyColorSubTable - glConvolutionFilter1D - glConvolutionFilter2D - glConvolutionParameterf - glConvolutionParameterfv - glConvolutionParameteri - glConvolutionParameteriv - glCopyConvolutionFilter1D - glCopyConvolutionFilter2D - glGetConvolutionFilter - glGetConvolutionParameterfv - glGetConvolutionParameteriv - glGetSeparableFilter - glSeparableFilter2D - glGetHistogram - glGetHistogramParameterfv - glGetHistogramParameteriv - glGetMinmax - glGetMinmaxParameterfv - glGetMinmaxParameteriv - glHistogram - glMinmax - glResetHistogram - glResetMinmax - glTexImage3D - glTexSubImage3D - glCopyTexSubImage3D - glActiveTextureARB - glClientActiveTextureARB - glMultiTexCoord1dARB - glMultiTexCoord1dvARB - glMultiTexCoord1fARB - glMultiTexCoord1fvARB - glMultiTexCoord1iARB - glMultiTexCoord1ivARB - glMultiTexCoord1sARB - glMultiTexCoord1svARB - glMultiTexCoord2dARB - glMultiTexCoord2dvARB - glMultiTexCoord2fARB - glMultiTexCoord2fvARB - glMultiTexCoord2iARB - glMultiTexCoord2ivARB - glMultiTexCoord2sARB - glMultiTexCoord2svARB - glMultiTexCoord3dARB - glMultiTexCoord3dvARB - glMultiTexCoord3fARB - glMultiTexCoord3fvARB - glMultiTexCoord3iARB - glMultiTexCoord3ivARB - glMultiTexCoord3sARB - glMultiTexCoord3svARB - glMultiTexCoord4dARB - glMultiTexCoord4dvARB - glMultiTexCoord4fARB - glMultiTexCoord4fvARB - glMultiTexCoord4iARB - glMultiTexCoord4ivARB - glMultiTexCoord4sARB - glMultiTexCoord4svARB - glLoadTransposeMatrixfARB - glLoadTransposeMatrixdARB - glMultTransposeMatrixfARB - glMultTransposeMatrixdARB - glSampleCoverageARB - glCompressedTexImage3DARB - glCompressedTexImage2DARB - glCompressedTexImage1DARB - glCompressedTexSubImage3DARB - glCompressedTexSubImage2DARB - glCompressedTexSubImage1DARB - glGetCompressedTexImageARB - glActiveTexture - glClientActiveTexture - glMultiTexCoord1d - glMultiTexCoord1dv - glMultiTexCoord1f - glMultiTexCoord1fv - glMultiTexCoord1i - glMultiTexCoord1iv - glMultiTexCoord1s - glMultiTexCoord1sv - glMultiTexCoord2d - glMultiTexCoord2dv - glMultiTexCoord2f - glMultiTexCoord2fv - glMultiTexCoord2i - glMultiTexCoord2iv - glMultiTexCoord2s - glMultiTexCoord2sv - glMultiTexCoord3d - glMultiTexCoord3dv - glMultiTexCoord3f - glMultiTexCoord3fv - glMultiTexCoord3i - glMultiTexCoord3iv - glMultiTexCoord3s - glMultiTexCoord3sv - glMultiTexCoord4d - glMultiTexCoord4dv - glMultiTexCoord4f - glMultiTexCoord4fv - glMultiTexCoord4i - glMultiTexCoord4iv - glMultiTexCoord4s - glMultiTexCoord4sv - glLoadTransposeMatrixf - glLoadTransposeMatrixd - glMultTransposeMatrixf - glMultTransposeMatrixd - glSampleCoverage - glCompressedTexImage3D - glCompressedTexImage2D - glCompressedTexImage1D - glCompressedTexSubImage3D - glCompressedTexSubImage2D - glCompressedTexSubImage1D - glGetCompressedTexImage - glBlendColorEXT - glPolygonOffsetEXT - glTexImage3DEXT - glTexSubImage3DEXT - glTexSubImage1DEXT - glTexSubImage2DEXT - glCopyTexImage1DEXT - glCopyTexImage2DEXT - glCopyTexSubImage1DEXT - glCopyTexSubImage2DEXT - glCopyTexSubImage3DEXT - glAreTexturesResidentEXT - glBindTextureEXT - glDeleteTexturesEXT - glGenTexturesEXT - glIsTextureEXT - glPrioritizeTexturesEXT - glArrayElementEXT - glColorPointerEXT - glDrawArraysEXT - glEdgeFlagPointerEXT - glGetPointervEXT - glIndexPointerEXT - glNormalPointerEXT - glTexCoordPointerEXT - glVertexPointerEXT - glBlendEquationEXT - glPointParameterfEXT - glPointParameterfvEXT - glPointParameterfARB - glPointParameterfvARB - glColorTableEXT - glGetColorTableEXT - glGetColorTableParameterivEXT - glGetColorTableParameterfvEXT - glLockArraysEXT - glUnlockArraysEXT - glDrawRangeElementsEXT - glSecondaryColor3bEXT - glSecondaryColor3bvEXT - glSecondaryColor3dEXT - glSecondaryColor3dvEXT - glSecondaryColor3fEXT - glSecondaryColor3fvEXT - glSecondaryColor3iEXT - glSecondaryColor3ivEXT - glSecondaryColor3sEXT - glSecondaryColor3svEXT - glSecondaryColor3ubEXT - glSecondaryColor3ubvEXT - glSecondaryColor3uiEXT - glSecondaryColor3uivEXT - glSecondaryColor3usEXT - glSecondaryColor3usvEXT - glSecondaryColorPointerEXT - glMultiDrawArraysEXT - glMultiDrawElementsEXT - glFogCoordfEXT - glFogCoordfvEXT - glFogCoorddEXT - glFogCoorddvEXT - glFogCoordPointerEXT - glBlendFuncSeparateEXT - glFlushVertexArrayRangeNV - glVertexArrayRangeNV - glCombinerParameterfvNV - glCombinerParameterfNV - glCombinerParameterivNV - glCombinerParameteriNV - glCombinerInputNV - glCombinerOutputNV - glFinalCombinerInputNV - glGetCombinerInputParameterfvNV - glGetCombinerInputParameterivNV - glGetCombinerOutputParameterfvNV - glGetCombinerOutputParameterivNV - glGetFinalCombinerInputParameterfvNV - glGetFinalCombinerInputParameterivNV - glResizeBuffersMESA - glWindowPos2dMESA - glWindowPos2dvMESA - glWindowPos2fMESA - glWindowPos2fvMESA - glWindowPos2iMESA - glWindowPos2ivMESA - glWindowPos2sMESA - glWindowPos2svMESA - glWindowPos3dMESA - glWindowPos3dvMESA - glWindowPos3fMESA - glWindowPos3fvMESA - glWindowPos3iMESA - glWindowPos3ivMESA - glWindowPos3sMESA - glWindowPos3svMESA - glWindowPos4dMESA - glWindowPos4dvMESA - glWindowPos4fMESA - glWindowPos4fvMESA - glWindowPos4iMESA - glWindowPos4ivMESA - glWindowPos4sMESA - glWindowPos4svMESA - glWindowPos2dARB - glWindowPos2fARB - glWindowPos2iARB - glWindowPos2sARB - glWindowPos2dvARB - glWindowPos2fvARB - glWindowPos2ivARB - glWindowPos2svARB - glWindowPos3dARB - glWindowPos3fARB - glWindowPos3iARB - glWindowPos3sARB - glWindowPos3dvARB - glWindowPos3fvARB - glWindowPos3ivARB - glWindowPos3svARB - glAreProgramsResidentNV - glBindProgramNV - glDeleteProgramsNV - glExecuteProgramNV - glGenProgramsNV - glGetProgramParameterdvNV - glGetProgramParameterfvNV - glGetProgramivNV - glGetProgramStringNV - glGetTrackMatrixivNV - glGetVertexAttribdvNV - glGetVertexAttribfvNV - glGetVertexAttribivNV - glGetVertexAttribPointervNV - glIsProgramNV - glLoadProgramNV - glProgramParameter4dNV - glProgramParameter4dvNV - glProgramParameter4fNV - glProgramParameter4fvNV - glProgramParameters4dvNV - glProgramParameters4fvNV - glRequestResidentProgramsNV - glTrackMatrixNV - glVertexAttribPointerNV - glVertexAttrib1dNV - glVertexAttrib1dvNV - glVertexAttrib1fNV - glVertexAttrib1fvNV - glVertexAttrib1sNV - glVertexAttrib1svNV - glVertexAttrib2dNV - glVertexAttrib2dvNV - glVertexAttrib2fNV - glVertexAttrib2fvNV - glVertexAttrib2sNV - glVertexAttrib2svNV - glVertexAttrib3dNV - glVertexAttrib3dvNV - glVertexAttrib3fNV - glVertexAttrib3fvNV - glVertexAttrib3sNV - glVertexAttrib3svNV - glVertexAttrib4dNV - glVertexAttrib4dvNV - glVertexAttrib4fNV - glVertexAttrib4fvNV - glVertexAttrib4sNV - glVertexAttrib4svNV - glVertexAttrib4ubNV - glVertexAttrib4ubvNV - glVertexAttribs1dvNV - glVertexAttribs1fvNV - glVertexAttribs1svNV - glVertexAttribs2dvNV - glVertexAttribs2fvNV - glVertexAttribs2svNV - glVertexAttribs3dvNV - glVertexAttribs3fvNV - glVertexAttribs3svNV - glVertexAttribs4dvNV - glVertexAttribs4fvNV - glVertexAttribs4svNV - glVertexAttribs4ubvNV - glPointParameteriNV - glPointParameterivNV - glFogCoordf - glFogCoordfv - glFogCoordd - glFogCoorddv - glFogCoordPointer - glMultiDrawArrays - glMultiDrawElements - glPointParameterf - glPointParameterfv - glPointParameteri - glPointParameteriv - glSecondaryColor3b - glSecondaryColor3bv - glSecondaryColor3d - glSecondaryColor3dv - glSecondaryColor3f - glSecondaryColor3fv - glSecondaryColor3i - glSecondaryColor3iv - glSecondaryColor3s - glSecondaryColor3sv - glSecondaryColor3ub - glSecondaryColor3ubv - glSecondaryColor3ui - glSecondaryColor3uiv - glSecondaryColor3us - glSecondaryColor3usv - glSecondaryColorPointer - glWindowPos2d - glWindowPos2dv - glWindowPos2f - glWindowPos2fv - glWindowPos2i - glWindowPos2iv - glWindowPos2s - glWindowPos2sv - glWindowPos3d - glWindowPos3dv - glWindowPos3f - glWindowPos3fv - glWindowPos3i - glWindowPos3iv - glWindowPos3s - glWindowPos3sv - glVertexAttrib1sARB - glVertexAttrib1fARB - glVertexAttrib1dARB - glVertexAttrib2sARB - glVertexAttrib2fARB - glVertexAttrib2dARB - glVertexAttrib3sARB - glVertexAttrib3fARB - glVertexAttrib3dARB - glVertexAttrib4sARB - glVertexAttrib4fARB - glVertexAttrib4dARB - glVertexAttrib4NubARB - glVertexAttrib1svARB - glVertexAttrib1fvARB - glVertexAttrib1dvARB - glVertexAttrib2svARB - glVertexAttrib2fvARB - glVertexAttrib2dvARB - glVertexAttrib3svARB - glVertexAttrib3fvARB - glVertexAttrib3dvARB - glVertexAttrib4bvARB - glVertexAttrib4svARB - glVertexAttrib4ivARB - glVertexAttrib4ubvARB - glVertexAttrib4usvARB - glVertexAttrib4uivARB - glVertexAttrib4fvARB - glVertexAttrib4dvARB - glVertexAttrib4NbvARB - glVertexAttrib4NsvARB - glVertexAttrib4NivARB - glVertexAttrib4NubvARB - glVertexAttrib4NusvARB - glVertexAttrib4NuivARB - glVertexAttribPointerARB - glEnableVertexAttribArrayARB - glDisableVertexAttribArrayARB - glProgramStringARB - glBindProgramARB - glDeleteProgramsARB - glGenProgramsARB - glIsProgramARB - glProgramEnvParameter4dARB - glProgramEnvParameter4dvARB - glProgramEnvParameter4fARB - glProgramEnvParameter4fvARB - glProgramLocalParameter4dARB - glProgramLocalParameter4dvARB - glProgramLocalParameter4fARB - glProgramLocalParameter4fvARB - glGetProgramEnvParameterdvARB - glGetProgramEnvParameterfvARB - glGetProgramLocalParameterdvARB - glGetProgramLocalParameterfvARB - glGetProgramivARB - glGetProgramStringARB - glGetVertexAttribdvARB - glGetVertexAttribfvARB - glGetVertexAttribivARB - glGetVertexAttribPointervARB - glProgramNamedParameter4fNV - glProgramNamedParameter4dNV - glProgramNamedParameter4fvNV - glProgramNamedParameter4dvNV - glGetProgramNamedParameterfvNV - glGetProgramNamedParameterdvNV - glBindBufferARB - glBufferDataARB - glBufferSubDataARB - glDeleteBuffersARB - glGenBuffersARB - glGetBufferParameterivARB - glGetBufferPointervARB - glGetBufferSubDataARB - glIsBufferARB - glMapBufferARB - glUnmapBufferARB - glGenQueriesARB - glDeleteQueriesARB - glIsQueryARB - glBeginQueryARB - glEndQueryARB - glGetQueryivARB - glGetQueryObjectivARB - glGetQueryObjectuivARB - glBindBuffer - glBufferData - glBufferSubData - glDeleteBuffers - glGenBuffers - glGetBufferParameteriv - glGetBufferPointerv - glGetBufferSubData - glIsBuffer - glMapBuffer - glUnmapBuffer - glGenQueries - glDeleteQueries - glIsQuery - glBeginQuery - glEndQuery - glGetQueryiv - glGetQueryObjectiv - glGetQueryObjectuiv -; -; WGL API - wglChoosePixelFormat - wglCopyContext - wglCreateContext - wglCreateLayerContext - wglDeleteContext - wglDescribeLayerPlane - wglDescribePixelFormat - wglGetCurrentContext - wglGetCurrentDC - wglGetLayerPaletteEntries - wglGetPixelFormat - wglGetProcAddress - wglMakeCurrent - wglRealizeLayerPalette - wglSetLayerPaletteEntries - wglSetPixelFormat - wglShareLists - wglSwapBuffers - wglSwapLayerBuffers - wglUseFontBitmapsA - wglUseFontBitmapsW - wglUseFontOutlinesA - wglUseFontOutlinesW - wglGetExtensionsStringARB diff --git a/src/gallium/winsys/gdi/wgl.c b/src/gallium/winsys/gdi/wgl.c deleted file mode 100644 index 3ce470480d..0000000000 --- a/src/gallium/winsys/gdi/wgl.c +++ /dev/null @@ -1,701 +0,0 @@ -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* - * File name : wgl.c - * WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru - * Some things originated from the 3Dfx WGL functions - */ - -/* - * This file contains the implementation of the wgl* functions for - * Mesa on Windows. Since these functions are provided by Windows in - * GDI/OpenGL, we must supply our versions that work with Mesa here. - */ - - -/* We're essentially building part of GDI here, so define this so that - * we get the right export linkage. */ -#ifdef __MINGW32__ - -#include -#include -#include -#include - -# if defined(BUILD_GL32) -# define WINGDIAPI __declspec(dllexport) -# else -# define __W32API_USE_DLLIMPORT__ -# endif - -#include -#include "GL/mesa_wgl.h" -#include - -#else - -#define _GDI32_ -#include - -#endif - -#include "glapi.h" -#include "GL/wmesa.h" /* protos for wmesa* functions */ - -/* - * Pixel Format Descriptors - */ - -/* Extend the PFD to include DB flag */ -struct __pixelformat__ -{ - PIXELFORMATDESCRIPTOR pfd; - GLboolean doubleBuffered; -}; - -/* These are the PFD's supported by this driver. */ -struct __pixelformat__ pfd[] = -{ - /* Double Buffer, alpha */ - { - { - sizeof(PIXELFORMATDESCRIPTOR), 1, - PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| - PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, - PFD_TYPE_RGBA, - 24, - 8, 0, - 8, 8, - 8, 16, - 8, 24, - 0, 0, 0, 0, 0, - 16, 8, - 0, 0, 0, - 0, 0, 0 - }, - GL_TRUE - }, - /* Single Buffer, alpha */ - { - { - sizeof(PIXELFORMATDESCRIPTOR), 1, - PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| - PFD_GENERIC_FORMAT, - PFD_TYPE_RGBA, - 24, - 8, 0, - 8, 8, - 8, 16, - 8, 24, - 0, 0, 0, 0, 0, - 16, 8, - 0, 0, 0, - 0, 0, 0 - }, - GL_FALSE - }, - /* Double Buffer, no alpha */ - { - { - sizeof(PIXELFORMATDESCRIPTOR), 1, - PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| - PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, - PFD_TYPE_RGBA, - 24, - 8, 0, - 8, 8, - 8, 16, - 0, 0, - 0, 0, 0, 0, 0, - 16, 8, - 0, 0, 0, - 0, 0, 0 - }, - GL_TRUE - }, - /* Single Buffer, no alpha */ - { - { - sizeof(PIXELFORMATDESCRIPTOR), 1, - PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| - PFD_GENERIC_FORMAT, - PFD_TYPE_RGBA, - 24, - 8, 0, - 8, 8, - 8, 16, - 0, 0, - 0, 0, 0, 0, 0, - 16, 8, - 0, 0, 0, - 0, 0, 0 - }, - GL_FALSE - }, -}; - -int npfd = sizeof(pfd) / sizeof(pfd[0]); - - -/* - * Contexts - */ - -typedef struct { - WMesaContext ctx; -} MesaWglCtx; - -#define MESAWGL_CTX_MAX_COUNT 20 - -static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT]; - -static unsigned ctx_count = 0; -static int ctx_current = -1; -static unsigned curPFD = 0; - -static HDC CurrentHDC = 0; - - -WINGDIAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc) -{ - int i = 0; - if (!ctx_count) { - for(i=0;inSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1) - { - SetLastError(0); - return(0); - } - for(i = 0; i < npfd;i++) - { - delta = 0; - if( - (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) && - !(pfd[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW)) - continue; - if( - (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) && - !(pfd[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP)) - continue; - if( - (ppfd->dwFlags & PFD_SUPPORT_GDI) && - !(pfd[i].pfd.dwFlags & PFD_SUPPORT_GDI)) - continue; - if( - (ppfd->dwFlags & PFD_SUPPORT_OPENGL) && - !(pfd[i].pfd.dwFlags & PFD_SUPPORT_OPENGL)) - continue; - if( - !(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) && - ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != - (pfd[i].pfd.dwFlags & PFD_DOUBLEBUFFER))) - continue; - if( - !(ppfd->dwFlags & PFD_STEREO_DONTCARE) && - ((ppfd->dwFlags & PFD_STEREO) != - (pfd[i].pfd.dwFlags & PFD_STEREO))) - continue; - if(ppfd->iPixelType != pfd[i].pfd.iPixelType) - delta++; - if(ppfd->cAlphaBits != pfd[i].pfd.cAlphaBits) - delta++; - if(delta < bestdelta) - { - best = i + 1; - bestdelta = delta; - if(bestdelta == 0) - break; - } - } - if(best == -1) - { - SetLastError(0); - return(0); - } - return(best); -} - -WINGDIAPI int GLAPIENTRY wglDescribePixelFormat(HDC hdc, - int iPixelFormat, - UINT nBytes, - LPPIXELFORMATDESCRIPTOR ppfd) -{ - (void) hdc; - - if(ppfd == NULL) - return(npfd); - if(iPixelFormat < 1 || iPixelFormat > npfd || - nBytes != sizeof(PIXELFORMATDESCRIPTOR)) - { - SetLastError(0); - return(0); - } - *ppfd = pfd[iPixelFormat - 1].pfd; - return(npfd); -} - -WINGDIAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc) -{ - PROC p = (PROC) _glapi_get_proc_address((const char *) lpszProc); - if (p) - return p; - - SetLastError(0); - return(NULL); -} - -WINGDIAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc) -{ - (void) hdc; - if(curPFD == 0) { - SetLastError(0); - return(0); - } - return(curPFD); -} - -WINGDIAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat, - const PIXELFORMATDESCRIPTOR *ppfd) -{ - (void) hdc; - - if(iPixelFormat < 1 || iPixelFormat > npfd || - ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) { - SetLastError(0); - return(FALSE); - } - curPFD = iPixelFormat; - return(TRUE); -} - -WINGDIAPI BOOL GLAPIENTRY wglSwapBuffers(HDC hdc) -{ - WMesaSwapBuffers(hdc); - return TRUE; -} - -static FIXED FixedFromDouble(double d) -{ - long l = (long) (d * 65536L); - return *(FIXED *) (void *) &l; -} - - -/* -** This is cribbed from FX/fxwgl.c, and seems to implement support -** for bitmap fonts where the wglUseFontBitmapsA() code implements -** support for outline fonts. In combination they hopefully give -** fairly generic support for fonts. -*/ -static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar, - DWORD numChars, DWORD listBase) -{ -#define VERIFY(a) a - - TEXTMETRIC metric; - BITMAPINFO *dibInfo; - HDC bitDevice; - COLORREF tempColor; - int i; - - VERIFY(GetTextMetrics(fontDevice, &metric)); - - dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1); - dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - dibInfo->bmiHeader.biPlanes = 1; - dibInfo->bmiHeader.biBitCount = 1; - dibInfo->bmiHeader.biCompression = BI_RGB; - - bitDevice = CreateCompatibleDC(fontDevice); - - /* Swap fore and back colors so the bitmap has the right polarity */ - tempColor = GetBkColor(bitDevice); - SetBkColor(bitDevice, GetTextColor(bitDevice)); - SetTextColor(bitDevice, tempColor); - - /* Place chars based on base line */ - VERIFY(SetTextAlign(bitDevice, TA_BASELINE) != GDI_ERROR ? 1 : 0); - - for(i = 0; i < (int)numChars; i++) { - SIZE size; - char curChar; - int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res; - HBITMAP bitObject; - HGDIOBJ origBmap; - unsigned char *bmap; - - curChar = (char)(i + firstChar); - - /* Find how high/wide this character is */ - VERIFY(GetTextExtentPoint32(bitDevice, (LPCWSTR)&curChar, 1, &size)); - - /* Create the output bitmap */ - charWidth = size.cx; - charHeight = size.cy; - /* Round up to the next multiple of 32 bits */ - bmapWidth = ((charWidth + 31) / 32) * 32; - bmapHeight = charHeight; - bitObject = CreateCompatibleBitmap(bitDevice, - bmapWidth, - bmapHeight); - /* VERIFY(bitObject); */ - - /* Assign the output bitmap to the device */ - origBmap = SelectObject(bitDevice, bitObject); - (void) VERIFY(origBmap); - - VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) ); - - /* Use our source font on the device */ - VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT))); - - /* Draw the character */ - VERIFY(TextOut(bitDevice, 0, metric.tmAscent, (LPCWSTR)&curChar, 1)); - - /* Unselect our bmap object */ - VERIFY(SelectObject(bitDevice, origBmap)); - - /* Convert the display dependant representation to a 1 bit deep DIB */ - numBytes = (bmapWidth * bmapHeight) / 8; - bmap = (unsigned char *)malloc(numBytes); - dibInfo->bmiHeader.biWidth = bmapWidth; - dibInfo->bmiHeader.biHeight = bmapHeight; - res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap, - dibInfo, - DIB_RGB_COLORS); - /* VERIFY(res); */ - - /* Create the GL object */ - glNewList(i + listBase, GL_COMPILE); - glBitmap(bmapWidth, bmapHeight, 0.0, (GLfloat)metric.tmDescent, - (GLfloat)charWidth, 0.0, - bmap); - glEndList(); - /* CheckGL(); */ - - /* Destroy the bmap object */ - DeleteObject(bitObject); - - /* Deallocate the bitmap data */ - free(bmap); - } - - /* Destroy the DC */ - VERIFY(DeleteDC(bitDevice)); - - free(dibInfo); - - return TRUE; -#undef VERIFY -} - -WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsA(HDC hdc, DWORD first, - DWORD count, DWORD listBase) -{ - int i; - GLuint font_list; - DWORD size; - GLYPHMETRICS gm; - HANDLE hBits; - LPSTR lpBits; - MAT2 mat; - int success = TRUE; - - if (count == 0) - return FALSE; - - font_list = listBase; - - mat.eM11 = FixedFromDouble(1); - mat.eM12 = FixedFromDouble(0); - mat.eM21 = FixedFromDouble(0); - mat.eM22 = FixedFromDouble(-1); - - memset(&gm,0,sizeof(gm)); - - /* - ** If we can't get the glyph outline, it may be because this is a fixed - ** font. Try processing it that way. - */ - if( GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat) - == GDI_ERROR ) { - return wglUseFontBitmaps_FX( hdc, first, count, listBase ); - } - - /* - ** Otherwise process all desired characters. - */ - for (i = 0; i < (int)count; i++) { - DWORD err; - - glNewList( font_list+i, GL_COMPILE ); - - /* allocate space for the bitmap/outline */ - size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, - &gm, 0, NULL, &mat); - if (size == GDI_ERROR) { - glEndList( ); - err = GetLastError(); - success = FALSE; - continue; - } - - hBits = GlobalAlloc(GHND, size+1); - lpBits = GlobalLock(hBits); - - err = - GetGlyphOutline(hdc, /* handle to device context */ - first + i, /* character to query */ - GGO_BITMAP, /* format of data to return */ - &gm, /* ptr to structure for metrics*/ - size, /* size of buffer for data */ - lpBits, /* pointer to buffer for data */ - &mat /* pointer to transformation */ - /* matrix structure */ - ); - - if (err == GDI_ERROR) { - GlobalUnlock(hBits); - GlobalFree(hBits); - - glEndList( ); - err = GetLastError(); - success = FALSE; - continue; - } - - glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY, - (GLfloat)-gm.gmptGlyphOrigin.x, - (GLfloat)gm.gmptGlyphOrigin.y, - (GLfloat)gm.gmCellIncX, - (GLfloat)gm.gmCellIncY, - (const GLubyte * )lpBits); - - GlobalUnlock(hBits); - GlobalFree(hBits); - - glEndList( ); - } - - return success; -} - - - -/* NOT IMPLEMENTED YET */ -WINGDIAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc, - HGLRC hglrcDst, - UINT mask) -{ - (void) hglrcSrc; (void) hglrcDst; (void) mask; - return(FALSE); -} - -WINGDIAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc, - int iLayerPlane) -{ - (void) hdc; (void) iLayerPlane; - SetLastError(0); - return(NULL); -} - -WINGDIAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1, - HGLRC hglrc2) -{ - (void) hglrc1; (void) hglrc2; - return(TRUE); -} - - -WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc, - DWORD first, - DWORD count, - DWORD listBase) -{ - (void) hdc; (void) first; (void) count; (void) listBase; - return FALSE; -} - -WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc, - DWORD first, - DWORD count, - DWORD listBase, - FLOAT deviation, - FLOAT extrusion, - int format, - LPGLYPHMETRICSFLOAT lpgmf) -{ - (void) hdc; (void) first; (void) count; - (void) listBase; (void) deviation; (void) extrusion; (void) format; - (void) lpgmf; - SetLastError(0); - return(FALSE); -} - -WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc, - DWORD first, - DWORD count, - DWORD listBase, - FLOAT deviation, - FLOAT extrusion, - int format, - LPGLYPHMETRICSFLOAT lpgmf) -{ - (void) hdc; (void) first; (void) count; - (void) listBase; (void) deviation; (void) extrusion; (void) format; - (void) lpgmf; - SetLastError(0); - return(FALSE); -} - -WINGDIAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc, - int iPixelFormat, - int iLayerPlane, - UINT nBytes, - LPLAYERPLANEDESCRIPTOR plpd) -{ - (void) hdc; (void) iPixelFormat; (void) iLayerPlane; - (void) nBytes; (void) plpd; - SetLastError(0); - return(FALSE); -} - -WINGDIAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc, - int iLayerPlane, - int iStart, - int cEntries, - CONST COLORREF *pcr) -{ - (void) hdc; (void) iLayerPlane; (void) iStart; - (void) cEntries; (void) pcr; - SetLastError(0); - return(0); -} - -WINGDIAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc, - int iLayerPlane, - int iStart, - int cEntries, - COLORREF *pcr) -{ - (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr; - SetLastError(0); - return(0); -} - -WINGDIAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc, - int iLayerPlane, - BOOL bRealize) -{ - (void) hdc; (void) iLayerPlane; (void) bRealize; - SetLastError(0); - return(FALSE); -} - -WINGDIAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc, - UINT fuPlanes) -{ - (void) hdc; (void) fuPlanes; - SetLastError(0); - return(FALSE); -} - -WINGDIAPI const char * GLAPIENTRY wglGetExtensionsStringARB(HDC hdc) -{ - return "WGL_ARB_extensions_string"; -} diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c deleted file mode 100644 index ed3dd2b927..0000000000 --- a/src/gallium/winsys/gdi/wmesa.c +++ /dev/null @@ -1,823 +0,0 @@ -/* - * Windows (Win32/Win64) device driver for Mesa - * - */ - -#include "mtypes.h" -#include -#include "wmesadef.h" - -#undef Elements - -#include "pipe/p_winsys.h" -#include "pipe/p_format.h" -#include "pipe/p_context.h" -#include "pipe/p_inlines.h" -#include "util/u_memory.h" -#include "softpipe/sp_winsys.h" -#include "glapi/glapi.h" -#include "colors.h" - -extern GLvisual * -_mesa_create_visual( GLboolean rgbFlag, - GLboolean dbFlag, - GLboolean stereoFlag, - GLint redBits, - GLint greenBits, - GLint blueBits, - GLint alphaBits, - GLint indexBits, - GLint depthBits, - GLint stencilBits, - GLint accumRedBits, - GLint accumGreenBits, - GLint accumBlueBits, - GLint accumAlphaBits, - GLint numSamples ); - -/* linked list of our Framebuffers (windows) */ -WMesaFramebuffer FirstFramebuffer = NULL; - -struct wmesa_pipe_winsys -{ - struct pipe_winsys base; -}; - -/** - * Choose the pixel format for the given visual. - * This will tell the gallium driver how to pack pixel data into - * drawing surfaces. - */ -static GLuint -choose_pixel_format(GLvisual *v) -{ -#if 1 - return PIPE_FORMAT_A8R8G8B8_UNORM; -#else - if ( GET_REDMASK(v) == 0x0000ff - && GET_GREENMASK(v) == 0x00ff00 - && GET_BLUEMASK(v) == 0xff0000 - && v->BitsPerPixel == 32) { - if (CHECK_BYTE_ORDER(v)) { - /* no byteswapping needed */ - return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */; - } - else { - return PIPE_FORMAT_R8G8B8A8_UNORM; - } - } - else if ( GET_REDMASK(v) == 0xff0000 - && GET_GREENMASK(v) == 0x00ff00 - && GET_BLUEMASK(v) == 0x0000ff - && v->BitsPerPixel == 32) { - if (CHECK_BYTE_ORDER(v)) { - /* no byteswapping needed */ - return PIPE_FORMAT_A8R8G8B8_UNORM; - } - else { - return PIPE_FORMAT_B8G8R8A8_UNORM; - } - } - else if ( GET_REDMASK(v) == 0xf800 - && GET_GREENMASK(v) == 0x07e0 - && GET_BLUEMASK(v) == 0x001f - && CHECK_BYTE_ORDER(v) - && v->BitsPerPixel == 16) { - /* 5-6-5 RGB */ - return PIPE_FORMAT_R5G6B5_UNORM; - } - -printf("BITS %d\n",v->BitsPerPixel); - assert(0); - return 0; -#endif -} - -/* - * Determine the pixel format based on the pixel size. - */ -static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC) -{ - /* Only 16 and 32 bit targets are supported now */ - assert(pwfb->cColorBits == 0 || - pwfb->cColorBits == 16 || - pwfb->cColorBits == 32); - - switch(pwfb->cColorBits){ - case 8: - pwfb->pixelformat = PF_INDEX8; - break; - case 16: - pwfb->pixelformat = PF_5R6G5B; - break; - case 32: - pwfb->pixelformat = PF_8R8G8B; - break; - default: - pwfb->pixelformat = PF_BADFORMAT; - } -} - -/** - * Create a new WMesaFramebuffer object which will correspond to the - * given HDC (Window handle). - */ -WMesaFramebuffer -wmesa_new_framebuffer(HDC hdc, GLvisual *visual, GLuint width, GLuint height) -{ - WMesaFramebuffer pwfb - = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer)); - if (pwfb) { - enum pipe_format colorFormat, depthFormat, stencilFormat; - - /* determine PIPE_FORMATs for buffers */ - colorFormat = choose_pixel_format(visual); - - if (visual->depthBits == 0) - depthFormat = PIPE_FORMAT_NONE; - else if (visual->depthBits <= 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (visual->depthBits <= 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_Z32_UNORM; - - if (visual->stencilBits == 8) { - if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) - stencilFormat = depthFormat; - else - stencilFormat = PIPE_FORMAT_S8_UNORM; - } - else { - stencilFormat = PIPE_FORMAT_NONE; - } - - pwfb->stfb = st_create_framebuffer(visual, - colorFormat, depthFormat, stencilFormat, - width, height, - (void *) pwfb); - - pwfb->cColorBits = GetDeviceCaps(hdc, BITSPIXEL); - - pwfb->hDC = hdc; - /* insert at head of list */ - pwfb->next = FirstFramebuffer; - FirstFramebuffer = pwfb; - } - return pwfb; -} - -/** - * Given an hdc, free the corresponding WMesaFramebuffer - */ -void -wmesa_free_framebuffer(HDC hdc) -{ - WMesaFramebuffer pwfb, prev; - for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { - if (pwfb->hDC == hdc) - break; - prev = pwfb; - } - if (pwfb) { - if (pwfb == FirstFramebuffer) - FirstFramebuffer = pwfb->next; - else - prev->next = pwfb->next; - free(pwfb); - } -} - -/** - * Given an hdc, return the corresponding WMesaFramebuffer - */ -WMesaFramebuffer -wmesa_lookup_framebuffer(HDC hdc) -{ - WMesaFramebuffer pwfb; - for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { - if (pwfb->hDC == hdc) - return pwfb; - } - return NULL; -} - - -/** - * Given a GLframebuffer, return the corresponding WMesaFramebuffer. - */ -static WMesaFramebuffer wmesa_framebuffer(GLframebuffer *fb) -{ - return (WMesaFramebuffer) fb; -} - - -/** - * Given a GLcontext, return the corresponding WMesaContext. - */ -static WMesaContext wmesa_context(const GLcontext *ctx) -{ - return (WMesaContext) ctx; -} - -/** - * Find the width and height of the window named by hdc. - */ -static void -get_window_size(HDC hdc, GLuint *width, GLuint *height) -{ - if (WindowFromDC(hdc)) { - RECT rect; - GetClientRect(WindowFromDC(hdc), &rect); - *width = rect.right - rect.left; - *height = rect.bottom - rect.top; - } - else { /* Memory context */ - /* From contributed code - use the size of the desktop - * for the size of a memory context (?) */ - *width = GetDeviceCaps(hdc, HORZRES); - *height = GetDeviceCaps(hdc, VERTRES); - } -} - -/** - * Low-level OS/window system memory buffer - */ -struct wm_buffer -{ - struct pipe_buffer base; - boolean userBuffer; /** Is this a user-space buffer? */ - void *data; - void *mapped; -}; - -struct wmesa_surface -{ - struct pipe_surface surface; - - int no_swap; -}; - - -/** Cast wrapper */ -static INLINE struct wmesa_surface * -wmesa_surface(struct pipe_surface *ps) -{ -// assert(0); - return (struct wmesa_surface *) ps; -} - -/** - * Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque - * buffer pointer... - */ -static INLINE struct wm_buffer * -wm_buffer( struct pipe_buffer *buf ) -{ - return (struct wm_buffer *)buf; -} - - - -/* Most callbacks map direcly onto dri_bufmgr operations: - */ -static void * -wm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, - unsigned flags) -{ - struct wm_buffer *wm_buf = wm_buffer(buf); - wm_buf->mapped = wm_buf->data; - return wm_buf->mapped; -} - -static void -wm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) -{ - struct wm_buffer *wm_buf = wm_buffer(buf); - wm_buf->mapped = NULL; -} - -static void -wm_buffer_destroy(struct pipe_winsys *pws, - struct pipe_buffer *buf) -{ - struct wm_buffer *oldBuf = wm_buffer(buf); - - if (oldBuf->data) { - { - if (!oldBuf->userBuffer) { - align_free(oldBuf->data); - } - } - - oldBuf->data = NULL; - } - - free(oldBuf); -} - - -static void -wm_flush_frontbuffer(struct pipe_winsys *pws, - struct pipe_surface *surf, - void *context_private) -{ - WMesaContext pwc = context_private; - WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(pwc->hDC); - struct wm_buffer *wm_buf; - BITMAPINFO bmi, *pbmi; - - wm_buf = wm_buffer(surf->buffer); - - pbmi = &bmi; - memset(pbmi, 0, sizeof(BITMAPINFO)); - pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pbmi->bmiHeader.biWidth = pwfb->stfb->Base.Width; - pbmi->bmiHeader.biHeight= -((long)pwfb->stfb->Base.Height); - pbmi->bmiHeader.biPlanes = 1; - pbmi->bmiHeader.biBitCount = pwfb->cColorBits; - pbmi->bmiHeader.biCompression = BI_RGB; - pbmi->bmiHeader.biSizeImage = 0; - pbmi->bmiHeader.biXPelsPerMeter = 0; - pbmi->bmiHeader.biYPelsPerMeter = 0; - pbmi->bmiHeader.biClrUsed = 0; - pbmi->bmiHeader.biClrImportant = 0; - - StretchDIBits(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, wm_buf->data, pbmi, 0, SRCCOPY); -} - - - -static const char * -wm_get_name(struct pipe_winsys *pws) -{ - return "gdi"; -} - -static struct pipe_buffer * -wm_buffer_create(struct pipe_winsys *pws, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct wm_buffer *buffer = CALLOC_STRUCT(wm_buffer); - - buffer->base.refcount = 1; - buffer->base.alignment = alignment; - buffer->base.usage = usage; - buffer->base.size = size; - - if (buffer->data == NULL) { - /* align to 16-byte multiple for Cell */ - buffer->data = align_malloc(size, max(alignment, 16)); - } - - return &buffer->base; -} - - -/** - * Create buffer which wraps user-space data. - */ -static struct pipe_buffer * -wm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) -{ - struct wm_buffer *buffer = CALLOC_STRUCT(wm_buffer); - buffer->base.refcount = 1; - buffer->base.size = bytes; - buffer->userBuffer = TRUE; - buffer->data = ptr; - - return &buffer->base; -} - - - -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - -static int -wm_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, - unsigned width, unsigned height, - enum pipe_format format, - unsigned flags, - unsigned tex_usage) -{ - const unsigned alignment = 64; - - surf->width = width; - surf->height = height; - surf->format = format; - pf_get_block(format, &surf->block); - surf->nblocksx = pf_get_nblocksx(&surf->block, width); - surf->nblocksy = pf_get_nblocksy(&surf->block, height); - surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->nblocksy * surf->stride); - if(!surf->buffer) - return -1; - - return 0; -} - - -/** - * Called via winsys->surface_alloc() to create new surfaces. - */ -static struct pipe_surface * -wm_surface_alloc(struct pipe_winsys *ws) -{ - struct wmesa_surface *wms = CALLOC_STRUCT(wmesa_surface); - static boolean no_swap = 0; - static boolean firsttime = 1; - - if (firsttime) { - no_swap = getenv("SP_NO_RAST") != NULL; - firsttime = 0; - } - - assert(ws); - - wms->surface.refcount = 1; - wms->surface.winsys = ws; - - wms->no_swap = no_swap; - - return &wms->surface; -} - -static void -wm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - winsys_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; -} - - -/* - * Fence functions - basically nothing to do, as we don't create any actual - * fence objects. - */ - -static void -wm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence) -{ -} - - -static int -wm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - -static int -wm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - - -struct pipe_winsys * -wmesa_get_pipe_winsys(GLvisual *visual) -{ - static struct wmesa_pipe_winsys *ws = NULL; - - if (!ws) { - ws = CALLOC_STRUCT(wmesa_pipe_winsys); - - /* Fill in this struct with callbacks that pipe will need to - * communicate with the window system, buffer manager, etc. - */ - ws->base.buffer_create = wm_buffer_create; - ws->base.user_buffer_create = wm_user_buffer_create; - ws->base.buffer_map = wm_buffer_map; - ws->base.buffer_unmap = wm_buffer_unmap; - ws->base.buffer_destroy = wm_buffer_destroy; - - ws->base.surface_alloc = wm_surface_alloc; - ws->base.surface_alloc_storage = wm_surface_alloc_storage; - ws->base.surface_release = wm_surface_release; - - ws->base.fence_reference = wm_fence_reference; - ws->base.fence_signalled = wm_fence_signalled; - ws->base.fence_finish = wm_fence_finish; - - ws->base.flush_frontbuffer = wm_flush_frontbuffer; - ws->base.get_name = wm_get_name; - } - - return &ws->base; -} - - - -/**********************************************************************/ -/***** WMESA Functions *****/ -/**********************************************************************/ - -WMesaContext WMesaCreateContext(HDC hDC, - HPALETTE* Pal, - GLboolean rgb_flag, - GLboolean db_flag, - GLboolean alpha_flag) -{ - WMesaContext c; - struct pipe_winsys *pws; - struct pipe_context *pipe; - struct pipe_screen *screen; - GLint red_bits, green_bits, blue_bits, alpha_bits; - GLvisual *visual; - - (void) Pal; - - /* Indexed mode not supported */ - if (!rgb_flag) - return NULL; - - /* Allocate wmesa context */ - c = CALLOC_STRUCT(wmesa_context); - if (!c) - return NULL; - - c->hDC = hDC; - - /* Get data for visual */ - /* Dealing with this is actually a bit of overkill because Mesa will end - * up treating all color component size requests less than 8 by using - * a single byte per channel. In addition, the interface to the span - * routines passes colors as an entire byte per channel anyway, so there - * is nothing to be saved by telling the visual to be 16 bits if the device - * is 16 bits. That is, Mesa is going to compute colors down to 8 bits per - * channel anyway. - * But we go through the motions here anyway. - */ - c->cColorBits = GetDeviceCaps(c->hDC, BITSPIXEL); - - switch (c->cColorBits) { - case 16: - red_bits = green_bits = blue_bits = 5; - alpha_bits = 0; - break; - default: - red_bits = green_bits = blue_bits = 8; - alpha_bits = 8; - break; - } - /* Create visual based on flags */ - visual = _mesa_create_visual(rgb_flag, - db_flag, /* db_flag */ - GL_FALSE, /* stereo */ - red_bits, green_bits, blue_bits, /* color RGB */ - alpha_flag ? alpha_bits : 0, /* color A */ - 0, /* index bits */ - DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */ - 8, /* stencil_bits */ - 16,16,16, /* accum RGB */ - alpha_flag ? 16 : 0, /* accum A */ - 1); /* num samples */ - - if (!visual) { - _mesa_free(c); - return NULL; - } - - pws = wmesa_get_pipe_winsys(visual); - - screen = softpipe_create_screen(pws); - - if (!screen) { - _mesa_free(c); - return NULL; - } - - pipe = softpipe_create(screen, pws, NULL); - - if (!pipe) { - /* FIXME - free screen */ - _mesa_free(c); - return NULL; - } - - pipe->priv = c; - - c->st = st_create_context(pipe, visual, NULL); - - c->st->ctx->DriverCtx = c; - - return c; -} - - -void WMesaDestroyContext( WMesaContext pwc ) -{ - GLcontext *ctx = pwc->st->ctx; - WMesaFramebuffer pwfb; - GET_CURRENT_CONTEXT(cur_ctx); - - if (cur_ctx == ctx) { - /* unbind current if deleting current context */ - WMesaMakeCurrent(NULL, NULL); - } - - /* clean up frame buffer resources */ - pwfb = wmesa_lookup_framebuffer(pwc->hDC); - if (pwfb) { - wmesa_free_framebuffer(pwc->hDC); - } - - /* Release for device, not memory contexts */ - if (WindowFromDC(pwc->hDC) != NULL) - { - ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC); - } - - st_destroy_context(pwc->st); - _mesa_free(pwc); -} - - -void WMesaMakeCurrent(WMesaContext c, HDC hdc) -{ - GLuint width = 0, height = 0; - WMesaFramebuffer pwfb; - - { - /* return if already current */ - GET_CURRENT_CONTEXT(ctx); - WMesaContext pwc = wmesa_context(ctx); - if (pwc && c == pwc && pwc->hDC == hdc) - return; - } - - pwfb = wmesa_lookup_framebuffer(hdc); - - if (hdc) { - get_window_size(hdc, &width, &height); - } - - /* Lazy creation of framebuffers */ - if (c && !pwfb && (hdc != 0)) { - GLvisual *visual = &c->st->ctx->Visual; - - pwfb = wmesa_new_framebuffer(hdc, visual, width, height); - } - - if (c && pwfb) { - st_make_current(c->st, pwfb->stfb, pwfb->stfb); - - st_resize_framebuffer(pwfb->stfb, width, height); - } - else { - /* Detach */ - st_make_current( NULL, NULL, NULL ); - } -} - - -void WMesaSwapBuffers( HDC hdc ) -{ - struct pipe_surface *surf; - struct wm_buffer *wm_buf; - WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc); - BITMAPINFO bmi, *pbmi; - - if (!pwfb) { - _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc"); - return; - } - - - /* If we're swapping the buffer associated with the current context - * we have to flush any pending rendering commands first. - */ - st_notify_swapbuffers(pwfb->stfb); - - surf = st_get_framebuffer_surface(pwfb->stfb, ST_SURFACE_BACK_LEFT); - wm_buf = wm_buffer(surf->buffer); - - pbmi = &bmi; - memset(pbmi, 0, sizeof(BITMAPINFO)); - pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pbmi->bmiHeader.biWidth = pwfb->stfb->Base.Width; - pbmi->bmiHeader.biHeight= -((long)pwfb->stfb->Base.Height); - pbmi->bmiHeader.biPlanes = 1; - pbmi->bmiHeader.biBitCount = pwfb->cColorBits; - pbmi->bmiHeader.biCompression = BI_RGB; - pbmi->bmiHeader.biSizeImage = 0; - pbmi->bmiHeader.biXPelsPerMeter = 0; - pbmi->bmiHeader.biYPelsPerMeter = 0; - pbmi->bmiHeader.biClrUsed = 0; - pbmi->bmiHeader.biClrImportant = 0; - - StretchDIBits(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, wm_buf->data, pbmi, 0, SRCCOPY); - - { - GLuint width = 0, height = 0; - - get_window_size(pwfb->hDC, &width, &height); - - st_resize_framebuffer(pwfb->stfb, width, height); - } -} - -/* This is hopefully a temporary hack to define some needed dispatch - * table entries. Hopefully, I'll find a better solution. The - * dispatch table generation scripts ought to be making these dummy - * stubs as well. */ -#if !defined(__MINGW32__) || !defined(GL_NO_STDCALL) -void gl_dispatch_stub_543(void){} -void gl_dispatch_stub_544(void){} -void gl_dispatch_stub_545(void){} -void gl_dispatch_stub_546(void){} -void gl_dispatch_stub_547(void){} -void gl_dispatch_stub_548(void){} -void gl_dispatch_stub_549(void){} -void gl_dispatch_stub_550(void){} -void gl_dispatch_stub_551(void){} -void gl_dispatch_stub_552(void){} -void gl_dispatch_stub_553(void){} -void gl_dispatch_stub_554(void){} -void gl_dispatch_stub_555(void){} -void gl_dispatch_stub_556(void){} -void gl_dispatch_stub_557(void){} -void gl_dispatch_stub_558(void){} -void gl_dispatch_stub_559(void){} -void gl_dispatch_stub_560(void){} -void gl_dispatch_stub_561(void){} -void gl_dispatch_stub_565(void){} -void gl_dispatch_stub_566(void){} -void gl_dispatch_stub_577(void){} -void gl_dispatch_stub_578(void){} -void gl_dispatch_stub_603(void){} -void gl_dispatch_stub_645(void){} -void gl_dispatch_stub_646(void){} -void gl_dispatch_stub_647(void){} -void gl_dispatch_stub_648(void){} -void gl_dispatch_stub_649(void){} -void gl_dispatch_stub_650(void){} -void gl_dispatch_stub_651(void){} -void gl_dispatch_stub_652(void){} -void gl_dispatch_stub_653(void){} -void gl_dispatch_stub_733(void){} -void gl_dispatch_stub_734(void){} -void gl_dispatch_stub_735(void){} -void gl_dispatch_stub_736(void){} -void gl_dispatch_stub_737(void){} -void gl_dispatch_stub_738(void){} -void gl_dispatch_stub_744(void){} -void gl_dispatch_stub_745(void){} -void gl_dispatch_stub_746(void){} -void gl_dispatch_stub_760(void){} -void gl_dispatch_stub_761(void){} -void gl_dispatch_stub_763(void){} -void gl_dispatch_stub_765(void){} -void gl_dispatch_stub_766(void){} -void gl_dispatch_stub_767(void){} -void gl_dispatch_stub_768(void){} - -void gl_dispatch_stub_562(void){} -void gl_dispatch_stub_563(void){} -void gl_dispatch_stub_564(void){} -void gl_dispatch_stub_567(void){} -void gl_dispatch_stub_568(void){} -void gl_dispatch_stub_569(void){} -void gl_dispatch_stub_580(void){} -void gl_dispatch_stub_581(void){} -void gl_dispatch_stub_606(void){} -void gl_dispatch_stub_654(void){} -void gl_dispatch_stub_655(void){} -void gl_dispatch_stub_656(void){} -void gl_dispatch_stub_739(void){} -void gl_dispatch_stub_740(void){} -void gl_dispatch_stub_741(void){} -void gl_dispatch_stub_748(void){} -void gl_dispatch_stub_749(void){} -void gl_dispatch_stub_769(void){} -void gl_dispatch_stub_770(void){} -void gl_dispatch_stub_771(void){} -void gl_dispatch_stub_772(void){} -void gl_dispatch_stub_773(void){} - -#endif diff --git a/src/gallium/winsys/gdi/wmesadef.h b/src/gallium/winsys/gdi/wmesadef.h deleted file mode 100644 index fb8ce30a08..0000000000 --- a/src/gallium/winsys/gdi/wmesadef.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef WMESADEF_H -#define WMESADEF_H -#ifdef __MINGW32__ -#include -#endif -#if 0 -#include "context.h" -#endif -#include "state_tracker/st_context.h" -#include "state_tracker/st_public.h" - - -/** - * The Windows Mesa rendering context, derived from GLcontext. - */ -struct wmesa_context { - struct st_context *st; - HDC hDC; - BYTE cColorBits; -}; - -/** - * Windows framebuffer, derived from gl_framebuffer - */ -struct wmesa_framebuffer -{ - struct st_framebuffer *stfb; - HDC hDC; - int pixelformat; - BYTE cColorBits; - HDC dib_hDC; - HBITMAP hbmDIB; - HBITMAP hOldBitmap; - PBYTE pbPixels; - struct wmesa_framebuffer *next; -}; - -typedef struct wmesa_framebuffer *WMesaFramebuffer; - -#endif /* WMESADEF_H */ -- cgit v1.2.3 From 6b88d9606f5cc8147b9ef13c70a9416313c52205 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 17 Dec 2008 10:55:29 -0700 Subject: winsys: fix depth buffer size when using stencil --- src/gallium/winsys/xlib/fakeglx.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c index a56e63572a..fd2d222c85 100644 --- a/src/gallium/winsys/xlib/fakeglx.c +++ b/src/gallium/winsys/xlib/fakeglx.c @@ -304,6 +304,9 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, return NULL; } + if (stencil_size > 0 && depth_size > 0) + depth_size = 24; + /* Comparing IDs uses less memory but sometimes fails. */ /* XXX revisit this after 3.0 is finished. */ if (_mesa_getenv("MESA_GLX_VISUAL_HACK")) -- cgit v1.2.3 From 93afa779453e69951b168e8ecb7b6ddef53eb8b0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 19 Dec 2008 08:01:03 -0700 Subject: cell: fix build breakage --- src/gallium/winsys/xlib/xm_winsys_aub.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index b7c10b6bca..56e16a0fb4 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -560,6 +560,9 @@ static void aub_i965_buffer_subdata_typed(struct brw_winsys *winsys, struct pipe_context * xmesa_create_i965simple( struct pipe_winsys *winsys ) { +#ifdef GALLIUM_CELL + return NULL; +#else struct aub_brw_winsys *iws = CALLOC_STRUCT( aub_brw_winsys ); struct pipe_screen *screen = brw_create_screen(winsys, 0/* XXX pci_id */); @@ -583,4 +586,5 @@ xmesa_create_i965simple( struct pipe_winsys *winsys ) return brw_create( screen, &iws->winsys, 0 ); +#endif } -- cgit v1.2.3 From ce8469abeb8d48d84a77f3ddd1664d9f98d7d620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 11 Dec 2008 14:42:25 +0900 Subject: gdi: Cleanup sconsfile. --- src/gallium/winsys/gdi/SConscript | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript index b463fa6505..fdcdde101a 100644 --- a/src/gallium/winsys/gdi/SConscript +++ b/src/gallium/winsys/gdi/SConscript @@ -12,6 +12,15 @@ if env['platform'] == 'windows': ]) env.Append(CPPDEFINES = [ + '__GL_EXPORTS', + 'BUILD_GL32', + '_GNU_H_WINDOWS32_DEFINES', + ]) + + env.Append(LIBS = [ + 'gdi32', + 'user32',ss + 'kernel32', ]) sources = [ @@ -23,11 +32,6 @@ if env['platform'] == 'windows': softpipe, ] - env.Append(LIBS = [ - 'gdi32', - 'user32' - ]) - env.SharedLibrary( target ='opengl32', source = sources, -- cgit v1.2.3 From 8e63beff5608aca67cf55978e03c53b3fcbca5c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 30 Dec 2008 16:35:46 +0000 Subject: gdi: Remove accidental keypresses. --- src/gallium/winsys/gdi/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript index fdcdde101a..e68d5db7f4 100644 --- a/src/gallium/winsys/gdi/SConscript +++ b/src/gallium/winsys/gdi/SConscript @@ -19,7 +19,7 @@ if env['platform'] == 'windows': env.Append(LIBS = [ 'gdi32', - 'user32',ss + 'user32', 'kernel32', ]) -- cgit v1.2.3 From e59eb5fc969777ea9590af3710c3ec9373ce043b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 6 Jan 2009 16:22:54 +0000 Subject: gdi: Fix warning. --- src/gallium/winsys/gdi/gdi_softpipe_winsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c index e66ce48f2d..cb74b54742 100644 --- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -320,7 +320,7 @@ gdi_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, memset(&bmi, 0, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = surface->stride / pf_get_size(surface->format); - bmi.bmiHeader.biHeight= -surface->height; + bmi.bmiHeader.biHeight= -(long)surface->height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = pf_get_bits(surface->format); bmi.bmiHeader.biCompression = BI_RGB; -- cgit v1.2.3 From 73d02d70b8c98c0e64e7816795565ed5f5bf3639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 6 Jan 2009 16:45:12 +0000 Subject: wgl: Do not provide DllMain inside the state tracker. MS CRT libraries already provide a default DllMain entrypoint, and MS Linker will complain if it finds the same symbol in two different libraries. Therefore the DllMain has to be in (each) winsys. --- src/gallium/winsys/gdi/gdi_softpipe_winsys.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c index cb74b54742..e981b4c5cd 100644 --- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -337,8 +337,23 @@ gdi_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, } -const struct stw_winsys stw_winsys = { +static const struct stw_winsys stw_winsys = { &gdi_softpipe_screen_create, &gdi_softpipe_context_create, &gdi_softpipe_flush_frontbuffer }; + + +BOOL WINAPI +DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) +{ + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + return st_init(&stw_winsys); + + case DLL_PROCESS_DETACH: + st_cleanup(); + break; + } + return TRUE; +} \ No newline at end of file -- cgit v1.2.3 From 500e05d437adb14e9dd5e36b07f1b7554ba9563e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 8 Jan 2009 12:42:00 +0000 Subject: gdi: Add newline at end of file. --- src/gallium/winsys/gdi/gdi_softpipe_winsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c index e981b4c5cd..bd5aa10a20 100644 --- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -356,4 +356,4 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) break; } return TRUE; -} \ No newline at end of file +} -- cgit v1.2.3 From 002dfb12fce045d0e124301e5df805df772149d8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 8 Jan 2009 14:10:56 +0000 Subject: gallium: split driver-independent code out of xlib winsys Place in new xlib state-tracker. This is a statetracker for the GLX API. --- src/gallium/winsys/xlib/Makefile | 16 +- src/gallium/winsys/xlib/brw_aub.c | 397 ---- src/gallium/winsys/xlib/brw_aub.h | 114 - src/gallium/winsys/xlib/fakeglx.c | 3215 ---------------------------- src/gallium/winsys/xlib/glxapi.c | 1390 ------------ src/gallium/winsys/xlib/glxapi.h | 228 -- src/gallium/winsys/xlib/glxheader.h | 62 - src/gallium/winsys/xlib/realglx.c | 180 -- src/gallium/winsys/xlib/realglx.h | 326 --- src/gallium/winsys/xlib/xfonts.c | 377 ---- src/gallium/winsys/xlib/xfonts.h | 41 - src/gallium/winsys/xlib/xlib.c | 165 ++ src/gallium/winsys/xlib/xlib_brw.h | 40 + src/gallium/winsys/xlib/xlib_brw_aub.c | 397 ++++ src/gallium/winsys/xlib/xlib_brw_aub.h | 114 + src/gallium/winsys/xlib/xlib_brw_context.c | 205 ++ src/gallium/winsys/xlib/xlib_brw_screen.c | 470 ++++ src/gallium/winsys/xlib/xlib_softpipe.c | 744 +++++++ src/gallium/winsys/xlib/xlib_softpipe.h | 50 + src/gallium/winsys/xlib/xlib_trace.c | 102 + src/gallium/winsys/xlib/xlib_trace.h | 26 + src/gallium/winsys/xlib/xm_api.c | 1422 ------------ src/gallium/winsys/xlib/xm_image.c | 133 -- src/gallium/winsys/xlib/xm_image.h | 77 - src/gallium/winsys/xlib/xm_winsys.c | 719 ------- src/gallium/winsys/xlib/xm_winsys_aub.c | 590 ----- src/gallium/winsys/xlib/xm_winsys_aub.h | 68 - src/gallium/winsys/xlib/xmesaP.h | 180 -- 28 files changed, 2322 insertions(+), 9526 deletions(-) delete mode 100644 src/gallium/winsys/xlib/brw_aub.c delete mode 100644 src/gallium/winsys/xlib/brw_aub.h delete mode 100644 src/gallium/winsys/xlib/fakeglx.c delete mode 100644 src/gallium/winsys/xlib/glxapi.c delete mode 100644 src/gallium/winsys/xlib/glxapi.h delete mode 100644 src/gallium/winsys/xlib/glxheader.h delete mode 100644 src/gallium/winsys/xlib/realglx.c delete mode 100644 src/gallium/winsys/xlib/realglx.h delete mode 100644 src/gallium/winsys/xlib/xfonts.c delete mode 100644 src/gallium/winsys/xlib/xfonts.h create mode 100644 src/gallium/winsys/xlib/xlib.c create mode 100644 src/gallium/winsys/xlib/xlib_brw.h create mode 100644 src/gallium/winsys/xlib/xlib_brw_aub.c create mode 100644 src/gallium/winsys/xlib/xlib_brw_aub.h create mode 100644 src/gallium/winsys/xlib/xlib_brw_context.c create mode 100644 src/gallium/winsys/xlib/xlib_brw_screen.c create mode 100644 src/gallium/winsys/xlib/xlib_softpipe.c create mode 100644 src/gallium/winsys/xlib/xlib_softpipe.h create mode 100644 src/gallium/winsys/xlib/xlib_trace.c create mode 100644 src/gallium/winsys/xlib/xlib_trace.h delete mode 100644 src/gallium/winsys/xlib/xm_api.c delete mode 100644 src/gallium/winsys/xlib/xm_image.c delete mode 100644 src/gallium/winsys/xlib/xm_image.h delete mode 100644 src/gallium/winsys/xlib/xm_winsys.c delete mode 100644 src/gallium/winsys/xlib/xm_winsys_aub.c delete mode 100644 src/gallium/winsys/xlib/xm_winsys_aub.h delete mode 100644 src/gallium/winsys/xlib/xmesaP.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 11c7632411..129d038d4f 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -19,16 +19,17 @@ INCLUDE_DIRS = \ -I$(TOP)/src/mesa/main \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/state_trackers/xlib \ -I$(TOP)/src/gallium/auxiliary XLIB_WINSYS_SOURCES = \ - glxapi.c \ - fakeglx.c \ - xfonts.c \ - xm_api.c \ - xm_winsys.c \ - xm_winsys_aub.c \ - brw_aub.c + xlib.c \ + xlib_brw_aub.c \ + xlib_brw_context.c \ + xlib_brw_screen.c \ + xlib_softpipe.c \ + xlib_trace.c + XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o) @@ -63,6 +64,7 @@ $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \ + $(TOP)/src/gallium/state_trackers/xlib/*.o \ --start-group $(LIBS) --end-group $(GL_LIB_DEPS) diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c deleted file mode 100644 index 9e96efaa53..0000000000 --- a/src/gallium/winsys/xlib/brw_aub.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - 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, sublicense, 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 NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#include -#include -#include "brw_aub.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "pipe/p_debug.h" -#include "util/u_memory.h" - - -struct brw_aubfile { - FILE *file; - unsigned next_free_page; -}; - - -extern char *__progname; - - -struct aub_file_header { - unsigned int instruction_type; - unsigned int pad0:16; - unsigned int minor:8; - unsigned int major:8; - unsigned char application[8*4]; - unsigned int day:8; - unsigned int month:8; - unsigned int year:16; - unsigned int timezone:8; - unsigned int second:8; - unsigned int minute:8; - unsigned int hour:8; - unsigned int comment_length:16; - unsigned int pad1:16; -}; - -struct aub_block_header { - unsigned int instruction_type; - unsigned int operation:8; - unsigned int type:8; - unsigned int address_space:8; - unsigned int pad0:8; - unsigned int general_state_type:8; - unsigned int surface_state_type:8; - unsigned int pad1:16; - unsigned int address; - unsigned int length; -}; - -struct aub_dump_bmp { - unsigned int instruction_type; - unsigned int xmin:16; - unsigned int ymin:16; - unsigned int pitch:16; - unsigned int bpp:8; - unsigned int format:8; - unsigned int xsize:16; - unsigned int ysize:16; - unsigned int addr; - unsigned int unknown; -}; - -enum bh_operation { - BH_COMMENT, - BH_DATA_WRITE, - BH_COMMAND_WRITE, - BH_MMI0_WRITE32, - BH_END_SCENE, - BH_CONFIG_MEMORY_MAP, - BH_MAX_OPERATION -}; - -enum command_write_type { - CW_HWB_RING = 1, - CW_PRIMARY_RING_A, - CW_PRIMARY_RING_B, /* XXX - disagreement with listaub! */ - CW_PRIMARY_RING_C, - CW_MAX_TYPE -}; - -enum memory_map_type { - MM_DEFAULT, - MM_DYNAMIC, - MM_MAX_TYPE -}; - -enum address_space { - ADDR_GTT, - ADDR_LOCAL, - ADDR_MAIN, - ADDR_MAX -}; - - -#define AUB_FILE_HEADER 0xe085000b -#define AUB_BLOCK_HEADER 0xe0c10003 -#define AUB_DUMP_BMP 0xe09e0004 - -/* Registers to control page table - */ -#define PGETBL_CTL 0x2020 -#define PGETBL_ENABLED 0x1 - -#define NR_GTT_ENTRIES 65536 /* 256 mb */ - -#define FAIL \ -do { \ - fprintf(stderr, "failed to write aub data at %s/%d\n", __FUNCTION__, __LINE__); \ - exit(1); \ -} while (0) - - -/* Emit the headers at the top of each aubfile. Initialize the GTT. - */ -static void init_aubfile( FILE *aub_file ) -{ - struct aub_file_header fh; - struct aub_block_header bh; - unsigned int data; - - static int nr; - - nr++; - - /* Emit the aub header: - */ - memset(&fh, 0, sizeof(fh)); - - fh.instruction_type = AUB_FILE_HEADER; - fh.minor = 0x0; - fh.major = 0x7; - memcpy(fh.application, __progname, sizeof(fh.application)); - fh.day = (nr>>24) & 0xff; - fh.month = 0x0; - fh.year = 0x0; - fh.timezone = 0x0; - fh.second = nr & 0xff; - fh.minute = (nr>>8) & 0xff; - fh.hour = (nr>>16) & 0xff; - fh.comment_length = 0x0; - - if (fwrite(&fh, sizeof(fh), 1, aub_file) < 0) - FAIL; - - /* Setup the GTT starting at main memory address zero (!): - */ - memset(&bh, 0, sizeof(bh)); - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_MMI0_WRITE32; - bh.type = 0x0; - bh.address_space = ADDR_GTT; /* ??? */ - bh.general_state_type = 0x0; - bh.surface_state_type = 0x0; - bh.address = PGETBL_CTL; - bh.length = 0x4; - - if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) - FAIL; - - data = 0x0 | PGETBL_ENABLED; - - if (fwrite(&data, sizeof(data), 1, aub_file) < 0) - FAIL; -} - - -static void init_aub_gtt( struct brw_aubfile *aubfile, - unsigned start_offset, - unsigned size ) -{ - FILE *aub_file = aubfile->file; - struct aub_block_header bh; - unsigned int i; - - assert(start_offset + size < NR_GTT_ENTRIES * 4096); - - - memset(&bh, 0, sizeof(bh)); - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_DATA_WRITE; - bh.type = 0x0; - bh.address_space = ADDR_MAIN; - bh.general_state_type = 0x0; - bh.surface_state_type = 0x0; - bh.address = start_offset / 4096 * 4; - bh.length = size / 4096 * 4; - - if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) - FAIL; - - for (i = 0; i < size / 4096; i++) { - unsigned data = aubfile->next_free_page | 1; - - aubfile->next_free_page += 4096; - - if (fwrite(&data, sizeof(data), 1, aub_file) < 0) - FAIL; - } - -} - -static void write_block_header( FILE *aub_file, - struct aub_block_header *bh, - const unsigned *data, - unsigned sz ) -{ - sz = (sz + 3) & ~3; - - if (fwrite(bh, sizeof(*bh), 1, aub_file) < 0) - FAIL; - - if (fwrite(data, sz, 1, aub_file) < 0) - FAIL; - - fflush(aub_file); -} - - -static void write_dump_bmp( FILE *aub_file, - struct aub_dump_bmp *db ) -{ - if (fwrite(db, sizeof(*db), 1, aub_file) < 0) - FAIL; - - fflush(aub_file); -} - - - -void brw_aub_gtt_data( struct brw_aubfile *aubfile, - unsigned offset, - const void *data, - unsigned sz, - unsigned type, - unsigned state_type ) -{ - struct aub_block_header bh; - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_DATA_WRITE; - bh.type = type; - bh.address_space = ADDR_GTT; - bh.pad0 = 0; - - if (type == DW_GENERAL_STATE) { - bh.general_state_type = state_type; - bh.surface_state_type = 0; - } - else { - bh.general_state_type = 0; - bh.surface_state_type = state_type; - } - - bh.pad1 = 0; - bh.address = offset; - bh.length = sz; - - write_block_header(aubfile->file, &bh, data, sz); -} - - - -void brw_aub_gtt_cmds( struct brw_aubfile *aubfile, - unsigned offset, - const void *data, - unsigned sz ) -{ - struct aub_block_header bh; - unsigned type = CW_PRIMARY_RING_A; - - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_COMMAND_WRITE; - bh.type = type; - bh.address_space = ADDR_GTT; - bh.pad0 = 0; - bh.general_state_type = 0; - bh.surface_state_type = 0; - bh.pad1 = 0; - bh.address = offset; - bh.length = sz; - - write_block_header(aubfile->file, &bh, data, sz); -} - -void brw_aub_dump_bmp( struct brw_aubfile *aubfile, - struct pipe_surface *surface, - unsigned gtt_offset ) -{ - struct aub_dump_bmp db; - unsigned format; - - assert(surface->block.width == 1); - assert(surface->block.height == 1); - - if (surface->block.size == 4) - format = 0x7; - else - format = 0x3; - - db.instruction_type = AUB_DUMP_BMP; - db.xmin = 0; - db.ymin = 0; - db.format = format; - db.bpp = surface->block.size * 8; - db.pitch = surface->stride/surface->block.size; - db.xsize = surface->width; - db.ysize = surface->height; - db.addr = gtt_offset; - db.unknown = /* surface->tiled ? 0x4 : */ 0x0; - - write_dump_bmp(aubfile->file, &db); -} - - - -struct brw_aubfile *brw_aubfile_create( void ) -{ - struct brw_aubfile *aubfile = CALLOC_STRUCT(brw_aubfile); - char filename[80]; - int val; - static int i = 0; - - i++; - - if (getenv("INTEL_AUBFILE")) { - val = snprintf(filename, sizeof(filename), "%s%d.aub", getenv("INTEL_AUBFILE"), i%4); - debug_printf("--> Aub file: %s\n", filename); - aubfile->file = fopen(filename, "w"); - } - else { - val = snprintf(filename, sizeof(filename), "%s.aub", __progname); - if (val < 0 || val > sizeof(filename)) - strcpy(filename, "default.aub"); - - debug_printf("--> Aub file: %s\n", filename); - aubfile->file = fopen(filename, "w"); - } - - if (!aubfile->file) { - debug_printf("couldn't open aubfile\n"); - exit(1); - } - - init_aubfile(aubfile->file); - - /* The GTT is located starting address zero in main memory. Pages - * to populate the gtt start after this point. - */ - aubfile->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095; - - /* More or less correspond with all the agp regions mapped by the - * driver: - */ - init_aub_gtt(aubfile, 0, 4096*4); - init_aub_gtt(aubfile, AUB_BUF_START, AUB_BUF_SIZE); - - return aubfile; -} - -void brw_aub_destroy( struct brw_aubfile *aubfile ) -{ - fclose(aubfile->file); - FREE(aubfile); -} diff --git a/src/gallium/winsys/xlib/brw_aub.h b/src/gallium/winsys/xlib/brw_aub.h deleted file mode 100644 index f5c60c7be2..0000000000 --- a/src/gallium/winsys/xlib/brw_aub.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - 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, sublicense, 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 NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#ifndef BRW_AUB_H -#define BRW_AUB_H - -/* We set up this region, buffers may be allocated here: - */ -#define AUB_BUF_START (4096*4) -#define AUB_BUF_SIZE (8*1024*1024) - -struct intel_context; -struct pipe_surface; - -struct brw_aubfile *brw_aubfile_create( void ); - -void brw_aub_destroy( struct brw_aubfile *aubfile ); - -void brw_aub_gtt_data( struct brw_aubfile *aubfile, - unsigned offset, - const void *data, - unsigned sz, - unsigned type, - unsigned state_type ); - -void brw_aub_gtt_cmds( struct brw_aubfile *aubfile, - unsigned offset, - const void *data, - unsigned sz ); - -void brw_aub_dump_bmp( struct brw_aubfile *aubfile, - struct pipe_surface *surface, - unsigned gtt_offset ); - - -enum data_write_type { - DW_NOTYPE, - DW_BATCH_BUFFER, - DW_BIN_BUFFER, - DW_BIN_POINTER_LIST, - DW_SLOW_STATE_BUFFER, - DW_VERTEX_BUFFER, - DW_2D_MAP, - DW_CUBE_MAP, - DW_INDIRECT_STATE_BUFFER, - DW_VOLUME_MAP, - DW_1D_MAP, - DW_CONSTANT_BUFFER, - DW_CONSTANT_URB_ENTRY, - DW_INDEX_BUFFER, - DW_GENERAL_STATE, - DW_SURFACE_STATE, - DW_MEDIA_OBJECT_INDIRECT_DATA, - DW_MAX_TYPE -}; - -enum data_write_general_state_type { - DWGS_NOTYPE, - DWGS_VERTEX_SHADER_STATE, - DWGS_GEOMETRY_SHADER_STATE , - DWGS_CLIPPER_STATE, - DWGS_STRIPS_FANS_STATE, - DWGS_WINDOWER_IZ_STATE, - DWGS_COLOR_CALC_STATE, - DWGS_CLIPPER_VIEWPORT_STATE, /* was 0x7 */ - DWGS_STRIPS_FANS_VIEWPORT_STATE, - DWGS_COLOR_CALC_VIEWPORT_STATE, /* was 0x9 */ - DWGS_SAMPLER_STATE, - DWGS_KERNEL_INSTRUCTIONS, - DWGS_SCRATCH_SPACE, - DWGS_SAMPLER_DEFAULT_COLOR, - DWGS_INTERFACE_DESCRIPTOR, - DWGS_VLD_STATE, - DWGS_VFE_STATE, - DWGS_MAX_TYPE -}; - -enum data_write_surface_state_type { - DWSS_NOTYPE, - DWSS_BINDING_TABLE_STATE, - DWSS_SURFACE_STATE, - DWSS_MAX_TYPE -}; - - -#endif diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c deleted file mode 100644 index fd2d222c85..0000000000 --- a/src/gallium/winsys/xlib/fakeglx.c +++ /dev/null @@ -1,3215 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 1999-2007 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - - -/* - * This is an emulation of the GLX API which allows Mesa/GLX-based programs - * to run on X servers which do not have the real GLX extension. - * - * Thanks to the contributors: - * - * Initial version: Philip Brown (phil@bolthole.com) - * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu) - * Further visual-handling refinements: Wolfram Gloger - * (wmglo@Dent.MED.Uni-Muenchen.DE). - * - * Notes: - * Don't be fooled, stereo isn't supported yet. - */ - - - -#include "glxheader.h" -#include "glxapi.h" -#include "GL/xmesa.h" -#include "context.h" -#include "config.h" -#include "macros.h" -#include "imports.h" -#include "mtypes.h" -#include "version.h" -#include "xfonts.h" -#include "xmesaP.h" -#include "state_tracker/st_context.h" -#include "state_tracker/st_public.h" - - -#ifdef __VMS -#define _mesa_sprintf sprintf -#endif - -/* This indicates the client-side GLX API and GLX encoder version. */ -#define CLIENT_MAJOR_VERSION 1 -#define CLIENT_MINOR_VERSION 4 /* but don't have 1.3's pbuffers, etc yet */ - -/* This indicates the server-side GLX decoder version. - * GLX 1.4 indicates OpenGL 1.3 support - */ -#define SERVER_MAJOR_VERSION 1 -#define SERVER_MINOR_VERSION 4 - -/* This is appended onto the glXGetClient/ServerString version strings. */ -#define MESA_GLX_VERSION "Mesa " MESA_VERSION_STRING - -/* Who implemented this GLX? */ -#define VENDOR "Brian Paul" - -#define EXTENSIONS \ - "GLX_MESA_set_3dfx_mode " \ - "GLX_MESA_copy_sub_buffer " \ - "GLX_MESA_pixmap_colormap " \ - "GLX_MESA_release_buffers " \ - "GLX_ARB_get_proc_address " \ - "GLX_EXT_texture_from_pixmap " \ - "GLX_EXT_visual_info " \ - "GLX_EXT_visual_rating " \ - /*"GLX_SGI_video_sync "*/ \ - "GLX_SGIX_fbconfig " \ - "GLX_SGIX_pbuffer " - -/* - * Our fake GLX context will contain a "real" GLX context and an XMesa context. - * - * Note that a pointer to a __GLXcontext is a pointer to a fake_glx_context, - * and vice versa. - * - * We really just need this structure in order to make the libGL functions - * glXGetCurrentContext(), glXGetCurrentDrawable() and glXGetCurrentDisplay() - * work correctly. - */ -struct fake_glx_context { - __GLXcontext glxContext; /* this MUST be first! */ - XMesaContext xmesaContext; -}; - - - -/**********************************************************************/ -/*** GLX Visual Code ***/ -/**********************************************************************/ - -#define DONT_CARE -1 - - -static XMesaVisual *VisualTable = NULL; -static int NumVisuals = 0; - - -/* - * This struct and some code fragments borrowed - * from Mark Kilgard's GLUT library. - */ -typedef struct _OverlayInfo { - /* Avoid 64-bit portability problems by being careful to use - longs due to the way XGetWindowProperty is specified. Note - that these parameters are passed as CARD32s over X - protocol. */ - unsigned long overlay_visual; - long transparent_type; - long value; - long layer; -} OverlayInfo; - - - -/* Macro to handle c_class vs class field name in XVisualInfo struct */ -#if defined(__cplusplus) || defined(c_plusplus) -#define CLASS c_class -#else -#define CLASS class -#endif - - - -/* - * Test if the given XVisualInfo is usable for Mesa rendering. - */ -static GLboolean -is_usable_visual( XVisualInfo *vinfo ) -{ - switch (vinfo->CLASS) { - case StaticGray: - case GrayScale: - /* Any StaticGray/GrayScale visual works in RGB or CI mode */ - return GL_TRUE; - case StaticColor: - case PseudoColor: - /* Any StaticColor/PseudoColor visual of at least 4 bits */ - if (vinfo->depth>=4) { - return GL_TRUE; - } - else { - return GL_FALSE; - } - case TrueColor: - case DirectColor: - /* Any depth of TrueColor or DirectColor works in RGB mode */ - return GL_TRUE; - default: - /* This should never happen */ - return GL_FALSE; - } -} - - - -/** - * Get an array OverlayInfo records for specified screen. - * \param dpy the display - * \param screen screen number - * \param numOverlays returns numver of OverlayInfo records - * \return pointer to OverlayInfo array, free with XFree() - */ -static OverlayInfo * -GetOverlayInfo(Display *dpy, int screen, int *numOverlays) -{ - Atom overlayVisualsAtom; - Atom actualType; - Status status; - unsigned char *ovInfo; - unsigned long sizeData, bytesLeft; - int actualFormat; - - /* - * The SERVER_OVERLAY_VISUALS property on the root window contains - * a list of overlay visuals. Get that list now. - */ - overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True); - if (overlayVisualsAtom == None) { - return 0; - } - - status = XGetWindowProperty(dpy, RootWindow(dpy, screen), - overlayVisualsAtom, 0L, (long) 10000, False, - overlayVisualsAtom, &actualType, &actualFormat, - &sizeData, &bytesLeft, - &ovInfo); - - if (status != Success || actualType != overlayVisualsAtom || - actualFormat != 32 || sizeData < 4) { - /* something went wrong */ - XFree((void *) ovInfo); - *numOverlays = 0; - return NULL; - } - - *numOverlays = sizeData / 4; - return (OverlayInfo *) ovInfo; -} - - - -/** - * Return the level (overlay, normal, underlay) of a given XVisualInfo. - * Input: dpy - the X display - * vinfo - the XVisualInfo to test - * Return: level of the visual: - * 0 = normal planes - * >0 = overlay planes - * <0 = underlay planes - */ -static int -level_of_visual( Display *dpy, XVisualInfo *vinfo ) -{ - OverlayInfo *overlay_info; - int numOverlaysPerScreen, i; - - overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); - if (!overlay_info) { - return 0; - } - - /* search the overlay visual list for the visual ID of interest */ - for (i = 0; i < numOverlaysPerScreen; i++) { - const OverlayInfo *ov = overlay_info + i; - if (ov->overlay_visual == vinfo->visualid) { - /* found the visual */ - if (/*ov->transparent_type==1 &&*/ ov->layer!=0) { - int level = ov->layer; - XFree((void *) overlay_info); - return level; - } - else { - XFree((void *) overlay_info); - return 0; - } - } - } - - /* The visual ID was not found in the overlay list. */ - XFree((void *) overlay_info); - return 0; -} - - - - -/* - * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the - * configuration in our list of GLX visuals. - */ -static XMesaVisual -save_glx_visual( Display *dpy, XVisualInfo *vinfo, - GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag, - GLboolean stereoFlag, - GLint depth_size, GLint stencil_size, - GLint accumRedSize, GLint accumGreenSize, - GLint accumBlueSize, GLint accumAlphaSize, - GLint level, GLint numAuxBuffers ) -{ - GLboolean ximageFlag = GL_TRUE; - XMesaVisual xmvis; - GLint i; - GLboolean comparePointers; - - if (dbFlag) { - /* Check if the MESA_BACK_BUFFER env var is set */ - char *backbuffer = _mesa_getenv("MESA_BACK_BUFFER"); - if (backbuffer) { - if (backbuffer[0]=='p' || backbuffer[0]=='P') { - ximageFlag = GL_FALSE; - } - else if (backbuffer[0]=='x' || backbuffer[0]=='X') { - ximageFlag = GL_TRUE; - } - else { - _mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage."); - } - } - } - - if (stereoFlag) { - /* stereo not supported */ - return NULL; - } - - if (stencil_size > 0 && depth_size > 0) - depth_size = 24; - - /* Comparing IDs uses less memory but sometimes fails. */ - /* XXX revisit this after 3.0 is finished. */ - if (_mesa_getenv("MESA_GLX_VISUAL_HACK")) - comparePointers = GL_TRUE; - else - comparePointers = GL_FALSE; - - /* Force the visual to have an alpha channel */ - if (rgbFlag && _mesa_getenv("MESA_GLX_FORCE_ALPHA")) - alphaFlag = GL_TRUE; - - /* First check if a matching visual is already in the list */ - for (i=0; idisplay == dpy - && v->mesa_visual.level == level - && v->mesa_visual.numAuxBuffers == numAuxBuffers - && v->ximage_flag == ximageFlag - && v->mesa_visual.rgbMode == rgbFlag - && v->mesa_visual.doubleBufferMode == dbFlag - && v->mesa_visual.stereoMode == stereoFlag - && (v->mesa_visual.alphaBits > 0) == alphaFlag - && (v->mesa_visual.depthBits >= depth_size || depth_size == 0) - && (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0) - && (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0) - && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0) - && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0) - && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) { - /* now either compare XVisualInfo pointers or visual IDs */ - if ((!comparePointers && v->visinfo->visualid == vinfo->visualid) - || (comparePointers && v->vishandle == vinfo)) { - return v; - } - } - } - - /* Create a new visual and add it to the list. */ - - xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag, - stereoFlag, ximageFlag, - depth_size, stencil_size, - accumRedSize, accumBlueSize, - accumBlueSize, accumAlphaSize, 0, level, - GLX_NONE_EXT ); - if (xmvis) { - /* Save a copy of the pointer now so we can find this visual again - * if we need to search for it in find_glx_visual(). - */ - xmvis->vishandle = vinfo; - /* Allocate more space for additional visual */ - VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable, - sizeof(XMesaVisual) * NumVisuals, - sizeof(XMesaVisual) * (NumVisuals + 1)); - /* add xmvis to the list */ - VisualTable[NumVisuals] = xmvis; - NumVisuals++; - /* XXX minor hack, because XMesaCreateVisual doesn't support an - * aux buffers parameter. - */ - xmvis->mesa_visual.numAuxBuffers = numAuxBuffers; - } - return xmvis; -} - - -/** - * Return the default number of bits for the Z buffer. - * If defined, use the MESA_GLX_DEPTH_BITS env var value. - * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant. - * XXX probably do the same thing for stencil, accum, etc. - */ -static GLint -default_depth_bits(void) -{ - int zBits; - const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS"); - if (zEnv) - zBits = _mesa_atoi(zEnv); - else - zBits = DEFAULT_SOFTWARE_DEPTH_BITS; - return zBits; -} - -static GLint -default_alpha_bits(void) -{ - int aBits; - const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS"); - if (aEnv) - aBits = _mesa_atoi(aEnv); - else - aBits = 0; - return aBits; -} - -static GLint -default_accum_bits(void) -{ - return 16; -} - - - -/* - * Create a GLX visual from a regular XVisualInfo. - * This is called when Fake GLX is given an XVisualInfo which wasn't - * returned by glXChooseVisual. Since this is the first time we're - * considering this visual we'll take a guess at reasonable values - * for depth buffer size, stencil size, accum size, etc. - * This is the best we can do with a client-side emulation of GLX. - */ -static XMesaVisual -create_glx_visual( Display *dpy, XVisualInfo *visinfo ) -{ - int vislevel; - GLint zBits = default_depth_bits(); - GLint accBits = default_accum_bits(); - GLboolean alphaFlag = default_alpha_bits() > 0; - - vislevel = level_of_visual( dpy, visinfo ); - if (vislevel) { - /* Configure this visual as a CI, single-buffered overlay */ - return save_glx_visual( dpy, visinfo, - GL_FALSE, /* rgb */ - GL_FALSE, /* alpha */ - GL_FALSE, /* double */ - GL_FALSE, /* stereo */ - 0, /* depth bits */ - 0, /* stencil bits */ - 0,0,0,0, /* accum bits */ - vislevel, /* level */ - 0 /* numAux */ - ); - } - else if (is_usable_visual( visinfo )) { - if (_mesa_getenv("MESA_GLX_FORCE_CI")) { - /* Configure this visual as a COLOR INDEX visual. */ - return save_glx_visual( dpy, visinfo, - GL_FALSE, /* rgb */ - GL_FALSE, /* alpha */ - GL_TRUE, /* double */ - GL_FALSE, /* stereo */ - zBits, - STENCIL_BITS, - 0, 0, 0, 0, /* accum bits */ - 0, /* level */ - 0 /* numAux */ - ); - } - else { - /* Configure this visual as RGB, double-buffered, depth-buffered. */ - /* This is surely wrong for some people's needs but what else */ - /* can be done? They should use glXChooseVisual(). */ - return save_glx_visual( dpy, visinfo, - GL_TRUE, /* rgb */ - alphaFlag, /* alpha */ - GL_TRUE, /* double */ - GL_FALSE, /* stereo */ - zBits, - STENCIL_BITS, - accBits, /* r */ - accBits, /* g */ - accBits, /* b */ - accBits, /* a */ - 0, /* level */ - 0 /* numAux */ - ); - } - } - else { - _mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n"); - return NULL; - } -} - - - -/* - * Find the GLX visual associated with an XVisualInfo. - */ -static XMesaVisual -find_glx_visual( Display *dpy, XVisualInfo *vinfo ) -{ - int i; - - /* try to match visual id */ - for (i=0;idisplay==dpy - && VisualTable[i]->visinfo->visualid == vinfo->visualid) { - return VisualTable[i]; - } - } - - /* if that fails, try to match pointers */ - for (i=0;idisplay==dpy && VisualTable[i]->vishandle==vinfo) { - return VisualTable[i]; - } - } - - return NULL; -} - - - -/** - * Return the transparent pixel value for a GLX visual. - * Input: glxvis - the glx_visual - * Return: a pixel value or -1 if no transparent pixel - */ -static int -transparent_pixel( XMesaVisual glxvis ) -{ - Display *dpy = glxvis->display; - XVisualInfo *vinfo = glxvis->visinfo; - OverlayInfo *overlay_info; - int numOverlaysPerScreen, i; - - overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); - if (!overlay_info) { - return -1; - } - - for (i = 0; i < numOverlaysPerScreen; i++) { - const OverlayInfo *ov = overlay_info + i; - if (ov->overlay_visual == vinfo->visualid) { - /* found it! */ - if (ov->transparent_type == 0) { - /* type 0 indicates no transparency */ - XFree((void *) overlay_info); - return -1; - } - else { - /* ov->value is the transparent pixel */ - XFree((void *) overlay_info); - return ov->value; - } - } - } - - /* The visual ID was not found in the overlay list. */ - XFree((void *) overlay_info); - return -1; -} - - - -/** - * Try to get an X visual which matches the given arguments. - */ -static XVisualInfo * -get_visual( Display *dpy, int scr, unsigned int depth, int xclass ) -{ - XVisualInfo temp, *vis; - long mask; - int n; - unsigned int default_depth; - int default_class; - - mask = VisualScreenMask | VisualDepthMask | VisualClassMask; - temp.screen = scr; - temp.depth = depth; - temp.CLASS = xclass; - - default_depth = DefaultDepth(dpy,scr); - default_class = DefaultVisual(dpy,scr)->CLASS; - - if (depth==default_depth && xclass==default_class) { - /* try to get root window's visual */ - temp.visualid = DefaultVisual(dpy,scr)->visualid; - mask |= VisualIDMask; - } - - vis = XGetVisualInfo( dpy, mask, &temp, &n ); - - /* In case bits/pixel > 24, make sure color channels are still <=8 bits. - * An SGI Infinite Reality system, for example, can have 30bpp pixels: - * 10 bits per color channel. Mesa's limited to a max of 8 bits/channel. - */ - if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) { - if (_mesa_bitcount((GLuint) vis->red_mask ) <= 8 && - _mesa_bitcount((GLuint) vis->green_mask) <= 8 && - _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) { - return vis; - } - else { - XFree((void *) vis); - return NULL; - } - } - - return vis; -} - - - -/* - * Retrieve the value of the given environment variable and find - * the X visual which matches it. - * Input: dpy - the display - * screen - the screen number - * varname - the name of the environment variable - * Return: an XVisualInfo pointer to NULL if error. - */ -static XVisualInfo * -get_env_visual(Display *dpy, int scr, const char *varname) -{ - char value[100], type[100]; - int depth, xclass = -1; - XVisualInfo *vis; - - if (!_mesa_getenv( varname )) { - return NULL; - } - - _mesa_strncpy( value, _mesa_getenv(varname), 100 ); - value[99] = 0; - - sscanf( value, "%s %d", type, &depth ); - - if (_mesa_strcmp(type,"TrueColor")==0) xclass = TrueColor; - else if (_mesa_strcmp(type,"DirectColor")==0) xclass = DirectColor; - else if (_mesa_strcmp(type,"PseudoColor")==0) xclass = PseudoColor; - else if (_mesa_strcmp(type,"StaticColor")==0) xclass = StaticColor; - else if (_mesa_strcmp(type,"GrayScale")==0) xclass = GrayScale; - else if (_mesa_strcmp(type,"StaticGray")==0) xclass = StaticGray; - - if (xclass>-1 && depth>0) { - vis = get_visual( dpy, scr, depth, xclass ); - if (vis) { - return vis; - } - } - - _mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.", - type, depth); - - return NULL; -} - - - -/* - * Select an X visual which satisfies the RGBA/CI flag and minimum depth. - * Input: dpy, screen - X display and screen number - * rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode - * min_depth - minimum visual depth - * preferred_class - preferred GLX visual class or DONT_CARE - * Return: pointer to an XVisualInfo or NULL. - */ -static XVisualInfo * -choose_x_visual( Display *dpy, int screen, GLboolean rgba, int min_depth, - int preferred_class ) -{ - XVisualInfo *vis; - int xclass, visclass = 0; - int depth; - - if (rgba) { - Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True); - /* First see if the MESA_RGB_VISUAL env var is defined */ - vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" ); - if (vis) { - return vis; - } - /* Otherwise, search for a suitable visual */ - if (preferred_class==DONT_CARE) { - for (xclass=0;xclass<6;xclass++) { - switch (xclass) { - case 0: visclass = TrueColor; break; - case 1: visclass = DirectColor; break; - case 2: visclass = PseudoColor; break; - case 3: visclass = StaticColor; break; - case 4: visclass = GrayScale; break; - case 5: visclass = StaticGray; break; - } - if (min_depth==0) { - /* start with shallowest */ - for (depth=0;depth<=32;depth++) { - if (visclass==TrueColor && depth==8 && !hp_cr_maps) { - /* Special case: try to get 8-bit PseudoColor before */ - /* 8-bit TrueColor */ - vis = get_visual( dpy, screen, 8, PseudoColor ); - if (vis) { - return vis; - } - } - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - } - else { - /* start with deepest */ - for (depth=32;depth>=min_depth;depth--) { - if (visclass==TrueColor && depth==8 && !hp_cr_maps) { - /* Special case: try to get 8-bit PseudoColor before */ - /* 8-bit TrueColor */ - vis = get_visual( dpy, screen, 8, PseudoColor ); - if (vis) { - return vis; - } - } - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - } - } - } - else { - /* search for a specific visual class */ - switch (preferred_class) { - case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break; - case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break; - case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break; - case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break; - case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break; - case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break; - default: return NULL; - } - if (min_depth==0) { - /* start with shallowest */ - for (depth=0;depth<=32;depth++) { - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - } - else { - /* start with deepest */ - for (depth=32;depth>=min_depth;depth--) { - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - } - } - } - else { - /* First see if the MESA_CI_VISUAL env var is defined */ - vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" ); - if (vis) { - return vis; - } - /* Otherwise, search for a suitable visual, starting with shallowest */ - if (preferred_class==DONT_CARE) { - for (xclass=0;xclass<4;xclass++) { - switch (xclass) { - case 0: visclass = PseudoColor; break; - case 1: visclass = StaticColor; break; - case 2: visclass = GrayScale; break; - case 3: visclass = StaticGray; break; - } - /* try 8-bit up through 16-bit */ - for (depth=8;depth<=16;depth++) { - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - /* try min_depth up to 8-bit */ - for (depth=min_depth;depth<8;depth++) { - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - } - } - else { - /* search for a specific visual class */ - switch (preferred_class) { - case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break; - case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break; - case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break; - case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break; - case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break; - case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break; - default: return NULL; - } - /* try 8-bit up through 16-bit */ - for (depth=8;depth<=16;depth++) { - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - /* try min_depth up to 8-bit */ - for (depth=min_depth;depth<8;depth++) { - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - } - } - - /* didn't find a visual */ - return NULL; -} - - - -/* - * Find the deepest X over/underlay visual of at least min_depth. - * Input: dpy, screen - X display and screen number - * level - the over/underlay level - * trans_type - transparent pixel type: GLX_NONE_EXT, - * GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT, - * or DONT_CARE - * trans_value - transparent pixel value or DONT_CARE - * min_depth - minimum visual depth - * preferred_class - preferred GLX visual class or DONT_CARE - * Return: pointer to an XVisualInfo or NULL. - */ -static XVisualInfo * -choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag, - int level, int trans_type, int trans_value, - int min_depth, int preferred_class ) -{ - OverlayInfo *overlay_info; - int numOverlaysPerScreen; - int i; - XVisualInfo *deepvis; - int deepest; - - /*DEBUG int tt, tv; */ - - switch (preferred_class) { - case GLX_TRUE_COLOR_EXT: preferred_class = TrueColor; break; - case GLX_DIRECT_COLOR_EXT: preferred_class = DirectColor; break; - case GLX_PSEUDO_COLOR_EXT: preferred_class = PseudoColor; break; - case GLX_STATIC_COLOR_EXT: preferred_class = StaticColor; break; - case GLX_GRAY_SCALE_EXT: preferred_class = GrayScale; break; - case GLX_STATIC_GRAY_EXT: preferred_class = StaticGray; break; - default: preferred_class = DONT_CARE; - } - - overlay_info = GetOverlayInfo(dpy, scr, &numOverlaysPerScreen); - if (!overlay_info) { - return NULL; - } - - /* Search for the deepest overlay which satisifies all criteria. */ - deepest = min_depth; - deepvis = NULL; - - for (i = 0; i < numOverlaysPerScreen; i++) { - const OverlayInfo *ov = overlay_info + i; - XVisualInfo *vislist, vistemplate; - int count; - - if (ov->layer!=level) { - /* failed overlay level criteria */ - continue; - } - if (!(trans_type==DONT_CARE - || (trans_type==GLX_TRANSPARENT_INDEX_EXT - && ov->transparent_type>0) - || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) { - /* failed transparent pixel type criteria */ - continue; - } - if (trans_value!=DONT_CARE && trans_value!=ov->value) { - /* failed transparent pixel value criteria */ - continue; - } - - /* get XVisualInfo and check the depth */ - vistemplate.visualid = ov->overlay_visual; - vistemplate.screen = scr; - vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask, - &vistemplate, &count ); - - if (count!=1) { - /* something went wrong */ - continue; - } - if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) { - /* wrong visual class */ - continue; - } - - /* if RGB was requested, make sure we have True/DirectColor */ - if (rgbFlag && vislist->CLASS != TrueColor - && vislist->CLASS != DirectColor) - continue; - - /* if CI was requested, make sure we have a color indexed visual */ - if (!rgbFlag - && (vislist->CLASS == TrueColor || vislist->CLASS == DirectColor)) - continue; - - if (deepvis==NULL || vislist->depth > deepest) { - /* YES! found a satisfactory visual */ - if (deepvis) { - XFree( deepvis ); - } - deepest = vislist->depth; - deepvis = vislist; - /* DEBUG tt = ov->transparent_type;*/ - /* DEBUG tv = ov->value; */ - } - } - -/*DEBUG - if (deepvis) { - printf("chose 0x%x: layer=%d depth=%d trans_type=%d trans_value=%d\n", - deepvis->visualid, level, deepvis->depth, tt, tv ); - } -*/ - return deepvis; -} - - -/**********************************************************************/ -/*** Display-related functions ***/ -/**********************************************************************/ - - -/** - * Free all XMesaVisuals which are associated with the given display. - */ -static void -destroy_visuals_on_display(Display *dpy) -{ - int i; - for (i = 0; i < NumVisuals; i++) { - if (VisualTable[i]->display == dpy) { - /* remove this visual */ - int j; - free(VisualTable[i]); - for (j = i; j < NumVisuals - 1; j++) - VisualTable[j] = VisualTable[j + 1]; - NumVisuals--; - } - } -} - - -/** - * Called from XCloseDisplay() to let us free our display-related data. - */ -static int -close_display_callback(Display *dpy, XExtCodes *codes) -{ - destroy_visuals_on_display(dpy); - xmesa_destroy_buffers_on_display(dpy); - return 0; -} - - -/** - * Look for the named extension on given display and return a pointer - * to the _XExtension data, or NULL if extension not found. - */ -static _XExtension * -lookup_extension(Display *dpy, const char *extName) -{ - _XExtension *ext; - for (ext = dpy->ext_procs; ext; ext = ext->next) { - if (ext->name && strcmp(ext->name, extName) == 0) { - return ext; - } - } - return NULL; -} - - -/** - * Whenever we're given a new Display pointer, call this function to - * register our close_display_callback function. - */ -static void -register_with_display(Display *dpy) -{ - const char *extName = "MesaGLX"; - _XExtension *ext; - - ext = lookup_extension(dpy, extName); - if (!ext) { - XExtCodes *c = XAddExtension(dpy); - ext = dpy->ext_procs; /* new extension is at head of list */ - assert(c->extension == ext->codes.extension); - ext->name = _mesa_strdup(extName); - ext->close_display = close_display_callback; - } -} - - -/**********************************************************************/ -/*** Begin Fake GLX API Functions ***/ -/**********************************************************************/ - - -/** - * Helper used by glXChooseVisual and glXChooseFBConfig. - * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for - * the later. - * In either case, the attribute list is terminated with the value 'None'. - */ -static XMesaVisual -choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) -{ - const GLboolean rgbModeDefault = fbConfig; - const int *parselist; - XVisualInfo *vis; - int min_ci = 0; - int min_red=0, min_green=0, min_blue=0; - GLboolean rgb_flag = rgbModeDefault; - GLboolean alpha_flag = GL_FALSE; - GLboolean double_flag = GL_FALSE; - GLboolean stereo_flag = GL_FALSE; - GLint depth_size = 0; - GLint stencil_size = 0; - GLint accumRedSize = 0; - GLint accumGreenSize = 0; - GLint accumBlueSize = 0; - GLint accumAlphaSize = 0; - int level = 0; - int visual_type = DONT_CARE; - int trans_type = DONT_CARE; - int trans_value = DONT_CARE; - GLint caveat = DONT_CARE; - XMesaVisual xmvis = NULL; - int desiredVisualID = -1; - int numAux = 0; - - parselist = list; - - while (*parselist) { - - switch (*parselist) { - case GLX_USE_GL: - if (fbConfig) { - /* invalid token */ - return NULL; - } - else { - /* skip */ - parselist++; - } - break; - case GLX_BUFFER_SIZE: - parselist++; - min_ci = *parselist++; - break; - case GLX_LEVEL: - parselist++; - level = *parselist++; - break; - case GLX_RGBA: - if (fbConfig) { - /* invalid token */ - return NULL; - } - else { - rgb_flag = GL_TRUE; - parselist++; - } - break; - case GLX_DOUBLEBUFFER: - parselist++; - if (fbConfig) { - double_flag = *parselist++; - } - else { - double_flag = GL_TRUE; - } - break; - case GLX_STEREO: - parselist++; - if (fbConfig) { - stereo_flag = *parselist++; - } - else { - stereo_flag = GL_TRUE; - } - break; - case GLX_AUX_BUFFERS: - parselist++; - numAux = *parselist++; - if (numAux > MAX_AUX_BUFFERS) - return NULL; - break; - case GLX_RED_SIZE: - parselist++; - min_red = *parselist++; - break; - case GLX_GREEN_SIZE: - parselist++; - min_green = *parselist++; - break; - case GLX_BLUE_SIZE: - parselist++; - min_blue = *parselist++; - break; - case GLX_ALPHA_SIZE: - parselist++; - { - GLint size = *parselist++; - alpha_flag = size ? GL_TRUE : GL_FALSE; - } - break; - case GLX_DEPTH_SIZE: - parselist++; - depth_size = *parselist++; - break; - case GLX_STENCIL_SIZE: - parselist++; - stencil_size = *parselist++; - break; - case GLX_ACCUM_RED_SIZE: - parselist++; - { - GLint size = *parselist++; - accumRedSize = MAX2( accumRedSize, size ); - } - break; - case GLX_ACCUM_GREEN_SIZE: - parselist++; - { - GLint size = *parselist++; - accumGreenSize = MAX2( accumGreenSize, size ); - } - break; - case GLX_ACCUM_BLUE_SIZE: - parselist++; - { - GLint size = *parselist++; - accumBlueSize = MAX2( accumBlueSize, size ); - } - break; - case GLX_ACCUM_ALPHA_SIZE: - parselist++; - { - GLint size = *parselist++; - accumAlphaSize = MAX2( accumAlphaSize, size ); - } - break; - - /* - * GLX_EXT_visual_info extension - */ - case GLX_X_VISUAL_TYPE_EXT: - parselist++; - visual_type = *parselist++; - break; - case GLX_TRANSPARENT_TYPE_EXT: - parselist++; - trans_type = *parselist++; - break; - case GLX_TRANSPARENT_INDEX_VALUE_EXT: - parselist++; - trans_value = *parselist++; - break; - case GLX_TRANSPARENT_RED_VALUE_EXT: - case GLX_TRANSPARENT_GREEN_VALUE_EXT: - case GLX_TRANSPARENT_BLUE_VALUE_EXT: - case GLX_TRANSPARENT_ALPHA_VALUE_EXT: - /* ignore */ - parselist++; - parselist++; - break; - - /* - * GLX_EXT_visual_info extension - */ - case GLX_VISUAL_CAVEAT_EXT: - parselist++; - caveat = *parselist++; /* ignored for now */ - break; - - /* - * GLX_ARB_multisample - */ - case GLX_SAMPLE_BUFFERS_ARB: - /* ms not supported */ - return NULL; - case GLX_SAMPLES_ARB: - /* ms not supported */ - return NULL; - - /* - * FBConfig attribs. - */ - case GLX_RENDER_TYPE: - if (!fbConfig) - return NULL; - parselist++; - if (*parselist == GLX_RGBA_BIT) { - rgb_flag = GL_TRUE; - } - else if (*parselist == GLX_COLOR_INDEX_BIT) { - rgb_flag = GL_FALSE; - } - else if (*parselist == 0) { - rgb_flag = GL_TRUE; - } - parselist++; - break; - case GLX_DRAWABLE_TYPE: - if (!fbConfig) - return NULL; - parselist++; - if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) { - return NULL; /* bad bit */ - } - parselist++; - break; - case GLX_FBCONFIG_ID: - if (!fbConfig) - return NULL; - parselist++; - desiredVisualID = *parselist++; - break; - case GLX_X_RENDERABLE: - if (!fbConfig) - return NULL; - parselist += 2; - /* ignore */ - break; - -#ifdef GLX_EXT_texture_from_pixmap - case GLX_BIND_TO_TEXTURE_RGB_EXT: - parselist++; /*skip*/ - break; - case GLX_BIND_TO_TEXTURE_RGBA_EXT: - parselist++; /*skip*/ - break; - case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: - parselist++; /*skip*/ - break; - case GLX_BIND_TO_TEXTURE_TARGETS_EXT: - parselist++; - if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT | - GLX_TEXTURE_2D_BIT_EXT | - GLX_TEXTURE_RECTANGLE_BIT_EXT)) { - /* invalid bit */ - return NULL; - } - break; - case GLX_Y_INVERTED_EXT: - parselist++; /*skip*/ - break; -#endif - - case None: - /* end of list */ - break; - - default: - /* undefined attribute */ - _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()", - *parselist); - return NULL; - } - } - - (void) caveat; - - /* - * Since we're only simulating the GLX extension this function will never - * find any real GL visuals. Instead, all we can do is try to find an RGB - * or CI visual of appropriate depth. Other requested attributes such as - * double buffering, depth buffer, etc. will be associated with the X - * visual and stored in the VisualTable[]. - */ - if (desiredVisualID != -1) { - /* try to get a specific visual, by visualID */ - XVisualInfo temp; - int n; - temp.visualid = desiredVisualID; - temp.screen = screen; - vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n); - if (vis) { - /* give the visual some useful GLX attributes */ - double_flag = GL_TRUE; - if (vis->depth > 8) - rgb_flag = GL_TRUE; - depth_size = default_depth_bits(); - stencil_size = STENCIL_BITS; - /* XXX accum??? */ - } - } - else if (level==0) { - /* normal color planes */ - if (rgb_flag) { - /* Get an RGB visual */ - int min_rgb = min_red + min_green + min_blue; - if (min_rgb>1 && min_rgb<8) { - /* a special case to be sure we can get a monochrome visual */ - min_rgb = 1; - } - vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type ); - } - else { - /* Get a color index visual */ - vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type ); - accumRedSize = accumGreenSize = accumBlueSize = accumAlphaSize = 0; - } - } - else { - /* over/underlay planes */ - if (rgb_flag) { - /* rgba overlay */ - int min_rgb = min_red + min_green + min_blue; - if (min_rgb>1 && min_rgb<8) { - /* a special case to be sure we can get a monochrome visual */ - min_rgb = 1; - } - vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level, - trans_type, trans_value, min_rgb, visual_type ); - } - else { - /* color index overlay */ - vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level, - trans_type, trans_value, min_ci, visual_type ); - } - } - - if (vis) { - /* Note: we're not exactly obeying the glXChooseVisual rules here. - * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the - * largest depth buffer size, which is 32bits/value. Instead, we - * return 16 to maintain performance with earlier versions of Mesa. - */ - if (stencil_size > 0) - depth_size = 24; /* if Z and stencil, always use 24+8 format */ - else if (depth_size > 24) - depth_size = 32; - else if (depth_size > 16) - depth_size = 24; - else if (depth_size > 0) { - depth_size = default_depth_bits(); - } - - if (!alpha_flag) { - alpha_flag = default_alpha_bits() > 0; - } - - /* we only support one size of stencil and accum buffers. */ - if (stencil_size > 0) - stencil_size = STENCIL_BITS; - if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 || - accumAlphaSize > 0) { - accumRedSize = - accumGreenSize = - accumBlueSize = default_accum_bits(); - accumAlphaSize = alpha_flag ? accumRedSize : 0; - } - - xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag, - stereo_flag, depth_size, stencil_size, - accumRedSize, accumGreenSize, - accumBlueSize, accumAlphaSize, level, numAux ); - } - - return xmvis; -} - - -static XVisualInfo * -Fake_glXChooseVisual( Display *dpy, int screen, int *list ) -{ - XMesaVisual xmvis; - - /* register ourselves as an extension on this display */ - register_with_display(dpy); - - xmvis = choose_visual(dpy, screen, list, GL_FALSE); - if (xmvis) { -#if 0 - return xmvis->vishandle; -#else - /* create a new vishandle - the cached one may be stale */ - xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); - if (xmvis->vishandle) { - _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); - } - return xmvis->vishandle; -#endif - } - else - return NULL; -} - - -static GLXContext -Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, - GLXContext share_list, Bool direct ) -{ - XMesaVisual xmvis; - struct fake_glx_context *glxCtx; - struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list; - - if (!dpy || !visinfo) - return 0; - - glxCtx = CALLOC_STRUCT(fake_glx_context); - if (!glxCtx) - return 0; - - /* deallocate unused windows/buffers */ -#if 0 - XMesaGarbageCollect(); -#endif - - xmvis = find_glx_visual( dpy, visinfo ); - if (!xmvis) { - /* This visual wasn't found with glXChooseVisual() */ - xmvis = create_glx_visual( dpy, visinfo ); - if (!xmvis) { - /* unusable visual */ - _mesa_free(glxCtx); - return NULL; - } - } - - glxCtx->xmesaContext = XMesaCreateContext(xmvis, - shareCtx ? shareCtx->xmesaContext : NULL); - if (!glxCtx->xmesaContext) { - _mesa_free(glxCtx); - return NULL; - } - - glxCtx->glxContext.isDirect = GL_FALSE; - glxCtx->glxContext.currentDpy = dpy; - glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ - - assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); - - return (GLXContext) glxCtx; -} - - -/* XXX these may have to be removed due to thread-safety issues. */ -static GLXContext MakeCurrent_PrevContext = 0; -static GLXDrawable MakeCurrent_PrevDrawable = 0; -static GLXDrawable MakeCurrent_PrevReadable = 0; -static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0; -static XMesaBuffer MakeCurrent_PrevReadBuffer = 0; - - -/* GLX 1.3 and later */ -static Bool -Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext ctx ) -{ - struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; - static boolean firsttime = 1, no_rast = 0; - - if (firsttime) { - no_rast = getenv("SP_NO_RAST") != NULL; - firsttime = 0; - } - - - if (ctx && draw && read) { - XMesaBuffer drawBuffer, readBuffer; - XMesaContext xmctx = glxCtx->xmesaContext; - - /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */ - if (ctx == MakeCurrent_PrevContext - && draw == MakeCurrent_PrevDrawable) { - drawBuffer = MakeCurrent_PrevDrawBuffer; - } - else { - drawBuffer = XMesaFindBuffer( dpy, draw ); - } - if (!drawBuffer) { - /* drawable must be a new window! */ - drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw ); - if (!drawBuffer) { - /* Out of memory, or context/drawable depth mismatch */ - return False; - } -#ifdef FX - FXcreateContext( xmctx->xm_visual, draw, xmctx, drawBuffer ); -#endif - } - - /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */ - if (ctx == MakeCurrent_PrevContext - && read == MakeCurrent_PrevReadable) { - readBuffer = MakeCurrent_PrevReadBuffer; - } - else { - readBuffer = XMesaFindBuffer( dpy, read ); - } - if (!readBuffer) { - /* drawable must be a new window! */ - readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read ); - if (!readBuffer) { - /* Out of memory, or context/drawable depth mismatch */ - return False; - } -#ifdef FX - FXcreateContext( xmctx->xm_visual, read, xmctx, readBuffer ); -#endif - } - - if (no_rast && - MakeCurrent_PrevContext == ctx && - MakeCurrent_PrevDrawable == draw && - MakeCurrent_PrevReadable == read && - MakeCurrent_PrevDrawBuffer == drawBuffer && - MakeCurrent_PrevReadBuffer == readBuffer) - return True; - - MakeCurrent_PrevContext = ctx; - MakeCurrent_PrevDrawable = draw; - MakeCurrent_PrevReadable = read; - MakeCurrent_PrevDrawBuffer = drawBuffer; - MakeCurrent_PrevReadBuffer = readBuffer; - - /* Now make current! */ - if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) { - ((__GLXcontext *) ctx)->currentDpy = dpy; - ((__GLXcontext *) ctx)->currentDrawable = draw; - ((__GLXcontext *) ctx)->currentReadable = read; - return True; - } - else { - return False; - } - } - else if (!ctx && !draw && !read) { - /* release current context w/out assigning new one. */ - XMesaMakeCurrent( NULL, NULL ); - MakeCurrent_PrevContext = 0; - MakeCurrent_PrevDrawable = 0; - MakeCurrent_PrevReadable = 0; - MakeCurrent_PrevDrawBuffer = 0; - MakeCurrent_PrevReadBuffer = 0; - return True; - } - else { - /* The args must either all be non-zero or all zero. - * This is an error. - */ - return False; - } -} - - -static Bool -Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) -{ - return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx ); -} - - -static GLXPixmap -Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) -{ - XMesaVisual v; - XMesaBuffer b; - - v = find_glx_visual( dpy, visinfo ); - if (!v) { - v = create_glx_visual( dpy, visinfo ); - if (!v) { - /* unusable visual */ - return 0; - } - } - - b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); - if (!b) { - return 0; - } - return b->drawable; -} - - -/*** GLX_MESA_pixmap_colormap ***/ - -static GLXPixmap -Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, - Pixmap pixmap, Colormap cmap ) -{ - XMesaVisual v; - XMesaBuffer b; - - v = find_glx_visual( dpy, visinfo ); - if (!v) { - v = create_glx_visual( dpy, visinfo ); - if (!v) { - /* unusable visual */ - return 0; - } - } - - b = XMesaCreatePixmapBuffer( v, pixmap, cmap ); - if (!b) { - return 0; - } - return b->drawable; -} - - -static void -Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) -{ - XMesaBuffer b = XMesaFindBuffer(dpy, pixmap); - if (b) { - XMesaDestroyBuffer(b); - } - else if (_mesa_getenv("MESA_DEBUG")) { - _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n"); - } -} - - -static void -Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, - unsigned long mask ) -{ - struct fake_glx_context *fakeSrc = (struct fake_glx_context *) src; - struct fake_glx_context *fakeDst = (struct fake_glx_context *) dst; - XMesaContext xm_src = fakeSrc->xmesaContext; - XMesaContext xm_dst = fakeDst->xmesaContext; - (void) dpy; - if (MakeCurrent_PrevContext == src) { - _mesa_Flush(); - } - st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask ); -} - - -static Bool -Fake_glXQueryExtension( Display *dpy, int *errorb, int *event ) -{ - /* Mesa's GLX isn't really an X extension but we try to act like one. */ - (void) dpy; - (void) errorb; - (void) event; - return True; -} - - -extern void _kw_ungrab_all( Display *dpy ); -void _kw_ungrab_all( Display *dpy ) -{ - XUngrabPointer( dpy, CurrentTime ); - XUngrabKeyboard( dpy, CurrentTime ); -} - - -static void -Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) -{ - struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; - (void) dpy; - MakeCurrent_PrevContext = 0; - MakeCurrent_PrevDrawable = 0; - MakeCurrent_PrevReadable = 0; - MakeCurrent_PrevDrawBuffer = 0; - MakeCurrent_PrevReadBuffer = 0; - XMesaDestroyContext( glxCtx->xmesaContext ); - XMesaGarbageCollect(); - _mesa_free(glxCtx); -} - - -static Bool -Fake_glXIsDirect( Display *dpy, GLXContext ctx ) -{ - (void) dpy; - (void) ctx; - return False; -} - - - -static void -Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) -{ - XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); - static boolean firsttime = 1, no_rast = 0; - - if (firsttime) { - no_rast = getenv("SP_NO_RAST") != NULL; - firsttime = 0; - } - - if (no_rast) - return; - - if (buffer) { - XMesaSwapBuffers(buffer); - } - else if (_mesa_getenv("MESA_DEBUG")) { - _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n", - (int) drawable); - } -} - - - -/*** GLX_MESA_copy_sub_buffer ***/ - -static void -Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, - int x, int y, int width, int height ) -{ - XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); - if (buffer) { - XMesaCopySubBuffer(buffer, x, y, width, height); - } - else if (_mesa_getenv("MESA_DEBUG")) { - _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n"); - } -} - - -static Bool -Fake_glXQueryVersion( Display *dpy, int *maj, int *min ) -{ - (void) dpy; - /* Return GLX version, not Mesa version */ - assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION); - *maj = CLIENT_MAJOR_VERSION; - *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION ); - return True; -} - - -/* - * Query the GLX attributes of the given XVisualInfo. - */ -static int -get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) -{ - ASSERT(xmvis); - switch(attrib) { - case GLX_USE_GL: - if (fbconfig) - return GLX_BAD_ATTRIBUTE; - *value = (int) True; - return 0; - case GLX_BUFFER_SIZE: - *value = xmvis->visinfo->depth; - return 0; - case GLX_LEVEL: - *value = xmvis->mesa_visual.level; - return 0; - case GLX_RGBA: - if (fbconfig) - return GLX_BAD_ATTRIBUTE; - if (xmvis->mesa_visual.rgbMode) { - *value = True; - } - else { - *value = False; - } - return 0; - case GLX_DOUBLEBUFFER: - *value = (int) xmvis->mesa_visual.doubleBufferMode; - return 0; - case GLX_STEREO: - *value = (int) xmvis->mesa_visual.stereoMode; - return 0; - case GLX_AUX_BUFFERS: - *value = xmvis->mesa_visual.numAuxBuffers; - return 0; - case GLX_RED_SIZE: - *value = xmvis->mesa_visual.redBits; - return 0; - case GLX_GREEN_SIZE: - *value = xmvis->mesa_visual.greenBits; - return 0; - case GLX_BLUE_SIZE: - *value = xmvis->mesa_visual.blueBits; - return 0; - case GLX_ALPHA_SIZE: - *value = xmvis->mesa_visual.alphaBits; - return 0; - case GLX_DEPTH_SIZE: - *value = xmvis->mesa_visual.depthBits; - return 0; - case GLX_STENCIL_SIZE: - *value = xmvis->mesa_visual.stencilBits; - return 0; - case GLX_ACCUM_RED_SIZE: - *value = xmvis->mesa_visual.accumRedBits; - return 0; - case GLX_ACCUM_GREEN_SIZE: - *value = xmvis->mesa_visual.accumGreenBits; - return 0; - case GLX_ACCUM_BLUE_SIZE: - *value = xmvis->mesa_visual.accumBlueBits; - return 0; - case GLX_ACCUM_ALPHA_SIZE: - *value = xmvis->mesa_visual.accumAlphaBits; - return 0; - - /* - * GLX_EXT_visual_info extension - */ - case GLX_X_VISUAL_TYPE_EXT: - switch (xmvis->visinfo->CLASS) { - case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0; - case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0; - case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0; - case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0; - case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0; - case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0; - } - return 0; - case GLX_TRANSPARENT_TYPE_EXT: - if (xmvis->mesa_visual.level==0) { - /* normal planes */ - *value = GLX_NONE_EXT; - } - else if (xmvis->mesa_visual.level>0) { - /* overlay */ - if (xmvis->mesa_visual.rgbMode) { - *value = GLX_TRANSPARENT_RGB_EXT; - } - else { - *value = GLX_TRANSPARENT_INDEX_EXT; - } - } - else if (xmvis->mesa_visual.level<0) { - /* underlay */ - *value = GLX_NONE_EXT; - } - return 0; - case GLX_TRANSPARENT_INDEX_VALUE_EXT: - { - int pixel = transparent_pixel( xmvis ); - if (pixel>=0) { - *value = pixel; - } - /* else undefined */ - } - return 0; - case GLX_TRANSPARENT_RED_VALUE_EXT: - /* undefined */ - return 0; - case GLX_TRANSPARENT_GREEN_VALUE_EXT: - /* undefined */ - return 0; - case GLX_TRANSPARENT_BLUE_VALUE_EXT: - /* undefined */ - return 0; - case GLX_TRANSPARENT_ALPHA_VALUE_EXT: - /* undefined */ - return 0; - - /* - * GLX_EXT_visual_info extension - */ - case GLX_VISUAL_CAVEAT_EXT: - /* test for zero, just in case */ - if (xmvis->mesa_visual.visualRating > 0) - *value = xmvis->mesa_visual.visualRating; - else - *value = GLX_NONE_EXT; - return 0; - - /* - * GLX_ARB_multisample - */ - case GLX_SAMPLE_BUFFERS_ARB: - *value = 0; - return 0; - case GLX_SAMPLES_ARB: - *value = 0; - return 0; - - /* - * For FBConfigs: - */ - case GLX_SCREEN_EXT: - if (!fbconfig) - return GLX_BAD_ATTRIBUTE; - *value = xmvis->visinfo->screen; - break; - case GLX_DRAWABLE_TYPE: /*SGIX too */ - if (!fbconfig) - return GLX_BAD_ATTRIBUTE; - *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; - break; - case GLX_RENDER_TYPE_SGIX: - if (!fbconfig) - return GLX_BAD_ATTRIBUTE; - if (xmvis->mesa_visual.rgbMode) - *value = GLX_RGBA_BIT; - else - *value = GLX_COLOR_INDEX_BIT; - break; - case GLX_X_RENDERABLE_SGIX: - if (!fbconfig) - return GLX_BAD_ATTRIBUTE; - *value = True; /* XXX really? */ - break; - case GLX_FBCONFIG_ID_SGIX: - if (!fbconfig) - return GLX_BAD_ATTRIBUTE; - *value = xmvis->visinfo->visualid; - break; - case GLX_MAX_PBUFFER_WIDTH: - if (!fbconfig) - return GLX_BAD_ATTRIBUTE; - /* XXX or MAX_WIDTH? */ - *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen); - break; - case GLX_MAX_PBUFFER_HEIGHT: - if (!fbconfig) - return GLX_BAD_ATTRIBUTE; - *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen); - break; - case GLX_MAX_PBUFFER_PIXELS: - if (!fbconfig) - return GLX_BAD_ATTRIBUTE; - *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) * - DisplayHeight(xmvis->display, xmvis->visinfo->screen); - break; - case GLX_VISUAL_ID: - if (!fbconfig) - return GLX_BAD_ATTRIBUTE; - *value = xmvis->visinfo->visualid; - break; - -#ifdef GLX_EXT_texture_from_pixmap - case GLX_BIND_TO_TEXTURE_RGB_EXT: - *value = True; /*XXX*/ - break; - case GLX_BIND_TO_TEXTURE_RGBA_EXT: - /* XXX review */ - *value = xmvis->mesa_visual.alphaBits > 0 ? True : False; - break; - case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: - *value = True; /*XXX*/ - break; - case GLX_BIND_TO_TEXTURE_TARGETS_EXT: - *value = (GLX_TEXTURE_1D_BIT_EXT | - GLX_TEXTURE_2D_BIT_EXT | - GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/ - break; - case GLX_Y_INVERTED_EXT: - *value = True; /*XXX*/ - break; -#endif - - default: - return GLX_BAD_ATTRIBUTE; - } - return Success; -} - - -static int -Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, - int attrib, int *value ) -{ - XMesaVisual xmvis; - int k; - if (!dpy || !visinfo) - return GLX_BAD_ATTRIBUTE; - - xmvis = find_glx_visual( dpy, visinfo ); - if (!xmvis) { - /* this visual wasn't obtained with glXChooseVisual */ - xmvis = create_glx_visual( dpy, visinfo ); - if (!xmvis) { - /* this visual can't be used for GL rendering */ - if (attrib==GLX_USE_GL) { - *value = (int) False; - return 0; - } - else { - return GLX_BAD_VISUAL; - } - } - } - - k = get_config(xmvis, attrib, value, GL_FALSE); - return k; -} - - -static void -Fake_glXWaitGL( void ) -{ - XMesaContext xmesa = XMesaGetCurrentContext(); - XMesaFlush( xmesa ); -} - - - -static void -Fake_glXWaitX( void ) -{ - XMesaContext xmesa = XMesaGetCurrentContext(); - XMesaFlush( xmesa ); -} - - -static const char * -get_extensions( void ) -{ -#ifdef FX - const char *fx = _mesa_getenv("MESA_GLX_FX"); - if (fx && fx[0] != 'd') { - return EXTENSIONS; - } -#endif - return EXTENSIONS + 23; /* skip "GLX_MESA_set_3dfx_mode" */ -} - - - -/* GLX 1.1 and later */ -static const char * -Fake_glXQueryExtensionsString( Display *dpy, int screen ) -{ - (void) dpy; - (void) screen; - return get_extensions(); -} - - - -/* GLX 1.1 and later */ -static const char * -Fake_glXQueryServerString( Display *dpy, int screen, int name ) -{ - static char version[1000]; - _mesa_sprintf(version, "%d.%d %s", - SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION); - - (void) dpy; - (void) screen; - - switch (name) { - case GLX_EXTENSIONS: - return get_extensions(); - case GLX_VENDOR: - return VENDOR; - case GLX_VERSION: - return version; - default: - return NULL; - } -} - - - -/* GLX 1.1 and later */ -static const char * -Fake_glXGetClientString( Display *dpy, int name ) -{ - static char version[1000]; - _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, - CLIENT_MINOR_VERSION, MESA_GLX_VERSION); - - (void) dpy; - - switch (name) { - case GLX_EXTENSIONS: - return get_extensions(); - case GLX_VENDOR: - return VENDOR; - case GLX_VERSION: - return version; - default: - return NULL; - } -} - - - -/* - * GLX 1.3 and later - */ - - -static int -Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, - int attribute, int *value ) -{ - XMesaVisual v = (XMesaVisual) config; - (void) dpy; - (void) config; - - if (!dpy || !config || !value) - return -1; - - return get_config(v, attribute, value, GL_TRUE); -} - - -static GLXFBConfig * -Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) -{ - XVisualInfo *visuals, visTemplate; - const long visMask = VisualScreenMask; - int i; - - /* Get list of all X visuals */ - visTemplate.screen = screen; - visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements); - if (*nelements > 0) { - XMesaVisual *results; - results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual)); - if (!results) { - *nelements = 0; - return NULL; - } - for (i = 0; i < *nelements; i++) { - results[i] = create_glx_visual(dpy, visuals + i); - } - return (GLXFBConfig *) results; - } - return NULL; -} - - -static GLXFBConfig * -Fake_glXChooseFBConfig( Display *dpy, int screen, - const int *attribList, int *nitems ) -{ - XMesaVisual xmvis; - - if (!attribList || !attribList[0]) { - /* return list of all configs (per GLX_SGIX_fbconfig spec) */ - return Fake_glXGetFBConfigs(dpy, screen, nitems); - } - - xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); - if (xmvis) { - GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual)); - if (!config) { - *nitems = 0; - return NULL; - } - *nitems = 1; - config[0] = (GLXFBConfig) xmvis; - return (GLXFBConfig *) config; - } - else { - *nitems = 0; - return NULL; - } -} - - -static XVisualInfo * -Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) -{ - if (dpy && config) { - XMesaVisual xmvis = (XMesaVisual) config; -#if 0 - return xmvis->vishandle; -#else - /* create a new vishandle - the cached one may be stale */ - xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); - if (xmvis->vishandle) { - _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); - } - return xmvis->vishandle; -#endif - } - else { - return NULL; - } -} - - -static GLXWindow -Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, - const int *attribList ) -{ - XMesaVisual xmvis = (XMesaVisual) config; - XMesaBuffer xmbuf; - if (!xmvis) - return 0; - - xmbuf = XMesaCreateWindowBuffer(xmvis, win); - if (!xmbuf) - return 0; - -#ifdef FX - /* XXX this will segfault if actually called */ - FXcreateContext(xmvis, win, NULL, xmbuf); -#endif - - (void) dpy; - (void) attribList; /* Ignored in GLX 1.3 */ - - return win; /* A hack for now */ -} - - -static void -Fake_glXDestroyWindow( Display *dpy, GLXWindow window ) -{ - XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable) window); - if (b) - XMesaDestroyBuffer(b); - /* don't destroy X window */ -} - - -/* XXX untested */ -static GLXPixmap -Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, - const int *attribList ) -{ - XMesaVisual v = (XMesaVisual) config; - XMesaBuffer b; - const int *attr; - int target = 0, format = 0, mipmap = 0; - int value; - - if (!dpy || !config || !pixmap) - return 0; - - for (attr = attribList; *attr; attr++) { - switch (*attr) { - case GLX_TEXTURE_FORMAT_EXT: - attr++; - switch (*attr) { - case GLX_TEXTURE_FORMAT_NONE_EXT: - case GLX_TEXTURE_FORMAT_RGB_EXT: - case GLX_TEXTURE_FORMAT_RGBA_EXT: - format = *attr; - break; - default: - /* error */ - return 0; - } - break; - case GLX_TEXTURE_TARGET_EXT: - attr++; - switch (*attr) { - case GLX_TEXTURE_1D_EXT: - case GLX_TEXTURE_2D_EXT: - case GLX_TEXTURE_RECTANGLE_EXT: - target = *attr; - break; - default: - /* error */ - return 0; - } - break; - case GLX_MIPMAP_TEXTURE_EXT: - attr++; - if (*attr) - mipmap = 1; - break; - default: - /* error */ - return 0; - } - } - - if (format == GLX_TEXTURE_FORMAT_RGB_EXT) { - if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT, - &value, GL_TRUE) != Success - || !value) { - return 0; /* error! */ - } - } - else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) { - if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT, - &value, GL_TRUE) != Success - || !value) { - return 0; /* error! */ - } - } - if (mipmap) { - if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT, - &value, GL_TRUE) != Success - || !value) { - return 0; /* error! */ - } - } - if (target == GLX_TEXTURE_1D_EXT) { - if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, - &value, GL_TRUE) != Success - || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) { - return 0; /* error! */ - } - } - else if (target == GLX_TEXTURE_2D_EXT) { - if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, - &value, GL_TRUE) != Success - || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) { - return 0; /* error! */ - } - } - if (target == GLX_TEXTURE_RECTANGLE_EXT) { - if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, - &value, GL_TRUE) != Success - || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) { - return 0; /* error! */ - } - } - - if (format || target || mipmap) { - /* texture from pixmap */ - b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap); - } - else { - b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); - } - if (!b) { - return 0; - } - - return pixmap; -} - - -static void -Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) -{ - XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable)pixmap); - if (b) - XMesaDestroyBuffer(b); - /* don't destroy X pixmap */ -} - - -static GLXPbuffer -Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, - const int *attribList ) -{ - XMesaVisual xmvis = (XMesaVisual) config; - XMesaBuffer xmbuf; - const int *attrib; - int width = 0, height = 0; - GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; - - (void) dpy; - - for (attrib = attribList; *attrib; attrib++) { - switch (*attrib) { - case GLX_PBUFFER_WIDTH: - attrib++; - width = *attrib; - break; - case GLX_PBUFFER_HEIGHT: - attrib++; - height = *attrib; - break; - case GLX_PRESERVED_CONTENTS: - attrib++; - preserveContents = *attrib; /* ignored */ - break; - case GLX_LARGEST_PBUFFER: - attrib++; - useLargest = *attrib; /* ignored */ - break; - default: - return 0; - } - } - - /* not used at this time */ - (void) useLargest; - (void) preserveContents; - - if (width == 0 || height == 0) - return 0; - - xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); - /* A GLXPbuffer handle must be an X Drawable because that's what - * glXMakeCurrent takes. - */ - if (xmbuf) - return (GLXPbuffer) xmbuf->drawable; - else - return 0; -} - - -static void -Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) -{ - XMesaBuffer b = XMesaFindBuffer(dpy, pbuf); - if (b) { - XMesaDestroyBuffer(b); - } -} - - -static void -Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, - unsigned int *value ) -{ - XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw); - if (!xmbuf) - return; - - switch (attribute) { - case GLX_WIDTH: - *value = xmesa_buffer_width(xmbuf); - break; - case GLX_HEIGHT: - *value = xmesa_buffer_width(xmbuf); - break; - case GLX_PRESERVED_CONTENTS: - *value = True; - break; - case GLX_LARGEST_PBUFFER: - *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf); - break; - case GLX_FBCONFIG_ID: - *value = xmbuf->xm_visual->visinfo->visualid; - return; -#ifdef GLX_EXT_texture_from_pixmap - case GLX_TEXTURE_FORMAT_EXT: - *value = xmbuf->TextureFormat; - break; - case GLX_TEXTURE_TARGET_EXT: - *value = xmbuf->TextureTarget; - break; - case GLX_MIPMAP_TEXTURE_EXT: - *value = xmbuf->TextureMipmap; - break; -#endif - - default: - return; /* raise BadValue error */ - } -} - - -static GLXContext -Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, - int renderType, GLXContext shareList, Bool direct ) -{ - struct fake_glx_context *glxCtx; - struct fake_glx_context *shareCtx = (struct fake_glx_context *) shareList; - XMesaVisual xmvis = (XMesaVisual) config; - - if (!dpy || !config || - (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE)) - return 0; - - glxCtx = CALLOC_STRUCT(fake_glx_context); - if (!glxCtx) - return 0; - - /* deallocate unused windows/buffers */ - XMesaGarbageCollect(); - - glxCtx->xmesaContext = XMesaCreateContext(xmvis, - shareCtx ? shareCtx->xmesaContext : NULL); - if (!glxCtx->xmesaContext) { - _mesa_free(glxCtx); - return NULL; - } - - glxCtx->glxContext.isDirect = GL_FALSE; - glxCtx->glxContext.currentDpy = dpy; - glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ - - assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); - - return (GLXContext) glxCtx; -} - - -static int -Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) -{ - struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; - XMesaContext xmctx = glxCtx->xmesaContext; - - (void) dpy; - (void) ctx; - - switch (attribute) { - case GLX_FBCONFIG_ID: - *value = xmctx->xm_visual->visinfo->visualid; - break; - case GLX_RENDER_TYPE: - if (xmctx->xm_visual->mesa_visual.rgbMode) - *value = GLX_RGBA_BIT; - else - *value = GLX_COLOR_INDEX_BIT; - break; - case GLX_SCREEN: - *value = 0; - return Success; - default: - return GLX_BAD_ATTRIBUTE; - } - return 0; -} - - -static void -Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) -{ - XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); - if (xmbuf) - xmbuf->selectedEvents = mask; -} - - -static void -Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, - unsigned long *mask ) -{ - XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); - if (xmbuf) - *mask = xmbuf->selectedEvents; - else - *mask = 0; -} - - - -/*** GLX_SGI_swap_control ***/ - -static int -Fake_glXSwapIntervalSGI(int interval) -{ - (void) interval; - return 0; -} - - - -/*** GLX_SGI_video_sync ***/ - -static unsigned int FrameCounter = 0; - -static int -Fake_glXGetVideoSyncSGI(unsigned int *count) -{ - /* this is a bogus implementation */ - *count = FrameCounter++; - return 0; -} - -static int -Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) -{ - if (divisor <= 0 || remainder < 0) - return GLX_BAD_VALUE; - /* this is a bogus implementation */ - FrameCounter++; - while (FrameCounter % divisor != remainder) - FrameCounter++; - *count = FrameCounter; - return 0; -} - - - -/*** GLX_SGI_make_current_read ***/ - -static Bool -Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) -{ - return Fake_glXMakeContextCurrent( dpy, draw, read, ctx ); -} - -/* not used -static GLXDrawable -Fake_glXGetCurrentReadDrawableSGI(void) -{ - return 0; -} -*/ - - -/*** GLX_SGIX_video_source ***/ -#if defined(_VL_H) - -static GLXVideoSourceSGIX -Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) -{ - (void) dpy; - (void) screen; - (void) server; - (void) path; - (void) nodeClass; - (void) drainNode; - return 0; -} - -static void -Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) -{ - (void) dpy; - (void) src; -} - -#endif - - -/*** GLX_EXT_import_context ***/ - -static void -Fake_glXFreeContextEXT(Display *dpy, GLXContext context) -{ - (void) dpy; - (void) context; -} - -static GLXContextID -Fake_glXGetContextIDEXT(const GLXContext context) -{ - (void) context; - return 0; -} - -static GLXContext -Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID) -{ - (void) dpy; - (void) contextID; - return 0; -} - -static int -Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value) -{ - (void) dpy; - (void) context; - (void) attribute; - (void) value; - return 0; -} - - - -/*** GLX_SGIX_fbconfig ***/ - -static int -Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) -{ - return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value); -} - -static GLXFBConfigSGIX * -Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) -{ - return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements); -} - - -static GLXPixmap -Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) -{ - XMesaVisual xmvis = (XMesaVisual) config; - XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0); - return xmbuf->drawable; /* need to return an X ID */ -} - - -static GLXContext -Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) -{ - XMesaVisual xmvis = (XMesaVisual) config; - struct fake_glx_context *glxCtx; - struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list; - - glxCtx = CALLOC_STRUCT(fake_glx_context); - if (!glxCtx) - return 0; - - /* deallocate unused windows/buffers */ - XMesaGarbageCollect(); - - glxCtx->xmesaContext = XMesaCreateContext(xmvis, - shareCtx ? shareCtx->xmesaContext : NULL); - if (!glxCtx->xmesaContext) { - _mesa_free(glxCtx); - return NULL; - } - - glxCtx->glxContext.isDirect = GL_FALSE; - glxCtx->glxContext.currentDpy = dpy; - glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ - - assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); - - return (GLXContext) glxCtx; -} - - -static XVisualInfo * -Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) -{ - return Fake_glXGetVisualFromFBConfig(dpy, config); -} - - -static GLXFBConfigSGIX -Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) -{ - XMesaVisual xmvis = find_glx_visual(dpy, vis); - if (!xmvis) { - /* This visual wasn't found with glXChooseVisual() */ - xmvis = create_glx_visual(dpy, vis); - } - - return (GLXFBConfigSGIX) xmvis; -} - - - -/*** GLX_SGIX_pbuffer ***/ - -static GLXPbufferSGIX -Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, - unsigned int width, unsigned int height, - int *attribList) -{ - XMesaVisual xmvis = (XMesaVisual) config; - XMesaBuffer xmbuf; - const int *attrib; - GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; - - (void) dpy; - - for (attrib = attribList; attrib && *attrib; attrib++) { - switch (*attrib) { - case GLX_PRESERVED_CONTENTS_SGIX: - attrib++; - preserveContents = *attrib; /* ignored */ - break; - case GLX_LARGEST_PBUFFER_SGIX: - attrib++; - useLargest = *attrib; /* ignored */ - break; - default: - return 0; - } - } - - /* not used at this time */ - (void) useLargest; - (void) preserveContents; - - xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); - /* A GLXPbuffer handle must be an X Drawable because that's what - * glXMakeCurrent takes. - */ - return (GLXPbuffer) xmbuf->drawable; -} - - -static void -Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) -{ - XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); - if (xmbuf) { - XMesaDestroyBuffer(xmbuf); - } -} - - -static int -Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) -{ - const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); - - if (!xmbuf) { - /* Generate GLXBadPbufferSGIX for bad pbuffer */ - return 0; - } - - switch (attribute) { - case GLX_PRESERVED_CONTENTS_SGIX: - *value = True; - break; - case GLX_LARGEST_PBUFFER_SGIX: - *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf); - break; - case GLX_WIDTH_SGIX: - *value = xmesa_buffer_width(xmbuf); - break; - case GLX_HEIGHT_SGIX: - *value = xmesa_buffer_height(xmbuf); - break; - case GLX_EVENT_MASK_SGIX: - *value = 0; /* XXX might be wrong */ - break; - default: - *value = 0; - } - return 0; -} - - -static void -Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) -{ - XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); - if (xmbuf) { - /* Note: we'll never generate clobber events */ - xmbuf->selectedEvents = mask; - } -} - - -static void -Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) -{ - XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); - if (xmbuf) { - *mask = xmbuf->selectedEvents; - } - else { - *mask = 0; - } -} - - - -/*** GLX_SGI_cushion ***/ - -static void -Fake_glXCushionSGI(Display *dpy, Window win, float cushion) -{ - (void) dpy; - (void) win; - (void) cushion; -} - - - -/*** GLX_SGIX_video_resize ***/ - -static int -Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) -{ - (void) dpy; - (void) screen; - (void) channel; - (void) window; - return 0; -} - -static int -Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) -{ - (void) dpy; - (void) screen; - (void) channel; - (void) x; - (void) y; - (void) w; - (void) h; - return 0; -} - -static int -Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) -{ - (void) dpy; - (void) screen; - (void) channel; - (void) x; - (void) y; - (void) w; - (void) h; - return 0; -} - -static int -Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) -{ - (void) dpy; - (void) screen; - (void) channel; - (void) dx; - (void) dy; - (void) dw; - (void) dh; - return 0; -} - -static int -Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) -{ - (void) dpy; - (void) screen; - (void) channel; - (void) synctype; - return 0; -} - - - -/*** GLX_SGIX_dmbuffer **/ - -#if defined(_DM_BUFFER_H_) -static Bool -Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) -{ - (void) dpy; - (void) pbuffer; - (void) params; - (void) dmbuffer; - return False; -} -#endif - - -/*** GLX_SGIX_swap_group ***/ - -static void -Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) -{ - (void) dpy; - (void) drawable; - (void) member; -} - - - -/*** GLX_SGIX_swap_barrier ***/ - -static void -Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) -{ - (void) dpy; - (void) drawable; - (void) barrier; -} - -static Bool -Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) -{ - (void) dpy; - (void) screen; - (void) max; - return False; -} - - - -/*** GLX_SUN_get_transparent_index ***/ - -static Status -Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) -{ - (void) dpy; - (void) overlay; - (void) underlay; - (void) pTransparent; - return 0; -} - - - -/*** GLX_MESA_release_buffers ***/ - -/* - * Release the depth, stencil, accum buffers attached to a GLXDrawable - * (a window or pixmap) prior to destroying the GLXDrawable. - */ -static Bool -Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ) -{ - XMesaBuffer b = XMesaFindBuffer(dpy, d); - if (b) { - XMesaDestroyBuffer(b); - return True; - } - return False; -} - - - -/*** GLX_MESA_set_3dfx_mode ***/ - -static Bool -Fake_glXSet3DfxModeMESA( int mode ) -{ - return XMesaSetFXmode( mode ); -} - - - -/*** GLX_NV_vertex_array range ***/ -static void * -Fake_glXAllocateMemoryNV( GLsizei size, - GLfloat readFrequency, - GLfloat writeFrequency, - GLfloat priority ) -{ - (void) size; - (void) readFrequency; - (void) writeFrequency; - (void) priority; - return NULL; -} - - -static void -Fake_glXFreeMemoryNV( GLvoid *pointer ) -{ - (void) pointer; -} - - -/*** GLX_MESA_agp_offset ***/ - -static GLuint -Fake_glXGetAGPOffsetMESA( const GLvoid *pointer ) -{ - (void) pointer; - return ~0; -} - - -/*** GLX_EXT_texture_from_pixmap ***/ - -static void -Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, - const int *attrib_list) -{ - XMesaBuffer b = XMesaFindBuffer(dpy, drawable); - if (b) - XMesaBindTexImage(dpy, b, buffer, attrib_list); -} - -static void -Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) -{ - XMesaBuffer b = XMesaFindBuffer(dpy, drawable); - if (b) - XMesaReleaseTexImage(dpy, b, buffer); -} - - -/* silence warning */ -extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); - - -/** - * Create a new GLX API dispatch table with its function pointers - * initialized to point to Mesa's "fake" GLX API functions. - * Note: there's a similar function (_real_GetGLXDispatchTable) that - * returns a new dispatch table with all pointers initalized to point - * to "real" GLX functions (which understand GLX wire protocol, etc). - */ -struct _glxapi_table * -_mesa_GetGLXDispatchTable(void) -{ - static struct _glxapi_table glx; - - /* be sure our dispatch table size <= libGL's table */ - { - GLuint size = sizeof(struct _glxapi_table) / sizeof(void *); - (void) size; - assert(_glxapi_get_dispatch_table_size() >= size); - } - - /* initialize the whole table to no-ops */ - _glxapi_set_no_op_table(&glx); - - /* now initialize the table with the functions I implement */ - glx.ChooseVisual = Fake_glXChooseVisual; - glx.CopyContext = Fake_glXCopyContext; - glx.CreateContext = Fake_glXCreateContext; - glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap; - glx.DestroyContext = Fake_glXDestroyContext; - glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap; - glx.GetConfig = Fake_glXGetConfig; - /*glx.GetCurrentContext = Fake_glXGetCurrentContext;*/ - /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/ - glx.IsDirect = Fake_glXIsDirect; - glx.MakeCurrent = Fake_glXMakeCurrent; - glx.QueryExtension = Fake_glXQueryExtension; - glx.QueryVersion = Fake_glXQueryVersion; - glx.SwapBuffers = Fake_glXSwapBuffers; - glx.UseXFont = Fake_glXUseXFont; - glx.WaitGL = Fake_glXWaitGL; - glx.WaitX = Fake_glXWaitX; - - /*** GLX_VERSION_1_1 ***/ - glx.GetClientString = Fake_glXGetClientString; - glx.QueryExtensionsString = Fake_glXQueryExtensionsString; - glx.QueryServerString = Fake_glXQueryServerString; - - /*** GLX_VERSION_1_2 ***/ - /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/ - - /*** GLX_VERSION_1_3 ***/ - glx.ChooseFBConfig = Fake_glXChooseFBConfig; - glx.CreateNewContext = Fake_glXCreateNewContext; - glx.CreatePbuffer = Fake_glXCreatePbuffer; - glx.CreatePixmap = Fake_glXCreatePixmap; - glx.CreateWindow = Fake_glXCreateWindow; - glx.DestroyPbuffer = Fake_glXDestroyPbuffer; - glx.DestroyPixmap = Fake_glXDestroyPixmap; - glx.DestroyWindow = Fake_glXDestroyWindow; - /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/ - glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib; - glx.GetFBConfigs = Fake_glXGetFBConfigs; - glx.GetSelectedEvent = Fake_glXGetSelectedEvent; - glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig; - glx.MakeContextCurrent = Fake_glXMakeContextCurrent; - glx.QueryContext = Fake_glXQueryContext; - glx.QueryDrawable = Fake_glXQueryDrawable; - glx.SelectEvent = Fake_glXSelectEvent; - - /*** GLX_SGI_swap_control ***/ - glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI; - - /*** GLX_SGI_video_sync ***/ - glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI; - glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI; - - /*** GLX_SGI_make_current_read ***/ - glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI; - /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/ - -/*** GLX_SGIX_video_source ***/ -#if defined(_VL_H) - glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX; - glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX; -#endif - - /*** GLX_EXT_import_context ***/ - glx.FreeContextEXT = Fake_glXFreeContextEXT; - glx.GetContextIDEXT = Fake_glXGetContextIDEXT; - /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/ - glx.ImportContextEXT = Fake_glXImportContextEXT; - glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT; - - /*** GLX_SGIX_fbconfig ***/ - glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX; - glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX; - glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX; - glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX; - glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX; - glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX; - - /*** GLX_SGIX_pbuffer ***/ - glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX; - glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX; - glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX; - glx.SelectEventSGIX = Fake_glXSelectEventSGIX; - glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX; - - /*** GLX_SGI_cushion ***/ - glx.CushionSGI = Fake_glXCushionSGI; - - /*** GLX_SGIX_video_resize ***/ - glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX; - glx.ChannelRectSGIX = Fake_glXChannelRectSGIX; - glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX; - glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX; - glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX; - - /*** GLX_SGIX_dmbuffer **/ -#if defined(_DM_BUFFER_H_) - glx.AssociateDMPbufferSGIX = NULL; -#endif - - /*** GLX_SGIX_swap_group ***/ - glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX; - - /*** GLX_SGIX_swap_barrier ***/ - glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX; - glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX; - - /*** GLX_SUN_get_transparent_index ***/ - glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN; - - /*** GLX_MESA_copy_sub_buffer ***/ - glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA; - - /*** GLX_MESA_release_buffers ***/ - glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA; - - /*** GLX_MESA_pixmap_colormap ***/ - glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA; - - /*** GLX_MESA_set_3dfx_mode ***/ - glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA; - - /*** GLX_NV_vertex_array_range ***/ - glx.AllocateMemoryNV = Fake_glXAllocateMemoryNV; - glx.FreeMemoryNV = Fake_glXFreeMemoryNV; - - /*** GLX_MESA_agp_offset ***/ - glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA; - - /*** GLX_EXT_texture_from_pixmap ***/ - glx.BindTexImageEXT = Fake_glXBindTexImageEXT; - glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT; - - return &glx; -} diff --git a/src/gallium/winsys/xlib/glxapi.c b/src/gallium/winsys/xlib/glxapi.c deleted file mode 100644 index c059fc3edb..0000000000 --- a/src/gallium/winsys/xlib/glxapi.c +++ /dev/null @@ -1,1390 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 1999-2007 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - - -/* - * This is the GLX API dispatcher. Calls to the glX* functions are - * either routed to the real GLX encoders or to Mesa's pseudo-GLX functions. - * See the glxapi.h file for more details. - */ - - -#include -#include -#include -#include -#include "main/glheader.h" -#include "glapi/glapi.h" -#include "glxapi.h" -#include "pipe/p_thread.h" - - -extern struct _glxapi_table *_real_GetGLXDispatchTable(void); -extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); - - -struct display_dispatch { - Display *Dpy; - struct _glxapi_table *Table; - struct display_dispatch *Next; -}; - -static struct display_dispatch *DispatchList = NULL; - - -/* Display -> Dispatch caching */ -static Display *prevDisplay = NULL; -static struct _glxapi_table *prevTable = NULL; - - -static struct _glxapi_table * -get_dispatch(Display *dpy) -{ - if (!dpy) - return NULL; - - /* search list of display/dispatch pairs for this display */ - { - const struct display_dispatch *d = DispatchList; - while (d) { - if (d->Dpy == dpy) { - prevDisplay = dpy; - prevTable = d->Table; - return d->Table; /* done! */ - } - d = d->Next; - } - } - - /* A new display, determine if we should use real GLX - * or Mesa's pseudo-GLX. - */ - { - struct _glxapi_table *t = _mesa_GetGLXDispatchTable(); - - if (t) { - struct display_dispatch *d; - d = (struct display_dispatch *) malloc(sizeof(struct display_dispatch)); - if (d) { - d->Dpy = dpy; - d->Table = t; - /* insert at head of list */ - d->Next = DispatchList; - DispatchList = d; - /* update cache */ - prevDisplay = dpy; - prevTable = t; - return t; - } - } - } - - /* If we get here that means we can't use real GLX on this display - * and the Mesa pseudo-GLX software renderer wasn't compiled in. - * Or, we ran out of memory! - */ - return NULL; -} - - -/* Don't use the GET_DISPATCH defined in glthread.h */ -#undef GET_DISPATCH - -#define GET_DISPATCH(DPY, TABLE) \ - if (DPY == prevDisplay) { \ - TABLE = prevTable; \ - } \ - else if (!DPY) { \ - TABLE = NULL; \ - } \ - else { \ - TABLE = get_dispatch(DPY); \ - } - - - - -/** - * GLX API current context. - */ -pipe_tsd ContextTSD; - - -static void -SetCurrentContext(GLXContext c) -{ - pipe_tsd_set(&ContextTSD, c); -} - - -/* - * GLX API entrypoints - */ - -/*** GLX_VERSION_1_0 ***/ - -XVisualInfo PUBLIC * -glXChooseVisual(Display *dpy, int screen, int *list) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return NULL; - return (t->ChooseVisual)(dpy, screen, list); -} - - -void PUBLIC -glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->CopyContext)(dpy, src, dst, mask); -} - - -GLXContext PUBLIC -glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateContext)(dpy, visinfo, shareList, direct); -} - - -GLXPixmap PUBLIC -glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateGLXPixmap)(dpy, visinfo, pixmap); -} - - -void PUBLIC -glXDestroyContext(Display *dpy, GLXContext ctx) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - if (glXGetCurrentContext() == ctx) - SetCurrentContext(NULL); - (t->DestroyContext)(dpy, ctx); -} - - -void PUBLIC -glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->DestroyGLXPixmap)(dpy, pixmap); -} - - -int PUBLIC -glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return GLX_NO_EXTENSION; - return (t->GetConfig)(dpy, visinfo, attrib, value); -} - - -GLXContext PUBLIC -glXGetCurrentContext(void) -{ - return (GLXContext) pipe_tsd_get(&ContextTSD); -} - - -GLXDrawable PUBLIC -glXGetCurrentDrawable(void) -{ - __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); - return gc ? gc->currentDrawable : 0; -} - - -Bool PUBLIC -glXIsDirect(Display *dpy, GLXContext ctx) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->IsDirect)(dpy, ctx); -} - - -Bool PUBLIC -glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) -{ - Bool b; - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) { - return False; - } - b = (*t->MakeCurrent)(dpy, drawable, ctx); - if (b) { - SetCurrentContext(ctx); - } - return b; -} - - -Bool PUBLIC -glXQueryExtension(Display *dpy, int *errorb, int *event) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->QueryExtension)(dpy, errorb, event); -} - - -Bool PUBLIC -glXQueryVersion(Display *dpy, int *maj, int *min) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->QueryVersion)(dpy, maj, min); -} - - -void PUBLIC -glXSwapBuffers(Display *dpy, GLXDrawable drawable) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->SwapBuffers)(dpy, drawable); -} - - -void PUBLIC -glXUseXFont(Font font, int first, int count, int listBase) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->UseXFont)(font, first, count, listBase); -} - - -void PUBLIC -glXWaitGL(void) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->WaitGL)(); -} - - -void PUBLIC -glXWaitX(void) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->WaitX)(); -} - - - -/*** GLX_VERSION_1_1 ***/ - -const char PUBLIC * -glXGetClientString(Display *dpy, int name) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return NULL; - return (t->GetClientString)(dpy, name); -} - - -const char PUBLIC * -glXQueryExtensionsString(Display *dpy, int screen) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return NULL; - return (t->QueryExtensionsString)(dpy, screen); -} - - -const char PUBLIC * -glXQueryServerString(Display *dpy, int screen, int name) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return NULL; - return (t->QueryServerString)(dpy, screen, name); -} - - -/*** GLX_VERSION_1_2 ***/ - -Display PUBLIC * -glXGetCurrentDisplay(void) -{ - /* Same code as in libGL's glxext.c */ - __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); - if (NULL == gc) return NULL; - return gc->currentDpy; -} - - - -/*** GLX_VERSION_1_3 ***/ - -GLXFBConfig PUBLIC * -glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->ChooseFBConfig)(dpy, screen, attribList, nitems); -} - - -GLXContext PUBLIC -glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateNewContext)(dpy, config, renderType, shareList, direct); -} - - -GLXPbuffer PUBLIC -glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreatePbuffer)(dpy, config, attribList); -} - - -GLXPixmap PUBLIC -glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreatePixmap)(dpy, config, pixmap, attribList); -} - - -GLXWindow PUBLIC -glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateWindow)(dpy, config, win, attribList); -} - - -void PUBLIC -glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->DestroyPbuffer)(dpy, pbuf); -} - - -void PUBLIC -glXDestroyPixmap(Display *dpy, GLXPixmap pixmap) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->DestroyPixmap)(dpy, pixmap); -} - - -void PUBLIC -glXDestroyWindow(Display *dpy, GLXWindow window) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->DestroyWindow)(dpy, window); -} - - -GLXDrawable PUBLIC -glXGetCurrentReadDrawable(void) -{ - __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); - return gc ? gc->currentReadable : 0; -} - - -int PUBLIC -glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return GLX_NO_EXTENSION; - return (t->GetFBConfigAttrib)(dpy, config, attribute, value); -} - - -GLXFBConfig PUBLIC * -glXGetFBConfigs(Display *dpy, int screen, int *nelements) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->GetFBConfigs)(dpy, screen, nelements); -} - -void PUBLIC -glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->GetSelectedEvent)(dpy, drawable, mask); -} - - -XVisualInfo PUBLIC * -glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return NULL; - return (t->GetVisualFromFBConfig)(dpy, config); -} - - -Bool PUBLIC -glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) -{ - Bool b; - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - b = (t->MakeContextCurrent)(dpy, draw, read, ctx); - if (b) { - SetCurrentContext(ctx); - } - return b; -} - - -int PUBLIC -glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - assert(t); - if (!t) - return 0; /* XXX correct? */ - return (t->QueryContext)(dpy, ctx, attribute, value); -} - - -void PUBLIC -glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->QueryDrawable)(dpy, draw, attribute, value); -} - - -void PUBLIC -glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->SelectEvent)(dpy, drawable, mask); -} - - - -/*** GLX_SGI_swap_control ***/ - -int PUBLIC -glXSwapIntervalSGI(int interval) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->SwapIntervalSGI)(interval); -} - - - -/*** GLX_SGI_video_sync ***/ - -int PUBLIC -glXGetVideoSyncSGI(unsigned int *count) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t || !glXGetCurrentContext()) - return GLX_BAD_CONTEXT; - return (t->GetVideoSyncSGI)(count); -} - -int PUBLIC -glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t || !glXGetCurrentContext()) - return GLX_BAD_CONTEXT; - return (t->WaitVideoSyncSGI)(divisor, remainder, count); -} - - - -/*** GLX_SGI_make_current_read ***/ - -Bool PUBLIC -glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->MakeCurrentReadSGI)(dpy, draw, read, ctx); -} - -GLXDrawable PUBLIC -glXGetCurrentReadDrawableSGI(void) -{ - return glXGetCurrentReadDrawable(); -} - - -#if defined(_VL_H) - -GLXVideoSourceSGIX PUBLIC -glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateGLXVideoSourceSGIX)(dpy, screen, server, path, nodeClass, drainNode); -} - -void PUBLIC -glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->DestroyGLXVideoSourceSGIX)(dpy, src); -} - -#endif - - -/*** GLX_EXT_import_context ***/ - -void PUBLIC -glXFreeContextEXT(Display *dpy, GLXContext context) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->FreeContextEXT)(dpy, context); -} - -GLXContextID PUBLIC -glXGetContextIDEXT(const GLXContext context) -{ - return ((__GLXcontext *) context)->xid; -} - -Display PUBLIC * -glXGetCurrentDisplayEXT(void) -{ - return glXGetCurrentDisplay(); -} - -GLXContext PUBLIC -glXImportContextEXT(Display *dpy, GLXContextID contextID) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->ImportContextEXT)(dpy, contextID); -} - -int PUBLIC -glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; /* XXX ok? */ - return (t->QueryContextInfoEXT)(dpy, context, attribute, value); -} - - - -/*** GLX_SGIX_fbconfig ***/ - -int PUBLIC -glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->GetFBConfigAttribSGIX)(dpy, config, attribute, value); -} - -GLXFBConfigSGIX PUBLIC * -glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->ChooseFBConfigSGIX)(dpy, screen, attrib_list, nelements); -} - -GLXPixmap PUBLIC -glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateGLXPixmapWithConfigSGIX)(dpy, config, pixmap); -} - -GLXContext PUBLIC -glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateContextWithConfigSGIX)(dpy, config, render_type, share_list, direct); -} - -XVisualInfo PUBLIC * -glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->GetVisualFromFBConfigSGIX)(dpy, config); -} - -GLXFBConfigSGIX PUBLIC -glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->GetFBConfigFromVisualSGIX)(dpy, vis); -} - - - -/*** GLX_SGIX_pbuffer ***/ - -GLXPbufferSGIX PUBLIC -glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateGLXPbufferSGIX)(dpy, config, width, height, attrib_list); -} - -void PUBLIC -glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->DestroyGLXPbufferSGIX)(dpy, pbuf); -} - -int PUBLIC -glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->QueryGLXPbufferSGIX)(dpy, pbuf, attribute, value); -} - -void PUBLIC -glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->SelectEventSGIX)(dpy, drawable, mask); -} - -void PUBLIC -glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->GetSelectedEventSGIX)(dpy, drawable, mask); -} - - - -/*** GLX_SGI_cushion ***/ - -void PUBLIC -glXCushionSGI(Display *dpy, Window win, float cushion) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->CushionSGI)(dpy, win, cushion); -} - - - -/*** GLX_SGIX_video_resize ***/ - -int PUBLIC -glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->BindChannelToWindowSGIX)(dpy, screen, channel, window); -} - -int PUBLIC -glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->ChannelRectSGIX)(dpy, screen, channel, x, y, w, h); -} - -int PUBLIC -glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->QueryChannelRectSGIX)(dpy, screen, channel, x, y, w, h); -} - -int PUBLIC -glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->QueryChannelDeltasSGIX)(dpy, screen, channel, dx, dy, dw, dh); -} - -int PUBLIC -glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->ChannelRectSyncSGIX)(dpy, screen, channel, synctype); -} - - - -#if defined(_DM_BUFFER_H_) - -Bool PUBLIC -glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->AssociateDMPbufferSGIX)(dpy, pbuffer, params, dmbuffer); -} - -#endif - - -/*** GLX_SGIX_swap_group ***/ - -void PUBLIC -glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (*t->JoinSwapGroupSGIX)(dpy, drawable, member); -} - - -/*** GLX_SGIX_swap_barrier ***/ - -void PUBLIC -glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (*t->BindSwapBarrierSGIX)(dpy, drawable, barrier); -} - -Bool PUBLIC -glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (*t->QueryMaxSwapBarriersSGIX)(dpy, screen, max); -} - - - -/*** GLX_SUN_get_transparent_index ***/ - -Status PUBLIC -glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (*t->GetTransparentIndexSUN)(dpy, overlay, underlay, pTransparent); -} - - - -/*** GLX_MESA_copy_sub_buffer ***/ - -void PUBLIC -glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height); -} - - - -/*** GLX_MESA_release_buffers ***/ - -Bool PUBLIC -glXReleaseBuffersMESA(Display *dpy, Window w) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->ReleaseBuffersMESA)(dpy, w); -} - - - -/*** GLX_MESA_pixmap_colormap ***/ - -GLXPixmap PUBLIC -glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (!t) - return 0; - return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap); -} - - - -/*** GLX_MESA_set_3dfx_mode ***/ - -Bool PUBLIC -glXSet3DfxModeMESA(int mode) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t) - return False; - return (t->Set3DfxModeMESA)(mode); -} - - - -/*** GLX_NV_vertex_array_range ***/ - -void PUBLIC * -glXAllocateMemoryNV( GLsizei size, - GLfloat readFrequency, - GLfloat writeFrequency, - GLfloat priority ) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t) - return NULL; - return (t->AllocateMemoryNV)(size, readFrequency, writeFrequency, priority); -} - - -void PUBLIC -glXFreeMemoryNV( GLvoid *pointer ) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t) - return; - (t->FreeMemoryNV)(pointer); -} - - - - -/*** GLX_MESA_agp_offset */ - -GLuint PUBLIC -glXGetAGPOffsetMESA( const GLvoid *pointer ) -{ - struct _glxapi_table *t; - Display *dpy = glXGetCurrentDisplay(); - GET_DISPATCH(dpy, t); - if (!t) - return ~0; - return (t->GetAGPOffsetMESA)(pointer); -} - - -/*** GLX_MESA_allocate_memory */ - -void * -glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size, - float readfreq, float writefreq, float priority) -{ - /* dummy */ - return NULL; -} - -void -glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) -{ - /* dummy */ -} - - -GLuint -glXGetMemoryOffsetMESA(Display *dpy, int scrn, const void *pointer) -{ - /* dummy */ - return 0; -} - - -/*** GLX_EXT_texture_from_pixmap */ - -void -glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, - const int *attrib_list) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (t) - t->BindTexImageEXT(dpy, drawable, buffer, attrib_list); -} - -void -glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) -{ - struct _glxapi_table *t; - GET_DISPATCH(dpy, t); - if (t) - t->ReleaseTexImageEXT(dpy, drawable, buffer); -} - - -/**********************************************************************/ -/* GLX API management functions */ -/**********************************************************************/ - - -const char * -_glxapi_get_version(void) -{ - return "1.3"; -} - - -/* - * Return array of extension strings. - */ -const char ** -_glxapi_get_extensions(void) -{ - static const char *extensions[] = { -#ifdef GLX_EXT_import_context - "GLX_EXT_import_context", -#endif -#ifdef GLX_SGI_video_sync - "GLX_SGI_video_sync", -#endif -#ifdef GLX_MESA_copy_sub_buffer - "GLX_MESA_copy_sub_buffer", -#endif -#ifdef GLX_MESA_release_buffers - "GLX_MESA_release_buffers", -#endif -#ifdef GLX_MESA_pixmap_colormap - "GLX_MESA_pixmap_colormap", -#endif -#ifdef GLX_MESA_set_3dfx_mode - "GLX_MESA_set_3dfx_mode", -#endif -#ifdef GLX_SGIX_fbconfig - "GLX_SGIX_fbconfig", -#endif -#ifdef GLX_SGIX_pbuffer - "GLX_SGIX_pbuffer", -#endif -#ifdef GLX_EXT_texture_from_pixmap - "GLX_EXT_texture_from_pixmap", -#endif - NULL - }; - return extensions; -} - - -/* - * Return size of the GLX dispatch table, in entries, not bytes. - */ -GLuint -_glxapi_get_dispatch_table_size(void) -{ - return sizeof(struct _glxapi_table) / sizeof(void *); -} - - -static int -generic_no_op_func(void) -{ - return 0; -} - - -/* - * Initialize all functions in given dispatch table to be no-ops - */ -void -_glxapi_set_no_op_table(struct _glxapi_table *t) -{ - typedef int (*nop_func)(void); - nop_func *dispatch = (nop_func *) t; - GLuint n = _glxapi_get_dispatch_table_size(); - GLuint i; - for (i = 0; i < n; i++) { - dispatch[i] = generic_no_op_func; - } -} - - -struct name_address_pair { - const char *Name; - __GLXextFuncPtr Address; -}; - -static struct name_address_pair GLX_functions[] = { - /*** GLX_VERSION_1_0 ***/ - { "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual }, - { "glXCopyContext", (__GLXextFuncPtr) glXCopyContext }, - { "glXCreateContext", (__GLXextFuncPtr) glXCreateContext }, - { "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap }, - { "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext }, - { "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap }, - { "glXGetConfig", (__GLXextFuncPtr) glXGetConfig }, - { "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext }, - { "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable }, - { "glXIsDirect", (__GLXextFuncPtr) glXIsDirect }, - { "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent }, - { "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension }, - { "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion }, - { "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers }, - { "glXUseXFont", (__GLXextFuncPtr) glXUseXFont }, - { "glXWaitGL", (__GLXextFuncPtr) glXWaitGL }, - { "glXWaitX", (__GLXextFuncPtr) glXWaitX }, - - /*** GLX_VERSION_1_1 ***/ - { "glXGetClientString", (__GLXextFuncPtr) glXGetClientString }, - { "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString }, - { "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString }, - - /*** GLX_VERSION_1_2 ***/ - { "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay }, - - /*** GLX_VERSION_1_3 ***/ - { "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig }, - { "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext }, - { "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer }, - { "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap }, - { "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow }, - { "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer }, - { "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap }, - { "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow }, - { "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable }, - { "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib }, - { "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs }, - { "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent }, - { "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig }, - { "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent }, - { "glXQueryContext", (__GLXextFuncPtr) glXQueryContext }, - { "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable }, - { "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent }, - - /*** GLX_VERSION_1_4 ***/ - { "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress }, - - /*** GLX_SGI_swap_control ***/ - { "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI }, - - /*** GLX_SGI_video_sync ***/ - { "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI }, - { "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI }, - - /*** GLX_SGI_make_current_read ***/ - { "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI }, - { "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI }, - - /*** GLX_SGIX_video_source ***/ -#if defined(_VL_H) - { "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX }, - { "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX }, -#endif - - /*** GLX_EXT_import_context ***/ - { "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT }, - { "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT }, - { "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT }, - { "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT }, - { "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT }, - - /*** GLX_SGIX_fbconfig ***/ - { "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX }, - { "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX }, - { "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX }, - { "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX }, - { "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX }, - { "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX }, - - /*** GLX_SGIX_pbuffer ***/ - { "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX }, - { "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX }, - { "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX }, - { "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX }, - { "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX }, - - /*** GLX_SGI_cushion ***/ - { "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI }, - - /*** GLX_SGIX_video_resize ***/ - { "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX }, - { "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX }, - { "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX }, - { "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX }, - { "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX }, - - /*** GLX_SGIX_dmbuffer **/ -#if defined(_DM_BUFFER_H_) - { "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX }, -#endif - - /*** GLX_SGIX_swap_group ***/ - { "glXJoinSwapGroupSGIX", (__GLXextFuncPtr) glXJoinSwapGroupSGIX }, - - /*** GLX_SGIX_swap_barrier ***/ - { "glXBindSwapBarrierSGIX", (__GLXextFuncPtr) glXBindSwapBarrierSGIX }, - { "glXQueryMaxSwapBarriersSGIX", (__GLXextFuncPtr) glXQueryMaxSwapBarriersSGIX }, - - /*** GLX_SUN_get_transparent_index ***/ - { "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN }, - - /*** GLX_MESA_copy_sub_buffer ***/ - { "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA }, - - /*** GLX_MESA_pixmap_colormap ***/ - { "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA }, - - /*** GLX_MESA_release_buffers ***/ - { "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA }, - - /*** GLX_MESA_set_3dfx_mode ***/ - { "glXSet3DfxModeMESA", (__GLXextFuncPtr) glXSet3DfxModeMESA }, - - /*** GLX_ARB_get_proc_address ***/ - { "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB }, - - /*** GLX_NV_vertex_array_range ***/ - { "glXAllocateMemoryNV", (__GLXextFuncPtr) glXAllocateMemoryNV }, - { "glXFreeMemoryNV", (__GLXextFuncPtr) glXFreeMemoryNV }, - - /*** GLX_MESA_agp_offset ***/ - { "glXGetAGPOffsetMESA", (__GLXextFuncPtr) glXGetAGPOffsetMESA }, - - /*** GLX_MESA_allocate_memory ***/ - { "glXAllocateMemoryMESA", (__GLXextFuncPtr) glXAllocateMemoryMESA }, - { "glXFreeMemoryMESA", (__GLXextFuncPtr) glXFreeMemoryMESA }, - { "glXGetMemoryOffsetMESA", (__GLXextFuncPtr) glXGetMemoryOffsetMESA }, - - /*** GLX_EXT_texture_from_pixmap ***/ - { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT }, - { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT }, - - { NULL, NULL } /* end of list */ -}; - - - -/* - * Return address of named glX function, or NULL if not found. - */ -__GLXextFuncPtr -_glxapi_get_proc_address(const char *funcName) -{ - GLuint i; - for (i = 0; GLX_functions[i].Name; i++) { - if (strcmp(GLX_functions[i].Name, funcName) == 0) - return GLX_functions[i].Address; - } - return NULL; -} - - - -/* - * This function does not get dispatched through the dispatch table - * since it's really a "meta" function. - */ -__GLXextFuncPtr -glXGetProcAddressARB(const GLubyte *procName) -{ - __GLXextFuncPtr f; - - f = _glxapi_get_proc_address((const char *) procName); - if (f) { - return f; - } - - f = (__GLXextFuncPtr) _glapi_get_proc_address((const char *) procName); - return f; -} - - -/* GLX 1.4 */ -void (*glXGetProcAddress(const GLubyte *procName))() -{ - return glXGetProcAddressARB(procName); -} diff --git a/src/gallium/winsys/xlib/glxapi.h b/src/gallium/winsys/xlib/glxapi.h deleted file mode 100644 index 37de81e55a..0000000000 --- a/src/gallium/winsys/xlib/glxapi.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 1999-2004 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - - -#ifndef _glxapi_h_ -#define _glxapi_h_ - - -#define GLX_GLXEXT_PROTOTYPES -#include "GL/glx.h" - - -/* The GLX API dispatcher (i.e. this code) is being built into stand-alone - * Mesa. We don't know anything about XFree86 or real GLX so we define a - * minimal __GLXContextRec here so some of the functions in this file can - * work properly. - */ -typedef struct __GLXcontextRec { - Display *currentDpy; - GLboolean isDirect; - GLXDrawable currentDrawable; - GLXDrawable currentReadable; - XID xid; -} __GLXcontext; - - -/* - * Almost all the GLX API functions get routed through this dispatch table. - * The exceptions are the glXGetCurrentXXX() functions. - * - * This dispatch table allows multiple GLX client-side modules to coexist. - * Specifically, a real GLX library (like SGI's or the Utah GLX) and Mesa's - * pseudo-GLX can be present at the same time. The former being used on - * GLX-enabled X servers and the later on non-GLX X servers. - * - * Red Hat has been using this since Red Hat Linux 7.0 (I think). - * This'll be a standard feature in XFree86 4.3. It basically allows one - * libGL to do both DRI-rendering and "fake GLX" rendering to X displays - * that lack the GLX extension. - */ -struct _glxapi_table { - /*** GLX_VERSION_1_0 ***/ - XVisualInfo *(*ChooseVisual)(Display *dpy, int screen, int *list); - void (*CopyContext)(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask); - GLXContext (*CreateContext)(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct); - GLXPixmap (*CreateGLXPixmap)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap); - void (*DestroyContext)(Display *dpy, GLXContext ctx); - void (*DestroyGLXPixmap)(Display *dpy, GLXPixmap pixmap); - int (*GetConfig)(Display *dpy, XVisualInfo *visinfo, int attrib, int *value); - /*GLXContext (*GetCurrentContext)(void);*/ - /*GLXDrawable (*GetCurrentDrawable)(void);*/ - Bool (*IsDirect)(Display *dpy, GLXContext ctx); - Bool (*MakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx); - Bool (*QueryExtension)(Display *dpy, int *errorb, int *event); - Bool (*QueryVersion)(Display *dpy, int *maj, int *min); - void (*SwapBuffers)(Display *dpy, GLXDrawable drawable); - void (*UseXFont)(Font font, int first, int count, int listBase); - void (*WaitGL)(void); - void (*WaitX)(void); - - /*** GLX_VERSION_1_1 ***/ - const char *(*GetClientString)(Display *dpy, int name); - const char *(*QueryExtensionsString)(Display *dpy, int screen); - const char *(*QueryServerString)(Display *dpy, int screen, int name); - - /*** GLX_VERSION_1_2 ***/ - /*Display *(*GetCurrentDisplay)(void);*/ - - /*** GLX_VERSION_1_3 ***/ - GLXFBConfig *(*ChooseFBConfig)(Display *dpy, int screen, const int *attribList, int *nitems); - GLXContext (*CreateNewContext)(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct); - GLXPbuffer (*CreatePbuffer)(Display *dpy, GLXFBConfig config, const int *attribList); - GLXPixmap (*CreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList); - GLXWindow (*CreateWindow)(Display *dpy, GLXFBConfig config, Window win, const int *attribList); - void (*DestroyPbuffer)(Display *dpy, GLXPbuffer pbuf); - void (*DestroyPixmap)(Display *dpy, GLXPixmap pixmap); - void (*DestroyWindow)(Display *dpy, GLXWindow window); - /*GLXDrawable (*GetCurrentReadDrawable)(void);*/ - int (*GetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value); - GLXFBConfig *(*GetFBConfigs)(Display *dpy, int screen, int *nelements); - void (*GetSelectedEvent)(Display *dpy, GLXDrawable drawable, unsigned long *mask); - XVisualInfo *(*GetVisualFromFBConfig)(Display *dpy, GLXFBConfig config); - Bool (*MakeContextCurrent)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); - int (*QueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value); - void (*QueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); - void (*SelectEvent)(Display *dpy, GLXDrawable drawable, unsigned long mask); - - /*** GLX_SGI_swap_control ***/ - int (*SwapIntervalSGI)(int); - - /*** GLX_SGI_video_sync ***/ - int (*GetVideoSyncSGI)(unsigned int *count); - int (*WaitVideoSyncSGI)(int divisor, int remainder, unsigned int *count); - - /*** GLX_SGI_make_current_read ***/ - Bool (*MakeCurrentReadSGI)(Display *, GLXDrawable, GLXDrawable, GLXContext); - /*GLXDrawable (*GetCurrentReadDrawableSGI)(void);*/ - - /*** GLX_SGIX_video_source (needs video library) ***/ -#if defined(_VL_H_) - GLXVideoSourceSGIX (*CreateGLXVideoSourceSGIX)(Display *, int, VLServer, VLPath, int, VLNode); - void (*DestroyGLXVideoSourceSGIX)(Display *, GLXVideoSourceSGIX); -#else - void *CreateGLXVideoSourceSGIX; - void *DestroyGLXVideoSourceSGIX; -#endif - - /*** GLX_EXT_import_context ***/ - void (*FreeContextEXT)(Display *dpy, GLXContext context); - GLXContextID (*GetContextIDEXT)(const GLXContext context); - /*Display *(*GetCurrentDisplayEXT)(void);*/ - GLXContext (*ImportContextEXT)(Display *dpy, GLXContextID contextID); - int (*QueryContextInfoEXT)(Display *dpy, GLXContext context, int attribute,int *value); - - /*** GLX_SGIX_fbconfig ***/ - int (*GetFBConfigAttribSGIX)(Display *, GLXFBConfigSGIX, int, int *); - GLXFBConfigSGIX * (*ChooseFBConfigSGIX)(Display *, int, int *, int *); - GLXPixmap (*CreateGLXPixmapWithConfigSGIX)(Display *, GLXFBConfigSGIX, Pixmap); - GLXContext (*CreateContextWithConfigSGIX)(Display *, GLXFBConfigSGIX, int, GLXContext, Bool); - XVisualInfo * (*GetVisualFromFBConfigSGIX)(Display *, GLXFBConfigSGIX); - GLXFBConfigSGIX (*GetFBConfigFromVisualSGIX)(Display *, XVisualInfo *); - - /*** GLX_SGIX_pbuffer ***/ - GLXPbufferSGIX (*CreateGLXPbufferSGIX)(Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *); - void (*DestroyGLXPbufferSGIX)(Display *, GLXPbufferSGIX); - int (*QueryGLXPbufferSGIX)(Display *, GLXPbufferSGIX, int, unsigned int *); - void (*SelectEventSGIX)(Display *, GLXDrawable, unsigned long); - void (*GetSelectedEventSGIX)(Display *, GLXDrawable, unsigned long *); - - /*** GLX_SGI_cushion ***/ - void (*CushionSGI)(Display *, Window, float); - - /*** GLX_SGIX_video_resize ***/ - int (*BindChannelToWindowSGIX)(Display *, int, int, Window); - int (*ChannelRectSGIX)(Display *, int, int, int, int, int, int); - int (*QueryChannelRectSGIX)(Display *, int, int, int *, int *, int *, int *); - int (*QueryChannelDeltasSGIX)(Display *, int, int, int *, int *, int *, int *); - int (*ChannelRectSyncSGIX)(Display *, int, int, GLenum); - - /*** GLX_SGIX_dmbuffer (needs dmedia library) ***/ -#if defined (_DM_BUFFER_H_) - Bool (*AssociateDMPbufferSGIX)(Display *, GLXPbufferSGIX, DMparams *, DMbuffer); -#else - void *AssociciateDMPbufferSGIX; -#endif - - /*** GLX_SGIX_swap_group ***/ - void (*JoinSwapGroupSGIX)(Display *, GLXDrawable, GLXDrawable); - - /*** GLX_SGIX_swap_barrier ***/ - void (*BindSwapBarrierSGIX)(Display *, GLXDrawable, int); - Bool (*QueryMaxSwapBarriersSGIX)(Display *, int, int *); - - /*** GLX_SUN_get_transparent_index ***/ - Status (*GetTransparentIndexSUN)(Display *, Window, Window, long *); - - /*** GLX_MESA_copy_sub_buffer ***/ - void (*CopySubBufferMESA)(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); - - /*** GLX_MESA_release_buffers ***/ - Bool (*ReleaseBuffersMESA)(Display *dpy, Window w); - - /*** GLX_MESA_pixmap_colormap ***/ - GLXPixmap (*CreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap); - - /*** GLX_MESA_set_3dfx_mode ***/ - Bool (*Set3DfxModeMESA)(int mode); - - /*** GLX_NV_vertex_array_range ***/ - void * (*AllocateMemoryNV)( GLsizei size, - GLfloat readFrequency, - GLfloat writeFrequency, - GLfloat priority ); - void (*FreeMemoryNV)( GLvoid *pointer ); - - /*** GLX_MESA_agp_offset ***/ - GLuint (*GetAGPOffsetMESA)( const GLvoid *pointer ); - - /*** GLX_EXT_texture_from_pixmap ***/ - void (*BindTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer, - const int *attrib_list); - void (*ReleaseTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer); -}; - - - -extern const char * -_glxapi_get_version(void); - - -extern const char ** -_glxapi_get_extensions(void); - - -extern GLuint -_glxapi_get_dispatch_table_size(void); - - -extern void -_glxapi_set_no_op_table(struct _glxapi_table *t); - - -extern __GLXextFuncPtr -_glxapi_get_proc_address(const char *funcName); - - -#endif diff --git a/src/gallium/winsys/xlib/glxheader.h b/src/gallium/winsys/xlib/glxheader.h deleted file mode 100644 index a402191f13..0000000000 --- a/src/gallium/winsys/xlib/glxheader.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.1 - * - * Copyright (C) 1999-2006 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - - -#ifndef GLX_HEADER_H -#define GLX_HEADER_H - -#ifdef __VMS -#include -#endif - -#include "glheader.h" - -#ifdef XFree86Server - -# include "resource.h" -# include "windowstr.h" - -#else - -# include -# include -# include -# ifdef USE_XSHM /* was SHM */ -# include -# include -# include -# endif -# include -# include - -#endif - - - -/* this silences a compiler warning on several systems */ -struct timespec; -struct itimerspec; - - -#endif /*GLX_HEADER*/ diff --git a/src/gallium/winsys/xlib/realglx.c b/src/gallium/winsys/xlib/realglx.c deleted file mode 100644 index 30adb7465b..0000000000 --- a/src/gallium/winsys/xlib/realglx.c +++ /dev/null @@ -1,180 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2002 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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 -#include -#include "realglx.h" -#include "glxapi.h" - - -struct _glxapi_table * -_real_GetGLXDispatchTable(void) -{ - static struct _glxapi_table glx; - - /* be sure our dispatch table size <= libGL's table */ - { - GLuint size = sizeof(struct _glxapi_table) / sizeof(void *); - (void) size; - assert(_glxapi_get_dispatch_table_size() >= size); - } - - /* initialize the whole table to no-ops */ - _glxapi_set_no_op_table(&glx); - - /* now initialize the table with the functions I implement */ - - /*** GLX_VERSION_1_0 ***/ - glx.ChooseVisual = _real_glXChooseVisual; - glx.CopyContext = _real_glXCopyContext; - glx.CreateContext = _real_glXCreateContext; - glx.CreateGLXPixmap = _real_glXCreateGLXPixmap; - glx.DestroyContext = _real_glXDestroyContext; - glx.DestroyGLXPixmap = _real_glXDestroyGLXPixmap; - glx.GetConfig = _real_glXGetConfig; - /*glx.GetCurrentContext = _real_glXGetCurrentContext;*/ - /*glx.GetCurrentDrawable = _real_glXGetCurrentDrawable;*/ - glx.IsDirect = _real_glXIsDirect; - glx.MakeCurrent = _real_glXMakeCurrent; - glx.QueryExtension = _real_glXQueryExtension; - glx.QueryVersion = _real_glXQueryVersion; - glx.SwapBuffers = _real_glXSwapBuffers; - glx.UseXFont = _real_glXUseXFont; - glx.WaitGL = _real_glXWaitGL; - glx.WaitX = _real_glXWaitX; - - /*** GLX_VERSION_1_1 ***/ - glx.GetClientString = _real_glXGetClientString; - glx.QueryExtensionsString = _real_glXQueryExtensionsString; - glx.QueryServerString = _real_glXQueryServerString; - - /*** GLX_VERSION_1_2 ***/ - /*glx.GetCurrentDisplay = _real_glXGetCurrentDisplay;*/ - - /*** GLX_VERSION_1_3 ***/ - glx.ChooseFBConfig = _real_glXChooseFBConfig; - glx.CreateNewContext = _real_glXCreateNewContext; - glx.CreatePbuffer = _real_glXCreatePbuffer; - glx.CreatePixmap = _real_glXCreatePixmap; - glx.CreateWindow = _real_glXCreateWindow; - glx.DestroyPbuffer = _real_glXDestroyPbuffer; - glx.DestroyPixmap = _real_glXDestroyPixmap; - glx.DestroyWindow = _real_glXDestroyWindow; - /*glx.GetCurrentReadDrawable = _real_glXGetCurrentReadDrawable;*/ - glx.GetFBConfigAttrib = _real_glXGetFBConfigAttrib; - glx.GetFBConfigs = _real_glXGetFBConfigs; - glx.GetSelectedEvent = _real_glXGetSelectedEvent; - glx.GetVisualFromFBConfig = _real_glXGetVisualFromFBConfig; - glx.MakeContextCurrent = _real_glXMakeContextCurrent; - glx.QueryContext = _real_glXQueryContext; - glx.QueryDrawable = _real_glXQueryDrawable; - glx.SelectEvent = _real_glXSelectEvent; - - /*** GLX_SGI_swap_control ***/ - glx.SwapIntervalSGI = _real_glXSwapIntervalSGI; - - /*** GLX_SGI_video_sync ***/ - glx.GetVideoSyncSGI = _real_glXGetVideoSyncSGI; - glx.WaitVideoSyncSGI = _real_glXWaitVideoSyncSGI; - - /*** GLX_SGI_make_current_read ***/ - glx.MakeCurrentReadSGI = _real_glXMakeCurrentReadSGI; - /*glx.GetCurrentReadDrawableSGI = _real_glXGetCurrentReadDrawableSGI;*/ - -#if defined(_VL_H) - /*** GLX_SGIX_video_source ***/ - glx.CreateGLXVideoSourceSGIX = _real_glXCreateGLXVideoSourceSGIX; - glx.DestroyGLXVideoSourceSGIX = _real_glXDestroyGLXVideoSourceSGIX; -#endif - - /*** GLX_EXT_import_context ***/ - glx.FreeContextEXT = _real_glXFreeContextEXT; - /*glx.GetContextIDEXT = _real_glXGetContextIDEXT;*/ - /*glx.GetCurrentDisplayEXT = _real_glXGetCurrentDisplayEXT;*/ - glx.ImportContextEXT = _real_glXImportContextEXT; - glx.QueryContextInfoEXT = _real_glXQueryContextInfoEXT; - - /*** GLX_SGIX_fbconfig ***/ - glx.GetFBConfigAttribSGIX = _real_glXGetFBConfigAttribSGIX; - glx.ChooseFBConfigSGIX = _real_glXChooseFBConfigSGIX; - glx.CreateGLXPixmapWithConfigSGIX = _real_glXCreateGLXPixmapWithConfigSGIX; - glx.CreateContextWithConfigSGIX = _real_glXCreateContextWithConfigSGIX; - glx.GetVisualFromFBConfigSGIX = _real_glXGetVisualFromFBConfigSGIX; - glx.GetFBConfigFromVisualSGIX = _real_glXGetFBConfigFromVisualSGIX; - - /*** GLX_SGIX_pbuffer ***/ - glx.CreateGLXPbufferSGIX = _real_glXCreateGLXPbufferSGIX; - glx.DestroyGLXPbufferSGIX = _real_glXDestroyGLXPbufferSGIX; - glx.QueryGLXPbufferSGIX = _real_glXQueryGLXPbufferSGIX; - glx.SelectEventSGIX = _real_glXSelectEventSGIX; - glx.GetSelectedEventSGIX = _real_glXGetSelectedEventSGIX; - - /*** GLX_SGI_cushion ***/ - glx.CushionSGI = _real_glXCushionSGI; - - /*** GLX_SGIX_video_resize ***/ - glx.BindChannelToWindowSGIX = _real_glXBindChannelToWindowSGIX; - glx.ChannelRectSGIX = _real_glXChannelRectSGIX; - glx.QueryChannelRectSGIX = _real_glXQueryChannelRectSGIX; - glx.QueryChannelDeltasSGIX = _real_glXQueryChannelDeltasSGIX; - glx.ChannelRectSyncSGIX = _real_glXChannelRectSyncSGIX; - -#if defined(_DM_BUFFER_H_) - /*** (GLX_SGIX_dmbuffer ***/ - glx.AssociateDMPbufferSGIX = NULL; -#endif - - /*** GLX_SGIX_swap_group ***/ - glx.JoinSwapGroupSGIX = _real_glXJoinSwapGroupSGIX; - - /*** GLX_SGIX_swap_barrier ***/ - glx.BindSwapBarrierSGIX = _real_glXBindSwapBarrierSGIX; - glx.QueryMaxSwapBarriersSGIX = _real_glXQueryMaxSwapBarriersSGIX; - - /*** GLX_SUN_get_transparent_index ***/ - glx.GetTransparentIndexSUN = _real_glXGetTransparentIndexSUN; - - /*** GLX_MESA_copy_sub_buffer ***/ - glx.CopySubBufferMESA = _real_glXCopySubBufferMESA; - - /*** GLX_MESA_release_buffers ***/ - glx.ReleaseBuffersMESA = _real_glXReleaseBuffersMESA; - - /*** GLX_MESA_pixmap_colormap ***/ - glx.CreateGLXPixmapMESA = _real_glXCreateGLXPixmapMESA; - - /*** GLX_MESA_set_3dfx_mode ***/ - glx.Set3DfxModeMESA = _real_glXSet3DfxModeMESA; - - /*** GLX_NV_vertex_array_range ***/ - glx.AllocateMemoryNV = _real_glXAllocateMemoryNV; - glx.FreeMemoryNV = _real_glXFreeMemoryNV; - - /*** GLX_MESA_agp_offset ***/ - glx.GetAGPOffsetMESA = _real_glXGetAGPOffsetMESA; - - return &glx; -} diff --git a/src/gallium/winsys/xlib/realglx.h b/src/gallium/winsys/xlib/realglx.h deleted file mode 100644 index 150129db68..0000000000 --- a/src/gallium/winsys/xlib/realglx.h +++ /dev/null @@ -1,326 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - - -#ifndef REALGLX_H -#define REALGLX_H - - -extern struct _glxapi_table * -_real_GetGLXDispatchTable(void); - - -/* - * Basically just need these to prevent compiler warnings. - */ - - -extern XVisualInfo * -_real_glXChooseVisual( Display *dpy, int screen, int *list ); - -extern GLXContext -_real_glXCreateContext( Display *dpy, XVisualInfo *visinfo, - GLXContext share_list, Bool direct ); - -extern GLXPixmap -_real_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ); - -extern GLXPixmap -_real_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, - Pixmap pixmap, Colormap cmap ); - -extern void -_real_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ); - -extern void -_real_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, - unsigned long mask ); - -extern Bool -_real_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ); - -extern Bool -_real_glXQueryExtension( Display *dpy, int *errorb, int *event ); - -extern void -_real_glXDestroyContext( Display *dpy, GLXContext ctx ); - -extern Bool -_real_glXIsDirect( Display *dpy, GLXContext ctx ); - -extern void -_real_glXSwapBuffers( Display *dpy, GLXDrawable drawable ); - -extern void -_real_glXUseXFont( Font font, int first, int count, int listbase ); - -extern Bool -_real_glXQueryVersion( Display *dpy, int *maj, int *min ); - -extern int -_real_glXGetConfig( Display *dpy, XVisualInfo *visinfo, - int attrib, int *value ); - -extern void -_real_glXWaitGL( void ); - - -extern void -_real_glXWaitX( void ); - -/* GLX 1.1 and later */ -extern const char * -_real_glXQueryExtensionsString( Display *dpy, int screen ); - -/* GLX 1.1 and later */ -extern const char * -_real_glXQueryServerString( Display *dpy, int screen, int name ); - -/* GLX 1.1 and later */ -extern const char * -_real_glXGetClientString( Display *dpy, int name ); - - -/* - * GLX 1.3 and later - */ - -extern GLXFBConfig * -_real_glXChooseFBConfig( Display *dpy, int screen, - const int *attribList, int *nitems ); - -extern int -_real_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, - int attribute, int *value ); - -extern GLXFBConfig * -_real_glXGetFBConfigs( Display *dpy, int screen, int *nelements ); - -extern XVisualInfo * -_real_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ); - -extern GLXWindow -_real_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, - const int *attribList ); - -extern void -_real_glXDestroyWindow( Display *dpy, GLXWindow window ); - -extern GLXPixmap -_real_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, - const int *attribList ); - -extern void -_real_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ); - -extern GLXPbuffer -_real_glXCreatePbuffer( Display *dpy, GLXFBConfig config, - const int *attribList ); - -extern void -_real_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ); - -extern void -_real_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, - unsigned int *value ); - -extern GLXContext -_real_glXCreateNewContext( Display *dpy, GLXFBConfig config, - int renderType, GLXContext shareList, Bool direct ); - - -extern Bool -_real_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext ctx ); - -extern int -_real_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ); - -extern void -_real_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ); - -extern void -_real_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, - unsigned long *mask ); - -#ifdef GLX_SGI_swap_control -extern int -_real_glXSwapIntervalSGI(int interval); -#endif - - -#ifdef GLX_SGI_video_sync -extern int -_real_glXGetVideoSyncSGI(unsigned int *count); - -extern int -_real_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count); -#endif - - -#ifdef GLX_SGI_make_current_read -extern Bool -_real_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); - -extern GLXDrawable -_real_glXGetCurrentReadDrawableSGI(void); -#endif - -#if defined(_VL_H) && defined(GLX_SGIX_video_source) -extern GLXVideoSourceSGIX -_real_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode); - -extern void -_real_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src); -#endif - -#ifdef GLX_EXT_import_context -extern void -_real_glXFreeContextEXT(Display *dpy, GLXContext context); - -extern GLXContextID -_real_glXGetContextIDEXT(const GLXContext context); - -extern Display * -_real_glXGetCurrentDisplayEXT(void); - -extern GLXContext -_real_glXImportContextEXT(Display *dpy, GLXContextID contextID); - -extern int -_real_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value); -#endif - -#ifdef GLX_SGIX_fbconfig -extern int -_real_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); - -extern GLXFBConfigSGIX * -_real_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements); - -extern GLXPixmap -_real_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); - -extern GLXContext -_real_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); - -extern XVisualInfo * -_real_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config); - -extern GLXFBConfigSGIX -_real_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis); -#endif - -#ifdef GLX_SGIX_pbuffer -extern GLXPbufferSGIX -_real_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); - -extern void -_real_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf); - -extern int -_real_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); - -extern void -_real_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask); - -extern void -_real_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask); -#endif - -#ifdef GLX_SGI_cushion -extern void -_real_glXCushionSGI(Display *dpy, Window win, float cushion); -#endif - -#ifdef GLX_SGIX_video_resize -extern int -_real_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window); - -extern int -_real_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h); - -extern int -_real_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h); - -extern int -_real_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh); - -extern int -_real_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype); -#endif - -#if defined(_DM_BUFFER_H_) && defined(GLX_SGIX_dmbuffer) -extern Bool -_real_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer); -#endif - -#ifdef GLX_SGIX_swap_group -extern void -_real_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member); -#endif - -#ifdef GLX_SGIX_swap_barrier -extern void -_real_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier); - -extern Bool -_real_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max); -#endif - -#ifdef GLX_SUN_get_transparent_index -extern Status -_real_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent); -#endif - -#ifdef GLX_MESA_release_buffers -extern Bool -_real_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ); -#endif - -#ifdef GLX_MESA_set_3dfx_mode -extern Bool -_real_glXSet3DfxModeMESA( int mode ); -#endif - -#ifdef GLX_NV_vertex_array_range -extern void * -_real_glXAllocateMemoryNV(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -extern void -_real_glXFreeMemoryNV(GLvoid *pointer); -#endif - -#ifdef GLX_MESA_agp_offset -extern GLuint -_real_glXGetAGPOffsetMESA(const GLvoid *pointer); -#endif - -#ifdef GLX_MESA_copy_sub_buffer -extern void -_real_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, - int x, int y, int width, int height ); -#endif - -#endif /* REALGLX_H */ diff --git a/src/gallium/winsys/xlib/xfonts.c b/src/gallium/winsys/xlib/xfonts.c deleted file mode 100644 index d72c600bd1..0000000000 --- a/src/gallium/winsys/xlib/xfonts.c +++ /dev/null @@ -1,377 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2000 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - - -/* xfonts.c -- glXUseXFont() for Mesa written by - * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de - */ - -#ifdef __VMS -#include -#endif - -#include "glxheader.h" -#include "context.h" -#include "imports.h" -#include "xfonts.h" - - -/* Some debugging info. */ - -#ifdef DEBUG -#undef _R -#undef _G -#undef _B -#include - -int debug_xfonts = 0; - -static void -dump_char_struct(XCharStruct * ch, char *prefix) -{ - printf("%slbearing = %d, rbearing = %d, width = %d\n", - prefix, ch->lbearing, ch->rbearing, ch->width); - printf("%sascent = %d, descent = %d, attributes = %u\n", - prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes); -} - -static void -dump_font_struct(XFontStruct * font) -{ - printf("ascent = %d, descent = %d\n", font->ascent, font->descent); - printf("char_or_byte2 = (%u,%u)\n", - font->min_char_or_byte2, font->max_char_or_byte2); - printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1); - printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False"); - printf("default_char = %c (\\%03o)\n", - (char) (isprint(font->default_char) ? font->default_char : ' '), - font->default_char); - dump_char_struct(&font->min_bounds, "min> "); - dump_char_struct(&font->max_bounds, "max> "); -#if 0 - for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) { - char prefix[8]; - sprintf(prefix, "%d> ", c); - dump_char_struct(&font->per_char[c], prefix); - } -#endif -} - -static void -dump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap) -{ - unsigned int x, y; - - printf(" "); - for (x = 0; x < 8 * width; x++) - printf("%o", 7 - (x % 8)); - putchar('\n'); - for (y = 0; y < height; y++) { - printf("%3o:", y); - for (x = 0; x < 8 * width; x++) - putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x % - 8)))) - ? '*' : '.'); - printf(" "); - for (x = 0; x < width; x++) - printf("0x%02x, ", bitmap[width * (height - y - 1) + x]); - putchar('\n'); - } -} -#endif /* DEBUG */ - - -/* Implementation. */ - -/* Fill a BITMAP with a character C from thew current font - in the graphics context GC. WIDTH is the width in bytes - and HEIGHT is the height in bits. - - Note that the generated bitmaps must be used with - - glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE); - glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); - glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - - Possible optimizations: - - * use only one reusable pixmap with the maximum dimensions. - * draw the entire font into a single pixmap (careful with - proportional fonts!). -*/ - - -/* - * Generate OpenGL-compatible bitmap. - */ -static void -fill_bitmap(Display * dpy, Window win, GC gc, - unsigned int width, unsigned int height, - int x0, int y0, unsigned int c, GLubyte * bitmap) -{ - XImage *image; - unsigned int x, y; - Pixmap pixmap; - XChar2b char2b; - - pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1); - XSetForeground(dpy, gc, 0); - XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height); - XSetForeground(dpy, gc, 1); - - char2b.byte1 = (c >> 8) & 0xff; - char2b.byte2 = (c & 0xff); - - XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1); - - image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap); - if (image) { - /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */ - for (y = 0; y < height; y++) - for (x = 0; x < 8 * width; x++) - if (XGetPixel(image, x, y)) - bitmap[width * (height - y - 1) + x / 8] |= - (1 << (7 - (x % 8))); - XDestroyImage(image); - } - - XFreePixmap(dpy, pixmap); -} - -/* - * determine if a given glyph is valid and return the - * corresponding XCharStruct. - */ -static XCharStruct * -isvalid(XFontStruct * fs, unsigned int which) -{ - unsigned int rows, pages; - unsigned int byte1 = 0, byte2 = 0; - int i, valid = 1; - - rows = fs->max_byte1 - fs->min_byte1 + 1; - pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; - - if (rows == 1) { - /* "linear" fonts */ - if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which)) - valid = 0; - } - else { - /* "matrix" fonts */ - byte2 = which & 0xff; - byte1 = which >> 8; - if ((fs->min_char_or_byte2 > byte2) || - (fs->max_char_or_byte2 < byte2) || - (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1)) - valid = 0; - } - - if (valid) { - if (fs->per_char) { - if (rows == 1) { - /* "linear" fonts */ - return (fs->per_char + (which - fs->min_char_or_byte2)); - } - else { - /* "matrix" fonts */ - i = ((byte1 - fs->min_byte1) * pages) + - (byte2 - fs->min_char_or_byte2); - return (fs->per_char + i); - } - } - else { - return (&fs->min_bounds); - } - } - return (NULL); -} - - -void -Fake_glXUseXFont(Font font, int first, int count, int listbase) -{ - Display *dpy; - Window win; - Pixmap pixmap; - GC gc; - XGCValues values; - unsigned long valuemask; - XFontStruct *fs; - GLint swapbytes, lsbfirst, rowlength; - GLint skiprows, skippixels, alignment; - unsigned int max_width, max_height, max_bm_width, max_bm_height; - GLubyte *bm; - int i; - - dpy = glXGetCurrentDisplay(); - if (!dpy) - return; /* I guess glXMakeCurrent wasn't called */ - win = RootWindow(dpy, DefaultScreen(dpy)); - - fs = XQueryFont(dpy, font); - if (!fs) { - _mesa_error(NULL, GL_INVALID_VALUE, - "Couldn't get font structure information"); - return; - } - - /* Allocate a bitmap that can fit all characters. */ - max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing; - max_height = fs->max_bounds.ascent + fs->max_bounds.descent; - max_bm_width = (max_width + 7) / 8; - max_bm_height = max_height; - - bm = (GLubyte *) MALLOC((max_bm_width * max_bm_height) * sizeof(GLubyte)); - if (!bm) { - XFreeFontInfo(NULL, fs, 1); - _mesa_error(NULL, GL_OUT_OF_MEMORY, - "Couldn't allocate bitmap in glXUseXFont()"); - return; - } - -#if 0 - /* get the page info */ - pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; - firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2; - lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2; - rows = fs->max_byte1 - fs->min_byte1 + 1; - unsigned int first_char, last_char, pages, rows; -#endif - - /* Save the current packing mode for bitmaps. */ - glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes); - glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst); - glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength); - glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows); - glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels); - glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); - - /* Enforce a standard packing mode which is compatible with - fill_bitmap() from above. This is actually the default mode, - except for the (non)alignment. */ - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - pixmap = XCreatePixmap(dpy, win, 10, 10, 1); - values.foreground = BlackPixel(dpy, DefaultScreen(dpy)); - values.background = WhitePixel(dpy, DefaultScreen(dpy)); - values.font = fs->fid; - valuemask = GCForeground | GCBackground | GCFont; - gc = XCreateGC(dpy, pixmap, valuemask, &values); - XFreePixmap(dpy, pixmap); - -#ifdef DEBUG - if (debug_xfonts) - dump_font_struct(fs); -#endif - - for (i = 0; i < count; i++) { - unsigned int width, height, bm_width, bm_height; - GLfloat x0, y0, dx, dy; - XCharStruct *ch; - int x, y; - unsigned int c = first + i; - int list = listbase + i; - int valid; - - /* check on index validity and get the bounds */ - ch = isvalid(fs, c); - if (!ch) { - ch = &fs->max_bounds; - valid = 0; - } - else { - valid = 1; - } - -#ifdef DEBUG - if (debug_xfonts) { - char s[7]; - sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c); - dump_char_struct(ch, s); - } -#endif - - /* glBitmap()' parameters: - straight from the glXUseXFont(3) manpage. */ - width = ch->rbearing - ch->lbearing; - height = ch->ascent + ch->descent; - x0 = -ch->lbearing; - y0 = ch->descent - 0; /* XXX used to subtract 1 here */ - /* but that caused a conformace failure */ - dx = ch->width; - dy = 0; - - /* X11's starting point. */ - x = -ch->lbearing; - y = ch->ascent; - - /* Round the width to a multiple of eight. We will use this also - for the pixmap for capturing the X11 font. This is slightly - inefficient, but it makes the OpenGL part real easy. */ - bm_width = (width + 7) / 8; - bm_height = height; - - glNewList(list, GL_COMPILE); - if (valid && (bm_width > 0) && (bm_height > 0)) { - - MEMSET(bm, '\0', bm_width * bm_height); - fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm); - - glBitmap(width, height, x0, y0, dx, dy, bm); -#ifdef DEBUG - if (debug_xfonts) { - printf("width/height = %u/%u\n", width, height); - printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height); - dump_bitmap(bm_width, bm_height, bm); - } -#endif - } - else { - glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL); - } - glEndList(); - } - - FREE(bm); - XFreeFontInfo(NULL, fs, 1); - XFreeGC(dpy, gc); - - /* Restore saved packing modes. */ - glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); - glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst); - glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength); - glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); - glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); -} diff --git a/src/gallium/winsys/xlib/xfonts.h b/src/gallium/winsys/xlib/xfonts.h deleted file mode 100644 index e36f42f817..0000000000 --- a/src/gallium/winsys/xlib/xfonts.h +++ /dev/null @@ -1,41 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2000 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - - -#ifndef XFONTS_H -#define XFONTS_H - -#ifdef __VMS -#include -#endif - -#include - - -extern void Fake_glXUseXFont( Font font, int first, int count, int listbase ); - - -#endif - diff --git a/src/gallium/winsys/xlib/xlib.c b/src/gallium/winsys/xlib/xlib.c new file mode 100644 index 0000000000..8d4d734b03 --- /dev/null +++ b/src/gallium/winsys/xlib/xlib.c @@ -0,0 +1,165 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/* + * Authors: + * Keith Whitwell + */ + +#include "xlib_trace.h" +#include "xlib_softpipe.h" +#include "xlib_brw.h" +#include "xm_winsys.h" + +#include +#include + +/* Todo, replace all this with callback-structs provided by the + * individual implementations. + */ + +enum mode { + MODE_TRACE, + MODE_BRW, + MODE_CELL, + MODE_SOFTPIPE +}; + +static enum mode xlib_mode; + +static enum mode get_mode() +{ + if (getenv("XMESA_TRACE")) + return MODE_TRACE; + + if (getenv("XMESA_BRW")) + return MODE_BRW; + +#ifdef GALLIUM_CELL + if (!getenv("GALLIUM_NOCELL")) + return MODE_CELL; +#endif + + return MODE_SOFTPIPE; +} + + +struct pipe_winsys * +xmesa_create_pipe_winsys( void ) +{ + xlib_mode = get_mode(); + + switch (xlib_mode) { + case MODE_TRACE: + return xlib_create_trace_winsys(); + case MODE_BRW: + return xlib_create_brw_winsys(); + case MODE_CELL: + return xlib_create_cell_winsys(); + case MODE_SOFTPIPE: + return xlib_create_softpipe_winsys(); + default: + assert(0); + return NULL; + } +} + +struct pipe_screen * +xmesa_create_pipe_screen( struct pipe_winsys *winsys ) +{ + switch (xlib_mode) { + case MODE_TRACE: + return xlib_create_trace_screen( winsys ); + case MODE_BRW: + return xlib_create_brw_screen( winsys ); + case MODE_CELL: + return xlib_create_cell_screen( winsys ); + case MODE_SOFTPIPE: + return xlib_create_softpipe_screen( winsys ); + default: + assert(0); + return NULL; + } +} + +struct pipe_context * +xmesa_create_pipe_context( struct pipe_screen *screen, + void *priv ) +{ + switch (xlib_mode) { + case MODE_TRACE: + return xlib_create_trace_context( screen, priv ); + case MODE_BRW: + return xlib_create_brw_context( screen, priv ); + case MODE_CELL: + return xlib_create_cell_context( screen, priv ); + case MODE_SOFTPIPE: + return xlib_create_softpipe_context( screen, priv ); + default: + assert(0); + return NULL; + } +} + +void +xmesa_display_surface( struct xmesa_buffer *buffer, + struct pipe_surface *surf ) +{ + switch (xlib_mode) { + case MODE_TRACE: + xlib_trace_display_surface( buffer, surf ); + break; + case MODE_BRW: + xlib_brw_display_surface( buffer, surf ); + break; + case MODE_CELL: + xlib_cell_display_surface( buffer, surf ); + break; + case MODE_SOFTPIPE: + xlib_softpipe_display_surface( buffer, surf ); + break; + default: + assert(0); + break; + } +} + + + +/*********************************************************************** + * + * Butt-ugly hack to convince the linker not to throw away public GL + * symbols (they are all referenced from getprocaddress, I guess). + */ +extern void (*linker_foo(const unsigned char *procName))(); +extern void (*glXGetProcAddress(const unsigned char *procName))(); + +extern void (*linker_foo(const unsigned char *procName))() +{ + return glXGetProcAddress(procName); +} diff --git a/src/gallium/winsys/xlib/xlib_brw.h b/src/gallium/winsys/xlib/xlib_brw.h new file mode 100644 index 0000000000..aad3f229bf --- /dev/null +++ b/src/gallium/winsys/xlib/xlib_brw.h @@ -0,0 +1,40 @@ +#ifndef XLIB_BRW_H +#define XLIB_BRW_H + +struct pipe_winsys; +struct pipe_buffer; +struct pipe_surface; +struct xmesa_buffer; + +struct pipe_winsys *xlib_create_brw_winsys( void ); + +struct pipe_screen *xlib_create_brw_screen( struct pipe_winsys * ); + +struct pipe_context *xlib_create_brw_context( struct pipe_screen *, + void *priv ); + +void xlib_brw_display_surface(struct xmesa_buffer *b, + struct pipe_surface *surf); + +/*********************************************************************** + * Internal functions + */ + +unsigned xlib_brw_get_buffer_offset( struct pipe_winsys *pws, + struct pipe_buffer *buf, + unsigned access_flags ); + +void xlib_brw_buffer_subdata_typed( struct pipe_winsys *pws, + struct pipe_buffer *buf, + unsigned long offset, + unsigned long size, + const void *data, + unsigned data_type ); + + + +void xlib_brw_commands_aub(struct pipe_winsys *winsys, + unsigned *cmds, + unsigned nr_dwords); + +#endif diff --git a/src/gallium/winsys/xlib/xlib_brw_aub.c b/src/gallium/winsys/xlib/xlib_brw_aub.c new file mode 100644 index 0000000000..2956e1b960 --- /dev/null +++ b/src/gallium/winsys/xlib/xlib_brw_aub.c @@ -0,0 +1,397 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + 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, sublicense, 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 NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include +#include +#include "xlib_brw_aub.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_debug.h" +#include "util/u_memory.h" + + +struct brw_aubfile { + FILE *file; + unsigned next_free_page; +}; + + +extern char *__progname; + + +struct aub_file_header { + unsigned int instruction_type; + unsigned int pad0:16; + unsigned int minor:8; + unsigned int major:8; + unsigned char application[8*4]; + unsigned int day:8; + unsigned int month:8; + unsigned int year:16; + unsigned int timezone:8; + unsigned int second:8; + unsigned int minute:8; + unsigned int hour:8; + unsigned int comment_length:16; + unsigned int pad1:16; +}; + +struct aub_block_header { + unsigned int instruction_type; + unsigned int operation:8; + unsigned int type:8; + unsigned int address_space:8; + unsigned int pad0:8; + unsigned int general_state_type:8; + unsigned int surface_state_type:8; + unsigned int pad1:16; + unsigned int address; + unsigned int length; +}; + +struct aub_dump_bmp { + unsigned int instruction_type; + unsigned int xmin:16; + unsigned int ymin:16; + unsigned int pitch:16; + unsigned int bpp:8; + unsigned int format:8; + unsigned int xsize:16; + unsigned int ysize:16; + unsigned int addr; + unsigned int unknown; +}; + +enum bh_operation { + BH_COMMENT, + BH_DATA_WRITE, + BH_COMMAND_WRITE, + BH_MMI0_WRITE32, + BH_END_SCENE, + BH_CONFIG_MEMORY_MAP, + BH_MAX_OPERATION +}; + +enum command_write_type { + CW_HWB_RING = 1, + CW_PRIMARY_RING_A, + CW_PRIMARY_RING_B, /* XXX - disagreement with listaub! */ + CW_PRIMARY_RING_C, + CW_MAX_TYPE +}; + +enum memory_map_type { + MM_DEFAULT, + MM_DYNAMIC, + MM_MAX_TYPE +}; + +enum address_space { + ADDR_GTT, + ADDR_LOCAL, + ADDR_MAIN, + ADDR_MAX +}; + + +#define AUB_FILE_HEADER 0xe085000b +#define AUB_BLOCK_HEADER 0xe0c10003 +#define AUB_DUMP_BMP 0xe09e0004 + +/* Registers to control page table + */ +#define PGETBL_CTL 0x2020 +#define PGETBL_ENABLED 0x1 + +#define NR_GTT_ENTRIES 65536 /* 256 mb */ + +#define FAIL \ +do { \ + fprintf(stderr, "failed to write aub data at %s/%d\n", __FUNCTION__, __LINE__); \ + exit(1); \ +} while (0) + + +/* Emit the headers at the top of each aubfile. Initialize the GTT. + */ +static void init_aubfile( FILE *aub_file ) +{ + struct aub_file_header fh; + struct aub_block_header bh; + unsigned int data; + + static int nr; + + nr++; + + /* Emit the aub header: + */ + memset(&fh, 0, sizeof(fh)); + + fh.instruction_type = AUB_FILE_HEADER; + fh.minor = 0x0; + fh.major = 0x7; + memcpy(fh.application, __progname, sizeof(fh.application)); + fh.day = (nr>>24) & 0xff; + fh.month = 0x0; + fh.year = 0x0; + fh.timezone = 0x0; + fh.second = nr & 0xff; + fh.minute = (nr>>8) & 0xff; + fh.hour = (nr>>16) & 0xff; + fh.comment_length = 0x0; + + if (fwrite(&fh, sizeof(fh), 1, aub_file) < 0) + FAIL; + + /* Setup the GTT starting at main memory address zero (!): + */ + memset(&bh, 0, sizeof(bh)); + + bh.instruction_type = AUB_BLOCK_HEADER; + bh.operation = BH_MMI0_WRITE32; + bh.type = 0x0; + bh.address_space = ADDR_GTT; /* ??? */ + bh.general_state_type = 0x0; + bh.surface_state_type = 0x0; + bh.address = PGETBL_CTL; + bh.length = 0x4; + + if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) + FAIL; + + data = 0x0 | PGETBL_ENABLED; + + if (fwrite(&data, sizeof(data), 1, aub_file) < 0) + FAIL; +} + + +static void init_aub_gtt( struct brw_aubfile *aubfile, + unsigned start_offset, + unsigned size ) +{ + FILE *aub_file = aubfile->file; + struct aub_block_header bh; + unsigned int i; + + assert(start_offset + size < NR_GTT_ENTRIES * 4096); + + + memset(&bh, 0, sizeof(bh)); + + bh.instruction_type = AUB_BLOCK_HEADER; + bh.operation = BH_DATA_WRITE; + bh.type = 0x0; + bh.address_space = ADDR_MAIN; + bh.general_state_type = 0x0; + bh.surface_state_type = 0x0; + bh.address = start_offset / 4096 * 4; + bh.length = size / 4096 * 4; + + if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) + FAIL; + + for (i = 0; i < size / 4096; i++) { + unsigned data = aubfile->next_free_page | 1; + + aubfile->next_free_page += 4096; + + if (fwrite(&data, sizeof(data), 1, aub_file) < 0) + FAIL; + } + +} + +static void write_block_header( FILE *aub_file, + struct aub_block_header *bh, + const unsigned *data, + unsigned sz ) +{ + sz = (sz + 3) & ~3; + + if (fwrite(bh, sizeof(*bh), 1, aub_file) < 0) + FAIL; + + if (fwrite(data, sz, 1, aub_file) < 0) + FAIL; + + fflush(aub_file); +} + + +static void write_dump_bmp( FILE *aub_file, + struct aub_dump_bmp *db ) +{ + if (fwrite(db, sizeof(*db), 1, aub_file) < 0) + FAIL; + + fflush(aub_file); +} + + + +void brw_aub_gtt_data( struct brw_aubfile *aubfile, + unsigned offset, + const void *data, + unsigned sz, + unsigned type, + unsigned state_type ) +{ + struct aub_block_header bh; + + bh.instruction_type = AUB_BLOCK_HEADER; + bh.operation = BH_DATA_WRITE; + bh.type = type; + bh.address_space = ADDR_GTT; + bh.pad0 = 0; + + if (type == DW_GENERAL_STATE) { + bh.general_state_type = state_type; + bh.surface_state_type = 0; + } + else { + bh.general_state_type = 0; + bh.surface_state_type = state_type; + } + + bh.pad1 = 0; + bh.address = offset; + bh.length = sz; + + write_block_header(aubfile->file, &bh, data, sz); +} + + + +void brw_aub_gtt_cmds( struct brw_aubfile *aubfile, + unsigned offset, + const void *data, + unsigned sz ) +{ + struct aub_block_header bh; + unsigned type = CW_PRIMARY_RING_A; + + + bh.instruction_type = AUB_BLOCK_HEADER; + bh.operation = BH_COMMAND_WRITE; + bh.type = type; + bh.address_space = ADDR_GTT; + bh.pad0 = 0; + bh.general_state_type = 0; + bh.surface_state_type = 0; + bh.pad1 = 0; + bh.address = offset; + bh.length = sz; + + write_block_header(aubfile->file, &bh, data, sz); +} + +void brw_aub_dump_bmp( struct brw_aubfile *aubfile, + struct pipe_surface *surface, + unsigned gtt_offset ) +{ + struct aub_dump_bmp db; + unsigned format; + + assert(surface->block.width == 1); + assert(surface->block.height == 1); + + if (surface->block.size == 4) + format = 0x7; + else + format = 0x3; + + db.instruction_type = AUB_DUMP_BMP; + db.xmin = 0; + db.ymin = 0; + db.format = format; + db.bpp = surface->block.size * 8; + db.pitch = surface->stride/surface->block.size; + db.xsize = surface->width; + db.ysize = surface->height; + db.addr = gtt_offset; + db.unknown = /* surface->tiled ? 0x4 : */ 0x0; + + write_dump_bmp(aubfile->file, &db); +} + + + +struct brw_aubfile *brw_aubfile_create( void ) +{ + struct brw_aubfile *aubfile = CALLOC_STRUCT(brw_aubfile); + char filename[80]; + int val; + static int i = 0; + + i++; + + if (getenv("INTEL_AUBFILE")) { + val = snprintf(filename, sizeof(filename), "%s%d.aub", getenv("INTEL_AUBFILE"), i%4); + debug_printf("--> Aub file: %s\n", filename); + aubfile->file = fopen(filename, "w"); + } + else { + val = snprintf(filename, sizeof(filename), "%s.aub", __progname); + if (val < 0 || val > sizeof(filename)) + strcpy(filename, "default.aub"); + + debug_printf("--> Aub file: %s\n", filename); + aubfile->file = fopen(filename, "w"); + } + + if (!aubfile->file) { + debug_printf("couldn't open aubfile\n"); + exit(1); + } + + init_aubfile(aubfile->file); + + /* The GTT is located starting address zero in main memory. Pages + * to populate the gtt start after this point. + */ + aubfile->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095; + + /* More or less correspond with all the agp regions mapped by the + * driver: + */ + init_aub_gtt(aubfile, 0, 4096*4); + init_aub_gtt(aubfile, AUB_BUF_START, AUB_BUF_SIZE); + + return aubfile; +} + +void brw_aub_destroy( struct brw_aubfile *aubfile ) +{ + fclose(aubfile->file); + FREE(aubfile); +} diff --git a/src/gallium/winsys/xlib/xlib_brw_aub.h b/src/gallium/winsys/xlib/xlib_brw_aub.h new file mode 100644 index 0000000000..f5c60c7be2 --- /dev/null +++ b/src/gallium/winsys/xlib/xlib_brw_aub.h @@ -0,0 +1,114 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + 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, sublicense, 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 NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#ifndef BRW_AUB_H +#define BRW_AUB_H + +/* We set up this region, buffers may be allocated here: + */ +#define AUB_BUF_START (4096*4) +#define AUB_BUF_SIZE (8*1024*1024) + +struct intel_context; +struct pipe_surface; + +struct brw_aubfile *brw_aubfile_create( void ); + +void brw_aub_destroy( struct brw_aubfile *aubfile ); + +void brw_aub_gtt_data( struct brw_aubfile *aubfile, + unsigned offset, + const void *data, + unsigned sz, + unsigned type, + unsigned state_type ); + +void brw_aub_gtt_cmds( struct brw_aubfile *aubfile, + unsigned offset, + const void *data, + unsigned sz ); + +void brw_aub_dump_bmp( struct brw_aubfile *aubfile, + struct pipe_surface *surface, + unsigned gtt_offset ); + + +enum data_write_type { + DW_NOTYPE, + DW_BATCH_BUFFER, + DW_BIN_BUFFER, + DW_BIN_POINTER_LIST, + DW_SLOW_STATE_BUFFER, + DW_VERTEX_BUFFER, + DW_2D_MAP, + DW_CUBE_MAP, + DW_INDIRECT_STATE_BUFFER, + DW_VOLUME_MAP, + DW_1D_MAP, + DW_CONSTANT_BUFFER, + DW_CONSTANT_URB_ENTRY, + DW_INDEX_BUFFER, + DW_GENERAL_STATE, + DW_SURFACE_STATE, + DW_MEDIA_OBJECT_INDIRECT_DATA, + DW_MAX_TYPE +}; + +enum data_write_general_state_type { + DWGS_NOTYPE, + DWGS_VERTEX_SHADER_STATE, + DWGS_GEOMETRY_SHADER_STATE , + DWGS_CLIPPER_STATE, + DWGS_STRIPS_FANS_STATE, + DWGS_WINDOWER_IZ_STATE, + DWGS_COLOR_CALC_STATE, + DWGS_CLIPPER_VIEWPORT_STATE, /* was 0x7 */ + DWGS_STRIPS_FANS_VIEWPORT_STATE, + DWGS_COLOR_CALC_VIEWPORT_STATE, /* was 0x9 */ + DWGS_SAMPLER_STATE, + DWGS_KERNEL_INSTRUCTIONS, + DWGS_SCRATCH_SPACE, + DWGS_SAMPLER_DEFAULT_COLOR, + DWGS_INTERFACE_DESCRIPTOR, + DWGS_VLD_STATE, + DWGS_VFE_STATE, + DWGS_MAX_TYPE +}; + +enum data_write_surface_state_type { + DWSS_NOTYPE, + DWSS_BINDING_TABLE_STATE, + DWSS_SURFACE_STATE, + DWSS_MAX_TYPE +}; + + +#endif diff --git a/src/gallium/winsys/xlib/xlib_brw_context.c b/src/gallium/winsys/xlib/xlib_brw_context.c new file mode 100644 index 0000000000..a2bac0cc93 --- /dev/null +++ b/src/gallium/winsys/xlib/xlib_brw_context.c @@ -0,0 +1,205 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * Brian Paul + */ + + +//#include "glxheader.h" +//#include "xmesaP.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "i965simple/brw_winsys.h" +#include "xlib_brw_aub.h" +#include "xlib_brw.h" + + + + +#define XBCWS_BATCHBUFFER_SIZE 1024 + + +/* The backend to the brw driver (ie struct brw_winsys) is actually a + * per-context entity. + */ +struct xlib_brw_context_winsys { + struct brw_winsys brw_context_winsys; /**< batch buffer funcs */ + struct aub_context *aub; + + struct pipe_winsys *pipe_winsys; + + unsigned batch_data[XBCWS_BATCHBUFFER_SIZE]; + unsigned batch_nr; + unsigned batch_size; + unsigned batch_alloc; +}; + + +/* Turn a brw_winsys into an xlib_brw_context_winsys: + */ +static inline struct xlib_brw_context_winsys * +xlib_brw_context_winsys( struct brw_winsys *sws ) +{ + return (struct xlib_brw_context_winsys *)sws; +} + + +/* Simple batchbuffer interface: + */ + +static unsigned *xbcws_batch_start( struct brw_winsys *sws, + unsigned dwords, + unsigned relocs ) +{ + struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); + + if (xbcws->batch_size < xbcws->batch_nr + dwords) + return NULL; + + xbcws->batch_alloc = xbcws->batch_nr + dwords; + return (void *)1; /* not a valid pointer! */ +} + +static void xbcws_batch_dword( struct brw_winsys *sws, + unsigned dword ) +{ + struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); + + assert(xbcws->batch_nr < xbcws->batch_alloc); + xbcws->batch_data[xbcws->batch_nr++] = dword; +} + +static void xbcws_batch_reloc( struct brw_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta ) +{ + struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); + + assert(xbcws->batch_nr < xbcws->batch_alloc); + xbcws->batch_data[xbcws->batch_nr++] = + ( xlib_brw_get_buffer_offset( NULL, buf, access_flags ) + + delta ); +} + +static void xbcws_batch_end( struct brw_winsys *sws ) +{ + struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); + + assert(xbcws->batch_nr <= xbcws->batch_alloc); + xbcws->batch_alloc = 0; +} + +static void xbcws_batch_flush( struct brw_winsys *sws, + struct pipe_fence_handle **fence ) +{ + struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); + assert(xbcws->batch_nr <= xbcws->batch_size); + + if (xbcws->batch_nr) { + xlib_brw_commands_aub( xbcws->pipe_winsys, + xbcws->batch_data, + xbcws->batch_nr ); + } + + xbcws->batch_nr = 0; +} + + + +/* Really a per-device function, just pass through: + */ +static unsigned xbcws_get_buffer_offset( struct brw_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags ) +{ + struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); + + return xlib_brw_get_buffer_offset( xbcws->pipe_winsys, + buf, + access_flags ); +} + + +/* Really a per-device function, just pass through: + */ +static void xbcws_buffer_subdata_typed( struct brw_winsys *sws, + struct pipe_buffer *buf, + unsigned long offset, + unsigned long size, + const void *data, + unsigned data_type ) +{ + struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws); + + xlib_brw_buffer_subdata_typed( xbcws->pipe_winsys, + buf, + offset, + size, + data, + data_type ); +} + + +/** + * Create i965 hardware rendering context, but plugged into a + * dump-to-aubfile backend. + */ +struct pipe_context * +xlib_create_brw_context( struct pipe_screen *screen, + void *unused ) +{ + struct xlib_brw_context_winsys *xbcws = CALLOC_STRUCT( xlib_brw_context_winsys ); + + /* Fill in this struct with callbacks that i965simple will need to + * communicate with the window system, buffer manager, etc. + */ + xbcws->brw_context_winsys.batch_start = xbcws_batch_start; + xbcws->brw_context_winsys.batch_dword = xbcws_batch_dword; + xbcws->brw_context_winsys.batch_reloc = xbcws_batch_reloc; + xbcws->brw_context_winsys.batch_end = xbcws_batch_end; + xbcws->brw_context_winsys.batch_flush = xbcws_batch_flush; + xbcws->brw_context_winsys.buffer_subdata_typed = xbcws_buffer_subdata_typed; + xbcws->brw_context_winsys.get_buffer_offset = xbcws_get_buffer_offset; + + xbcws->pipe_winsys = screen->winsys; /* redundant */ + + xbcws->batch_size = XBCWS_BATCHBUFFER_SIZE; + + /* Create the i965simple context: + */ + return brw_create( screen, + &xbcws->brw_context_winsys, + 0 ); +} diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c new file mode 100644 index 0000000000..b0c7977185 --- /dev/null +++ b/src/gallium/winsys/xlib/xlib_brw_screen.c @@ -0,0 +1,470 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * Brian Paul + */ + + +//#include "state_trackers/xlib/glxheader.h" +//#include "state_trackers/xlib/xmesaP.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "i965simple/brw_winsys.h" +#include "i965simple/brw_screen.h" + +#include "xlib_brw_aub.h" +#include "xlib_brw.h" + + + +struct aub_buffer { + char *data; + unsigned offset; + unsigned size; + unsigned refcount; + unsigned map_count; + boolean dump_on_unmap; +}; + + + +struct aub_pipe_winsys { + struct pipe_winsys winsys; + + struct brw_aubfile *aubfile; + + /* This is simple, isn't it: + */ + char *pool; + unsigned size; + unsigned used; +}; + + +/* Turn a pipe winsys into an aub/pipe winsys: + */ +static inline struct aub_pipe_winsys * +aub_pipe_winsys( struct pipe_winsys *winsys ) +{ + return (struct aub_pipe_winsys *)winsys; +} + + + +static INLINE struct aub_buffer * +aub_bo( struct pipe_buffer *bo ) +{ + return (struct aub_buffer *)bo; +} + +static INLINE struct pipe_buffer * +pipe_bo( struct aub_buffer *bo ) +{ + return (struct pipe_buffer *)bo; +} + + + + +static void *aub_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags ) +{ + struct aub_buffer *sbo = aub_bo(buf); + + assert(sbo->data); + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + sbo->dump_on_unmap = 1; + + sbo->map_count++; + return sbo->data; +} + +static void aub_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + struct aub_buffer *sbo = aub_bo(buf); + + sbo->map_count--; + + if (sbo->map_count == 0 && + sbo->dump_on_unmap) { + + sbo->dump_on_unmap = 0; + + brw_aub_gtt_data( iws->aubfile, + sbo->offset, + sbo->data, + sbo->size, + 0, + 0); + } +} + + +static void +aub_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + free(buf); +} + + + +void xlib_brw_commands_aub(struct pipe_winsys *winsys, + unsigned *cmds, + unsigned nr_dwords) +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + unsigned size = nr_dwords * 4; + + assert(iws->used + size < iws->size); + + brw_aub_gtt_cmds( iws->aubfile, + AUB_BUF_START + iws->used, + cmds, + nr_dwords * sizeof(int) ); + + iws->used += align(size, 4096); +} + + +/* XXX: fix me: + */ +static struct aub_pipe_winsys *global_winsys = NULL; + + + + +/* Pipe has no concept of pools. We choose the tex/region pool + * for all buffers. + */ +static struct pipe_buffer * +aub_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + struct aub_buffer *sbo = CALLOC_STRUCT(aub_buffer); + + sbo->refcount = 1; + + /* Could reuse buffers that are not referenced in current + * batchbuffer. Can't do that atm, so always reallocate: + */ + assert(iws->used + size < iws->size); + sbo->data = iws->pool + iws->used; + sbo->offset = AUB_BUF_START + iws->used; + iws->used += align(size, 4096); + + sbo->size = size; + + return pipe_bo(sbo); +} + + +static struct pipe_buffer * +aub_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) +{ + struct aub_buffer *sbo; + + /* Lets hope this is meant for upload, not as a result! + */ + sbo = aub_bo(aub_buffer_create( winsys, 0, 0, 0 )); + + sbo->data = ptr; + sbo->size = bytes; + + return pipe_bo(sbo); +} + + +/* The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +aub_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surface, + void *context_private) +{ +// struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + brw_aub_dump_bmp( global_winsys->aubfile, + surface, + aub_bo(surface->buffer)->offset ); +} + +static struct pipe_surface * +aub_i915_surface_alloc(struct pipe_winsys *winsys) +{ + struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); + if (surf) { + surf->refcount = 1; + surf->winsys = winsys; + } + return surf; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +aub_i915_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->stride * surf->nblocksy); + if(!surf->buffer) + return -1; + + return 0; +} + +static void +aub_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + winsys_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + + +static const char * +aub_get_name( struct pipe_winsys *winsys ) +{ + return "Aub/xlib"; +} + +static void +xlib_brw_destroy_pipe_winsys_aub( struct pipe_winsys *winsys ) + +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + brw_aub_destroy(iws->aubfile); + free(iws->pool); + free(iws); +} + + + +struct pipe_winsys * +xlib_create_brw_winsys( void ) +{ + struct aub_pipe_winsys *iws = CALLOC_STRUCT( aub_pipe_winsys ); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + * + * Pipe would be happy with a malloc based memory manager, but + * the SwapBuffers implementation in this winsys driver requires + * that rendering be done to an appropriate _DriBufferObject. + */ + iws->winsys.buffer_create = aub_buffer_create; + iws->winsys.user_buffer_create = aub_user_buffer_create; + iws->winsys.buffer_map = aub_buffer_map; + iws->winsys.buffer_unmap = aub_buffer_unmap; + iws->winsys.buffer_destroy = aub_buffer_destroy; + iws->winsys.flush_frontbuffer = aub_flush_frontbuffer; + iws->winsys.get_name = aub_get_name; + iws->winsys.destroy = xlib_brw_destroy_pipe_winsys_aub; + + iws->winsys.surface_alloc = aub_i915_surface_alloc; + iws->winsys.surface_alloc_storage = aub_i915_surface_alloc_storage; + iws->winsys.surface_release = aub_i915_surface_release; + + iws->aubfile = brw_aubfile_create(); + iws->size = AUB_BUF_SIZE; + iws->pool = malloc(AUB_BUF_SIZE); + + /* HACK: static copy of this pointer: + */ + assert(global_winsys == NULL); + global_winsys = iws; + + return &iws->winsys; +} + + +struct pipe_screen * +xlib_create_brw_screen( struct pipe_winsys *winsys ) +{ + return brw_create_screen(winsys, 0/* XXX pci_id */); +} + + +/* These per-screen functions are acually made available to the driver + * through the brw_winsys (per-context) entity. + */ +unsigned xlib_brw_get_buffer_offset( struct pipe_winsys *pws, + struct pipe_buffer *buf, + unsigned access_flags ) +{ + return aub_bo(buf)->offset; +} + +void xlib_brw_buffer_subdata_typed( struct pipe_winsys *pws, + struct pipe_buffer *buf, + unsigned long offset, + unsigned long size, + const void *data, + unsigned data_type ) +{ + unsigned aub_type = DW_GENERAL_STATE; + unsigned aub_sub_type; + + switch (data_type) { + case BRW_CC_VP: + aub_sub_type = DWGS_COLOR_CALC_VIEWPORT_STATE; + break; + case BRW_CC_UNIT: + aub_sub_type = DWGS_COLOR_CALC_STATE; + break; + case BRW_WM_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_SAMPLER_DEFAULT_COLOR: + aub_sub_type = DWGS_SAMPLER_DEFAULT_COLOR; + break; + case BRW_SAMPLER: + aub_sub_type = DWGS_SAMPLER_STATE; + break; + case BRW_WM_UNIT: + aub_sub_type = DWGS_WINDOWER_IZ_STATE; + break; + case BRW_SF_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_SF_VP: + aub_sub_type = DWGS_STRIPS_FANS_VIEWPORT_STATE; + break; + case BRW_SF_UNIT: + aub_sub_type = DWGS_STRIPS_FANS_STATE; + break; + case BRW_VS_UNIT: + aub_sub_type = DWGS_VERTEX_SHADER_STATE; + break; + case BRW_VS_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_GS_UNIT: + aub_sub_type = DWGS_GEOMETRY_SHADER_STATE; + break; + case BRW_GS_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_CLIP_VP: + aub_sub_type = DWGS_CLIPPER_VIEWPORT_STATE; + break; + case BRW_CLIP_UNIT: + aub_sub_type = DWGS_CLIPPER_STATE; + break; + case BRW_CLIP_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_SS_SURFACE: + aub_type = DW_SURFACE_STATE; + aub_sub_type = DWSS_SURFACE_STATE; + break; + case BRW_SS_SURF_BIND: + aub_type = DW_SURFACE_STATE; + aub_sub_type = DWSS_BINDING_TABLE_STATE; + break; + case BRW_CONSTANT_BUFFER: + aub_type = DW_CONSTANT_URB_ENTRY; + aub_sub_type = 0; + break; + + default: + assert(0); + break; + } + + { + struct aub_pipe_winsys *iws = aub_pipe_winsys(pws); + struct aub_buffer *sbo = aub_bo(buf); + + assert(sbo->size > offset + size); + memcpy(sbo->data + offset, data, size); + + brw_aub_gtt_data( iws->aubfile, + sbo->offset + offset, + sbo->data + offset, + size, + aub_type, + aub_sub_type ); + } +} + + +void +xlib_brw_display_surface(struct xmesa_buffer *b, + struct pipe_surface *surf) +{ + brw_aub_dump_bmp( global_winsys->aubfile, + surf, + aub_bo(surf->buffer)->offset ); +} diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c new file mode 100644 index 0000000000..e4aa2d4b6a --- /dev/null +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -0,0 +1,744 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * Brian Paul + */ + + +#include "glxheader.h" +#include "xmesaP.h" + +#undef ASSERT +#undef Elements + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "softpipe/sp_winsys.h" + +#ifdef GALLIUM_CELL +#include "cell/ppu/cell_context.h" +#include "cell/ppu/cell_screen.h" +#include "cell/ppu/cell_winsys.h" +#else +#define TILE_SIZE 32 /* avoid compilation errors */ +#endif + +#include "xlib_softpipe.h" + +/** + * Subclass of pipe_buffer for Xlib winsys. + * Low-level OS/window system memory buffer + */ +struct xm_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; + + XImage *tempImage; + int shm; +#if defined(USE_XSHM) + XShmSegmentInfo shminfo; +#endif +}; + + +/** + * Subclass of pipe_winsys for Xlib winsys + */ +struct xmesa_pipe_winsys +{ + struct pipe_winsys base; +/* struct xmesa_visual *xm_visual; */ + int shm; +}; + + + +/** Cast wrapper */ +static INLINE struct xm_buffer * +xm_buffer( struct pipe_buffer *buf ) +{ + return (struct xm_buffer *)buf; +} + + +/** + * X Shared Memory Image extension code + */ +#if defined(USE_XSHM) + +#define XSHM_ENABLED(b) ((b)->shm) + +static volatile int mesaXErrorFlag = 0; + +/** + * Catches potential Xlib errors. + */ +static int +mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event) +{ + (void) dpy; + (void) event; + mesaXErrorFlag = 1; + return 0; +} + + +static GLboolean alloc_shm(struct xm_buffer *buf, unsigned size) +{ + XShmSegmentInfo *const shminfo = & buf->shminfo; + + shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); + if (shminfo->shmid < 0) { + return GL_FALSE; + } + + shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); + if (shminfo->shmaddr == (char *) -1) { + shmctl(shminfo->shmid, IPC_RMID, 0); + return GL_FALSE; + } + + shminfo->readOnly = False; + return GL_TRUE; +} + + +/** + * Allocate a shared memory XImage back buffer for the given XMesaBuffer. + */ +static void +alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, + unsigned width, unsigned height) +{ + /* + * We have to do a _lot_ of error checking here to be sure we can + * really use the XSHM extension. It seems different servers trigger + * errors at different points if the extension won't work. Therefore + * we have to be very careful... + */ +#if 0 + GC gc; +#endif + int (*old_handler)(XMesaDisplay *, XErrorEvent *); + + b->tempImage = XShmCreateImage(xmb->xm_visual->display, + xmb->xm_visual->visinfo->visual, + xmb->xm_visual->visinfo->depth, + ZPixmap, + NULL, + &b->shminfo, + width, height); + if (b->tempImage == NULL) { + b->shm = 0; + return; + } + + + mesaXErrorFlag = 0; + old_handler = XSetErrorHandler(mesaHandleXError); + /* This may trigger the X protocol error we're ready to catch: */ + XShmAttach(xmb->xm_visual->display, &b->shminfo); + XSync(xmb->xm_visual->display, False); + + if (mesaXErrorFlag) { + /* we are on a remote display, this error is normal, don't print it */ + XFlush(xmb->xm_visual->display); + mesaXErrorFlag = 0; + XDestroyImage(b->tempImage); + b->tempImage = NULL; + b->shm = 0; + (void) XSetErrorHandler(old_handler); + return; + } + + + /* Finally, try an XShmPutImage to be really sure the extension works */ +#if 0 + gc = XCreateGC(xmb->xm_visual->display, xmb->drawable, 0, NULL); + XShmPutImage(xmb->xm_visual->display, xmb->drawable, gc, + b->tempImage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False); + XSync(xmb->xm_visual->display, False); + XFreeGC(xmb->xm_visual->display, gc); + (void) XSetErrorHandler(old_handler); + if (mesaXErrorFlag) { + XFlush(xmb->xm_visual->display); + mesaXErrorFlag = 0; + XDestroyImage(b->tempImage); + b->tempImage = NULL; + b->shm = 0; + return; + } +#endif +} + +#else + +#define XSHM_ENABLED(b) 0 + +static void +alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, + unsigned width, unsigned height) +{ + b->shm = 0; +} +#endif /* USE_XSHM */ + + + + +/* Most callbacks map direcly onto dri_bufmgr operations: + */ +static void * +xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, + unsigned flags) +{ + struct xm_buffer *xm_buf = xm_buffer(buf); + xm_buf->mapped = xm_buf->data; + return xm_buf->mapped; +} + +static void +xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct xm_buffer *xm_buf = xm_buffer(buf); + xm_buf->mapped = NULL; +} + +static void +xm_buffer_destroy(struct pipe_winsys *pws, + struct pipe_buffer *buf) +{ + struct xm_buffer *oldBuf = xm_buffer(buf); + + if (oldBuf->data) { +#if defined(USE_XSHM) + if (oldBuf->shminfo.shmid >= 0) { + shmdt(oldBuf->shminfo.shmaddr); + shmctl(oldBuf->shminfo.shmid, IPC_RMID, 0); + + oldBuf->shminfo.shmid = -1; + oldBuf->shminfo.shmaddr = (char *) -1; + } + else +#endif + { + if (!oldBuf->userBuffer) { + align_free(oldBuf->data); + } + } + + oldBuf->data = NULL; + } + + free(oldBuf); +} + + +/** + * For Cell. Basically, rearrange the pixels/quads from this layout: + * +--+--+--+--+ + * |p0|p1|p2|p3|.... + * +--+--+--+--+ + * + * to this layout: + * +--+--+ + * |p0|p1|.... + * +--+--+ + * |p2|p3| + * +--+--+ + */ +static void +twiddle_tile(const uint *tileIn, uint *tileOut) +{ + int y, x; + + for (y = 0; y < TILE_SIZE; y+=2) { + for (x = 0; x < TILE_SIZE; x+=2) { + int k = 4 * (y/2 * TILE_SIZE/2 + x/2); + tileOut[y * TILE_SIZE + (x + 0)] = tileIn[k]; + tileOut[y * TILE_SIZE + (x + 1)] = tileIn[k+1]; + tileOut[(y + 1) * TILE_SIZE + (x + 0)] = tileIn[k+2]; + tileOut[(y + 1) * TILE_SIZE + (x + 1)] = tileIn[k+3]; + } + } +} + + + +/** + * Display a surface that's in a tiled configuration. That is, all the + * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory. + */ +void +xlib_cell_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf) +{ + XImage *ximage; + struct xm_buffer *xm_buf = xm_buffer(surf->buffer); + const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE; + uint x, y; + + if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { + alloc_shm_ximage(xm_buf, b, TILE_SIZE, TILE_SIZE); + } + + ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; + + /* check that the XImage has been previously initialized */ + assert(ximage->format); + assert(ximage->bitmap_unit); + + if (!XSHM_ENABLED(xm_buf)) { + /* update XImage's fields */ + ximage->width = TILE_SIZE; + ximage->height = TILE_SIZE; + ximage->bytes_per_line = TILE_SIZE * 4; + } + + for (y = 0; y < surf->height; y += TILE_SIZE) { + for (x = 0; x < surf->width; x += TILE_SIZE) { + uint tmpTile[TILE_SIZE * TILE_SIZE]; + int tx = x / TILE_SIZE; + int ty = y / TILE_SIZE; + int offset = ty * tilesPerRow + tx; + int w = TILE_SIZE; + int h = TILE_SIZE; + + if (y + h > surf->height) + h = surf->height - y; + if (x + w > surf->width) + w = surf->width - x; + + /* offset in pixels */ + offset *= TILE_SIZE * TILE_SIZE; + + if (0 && XSHM_ENABLED(xm_buf)) { + ximage->data = (char *) xm_buf->data + 4 * offset; + /* make copy of tile data */ + memcpy(tmpTile, (uint *) ximage->data, sizeof(tmpTile)); + /* twiddle from temp to ximage in shared memory */ + twiddle_tile(tmpTile, (uint *) ximage->data); + /* display image in shared memory */ +#if defined(USE_XSHM) + XShmPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, x, y, w, h, False); +#endif + } + else { + /* twiddle from ximage buffer to temp tile */ + twiddle_tile((uint *) xm_buf->data + offset, tmpTile); + /* display temp tile data */ + ximage->data = (char *) tmpTile; + XPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, x, y, w, h); + } + } + } +} + + +/** + * Display/copy the image in the surface into the X window specified + * by the XMesaBuffer. + */ +void +xlib_softpipe_display_surface(struct xmesa_buffer *b, + struct pipe_surface *surf) +{ + XImage *ximage; + struct xm_buffer *xm_buf = xm_buffer(surf->buffer); + static boolean no_swap = 0; + static boolean firsttime = 1; + static int tileSize = 0; + + if (firsttime) { + no_swap = getenv("SP_NO_RAST") != NULL; +#ifdef GALLIUM_CELL + if (!getenv("GALLIUM_NOCELL")) { + tileSize = 32; /** probably temporary */ + } +#endif + firsttime = 0; + } + + if (no_swap) + return; + + if (tileSize) { + xlib_cell_display_surface(b, surf); + return; + } + + if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { + assert(surf->block.width == 1); + assert(surf->block.height == 1); + alloc_shm_ximage(xm_buf, b, surf->stride/surf->block.size, surf->height); + } + + ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; + ximage->data = xm_buf->data; + + /* display image in Window */ + if (XSHM_ENABLED(xm_buf)) { +#if defined(USE_XSHM) + XShmPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, 0, 0, surf->width, surf->height, False); +#endif + } else { + /* check that the XImage has been previously initialized */ + assert(ximage->format); + assert(ximage->bitmap_unit); + + /* update XImage's fields */ + ximage->width = surf->width; + ximage->height = surf->height; + ximage->bytes_per_line = surf->stride; + + XPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, 0, 0, surf->width, surf->height); + } +} + + +static void +xm_flush_frontbuffer(struct pipe_winsys *pws, + struct pipe_surface *surf, + void *context_private) +{ + /* + * The front color buffer is actually just another XImage buffer. + * This function copies that XImage to the actual X Window. + */ + XMesaContext xmctx = (XMesaContext) context_private; + xlib_softpipe_display_surface(xmctx->xm_buffer, surf); +} + + + +static const char * +xm_get_name(struct pipe_winsys *pws) +{ + return "Xlib"; +} + + +static struct pipe_buffer * +xm_buffer_create(struct pipe_winsys *pws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); +#if defined(USE_XSHM) + struct xmesa_pipe_winsys *xpws = (struct xmesa_pipe_winsys *) pws; +#endif + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + +#if defined(USE_XSHM) + buffer->shminfo.shmid = -1; + buffer->shminfo.shmaddr = (char *) -1; + + if (xpws->shm && (usage & PIPE_BUFFER_USAGE_PIXEL) != 0) { + buffer->shm = xpws->shm; + + if (alloc_shm(buffer, size)) { + buffer->data = buffer->shminfo.shmaddr; + } + } +#endif + + if (buffer->data == NULL) { + buffer->shm = 0; + + /* align to 16-byte multiple for Cell */ + buffer->data = align_malloc(size, max(alignment, 16)); + } + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) +{ + struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); + buffer->base.refcount = 1; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + buffer->shm = 0; + + return &buffer->base; +} + + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +xm_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, +#ifdef GALLIUM_CELL /* XXX a bit of a hack */ + surf->stride * round_up(surf->nblocksy, TILE_SIZE)); +#else + surf->stride * surf->nblocksy); +#endif + + if(!surf->buffer) + return -1; + + return 0; +} + + +/** + * Called via winsys->surface_alloc() to create new surfaces. + */ +static struct pipe_surface * +xm_surface_alloc(struct pipe_winsys *ws) +{ + struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); + + assert(ws); + + surface->refcount = 1; + surface->winsys = ws; + + return surface; +} + + + +static void +xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + assert(!surf->texture); + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + winsys_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + +/* + * Fence functions - basically nothing to do, as we don't create any actual + * fence objects. + */ + +static void +xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + + +struct pipe_winsys * +xlib_create_softpipe_winsys( void ) +{ + static struct xmesa_pipe_winsys *ws = NULL; + + if (!ws) { + ws = CALLOC_STRUCT(xmesa_pipe_winsys); + + //ws->shm = xmesa_check_for_xshm( display ); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + */ + ws->base.buffer_create = xm_buffer_create; + ws->base.user_buffer_create = xm_user_buffer_create; + ws->base.buffer_map = xm_buffer_map; + ws->base.buffer_unmap = xm_buffer_unmap; + ws->base.buffer_destroy = xm_buffer_destroy; + + ws->base.surface_alloc = xm_surface_alloc; + ws->base.surface_alloc_storage = xm_surface_alloc_storage; + ws->base.surface_release = xm_surface_release; + + ws->base.fence_reference = xm_fence_reference; + ws->base.fence_signalled = xm_fence_signalled; + ws->base.fence_finish = xm_fence_finish; + + ws->base.flush_frontbuffer = xm_flush_frontbuffer; + ws->base.get_name = xm_get_name; + } + + return &ws->base; +} + + +struct pipe_screen * +xlib_create_softpipe_screen( struct pipe_winsys *pws ) +{ + struct pipe_screen *screen; + + screen = softpipe_create_screen(pws); + if (screen == NULL) + goto fail; + + return screen; + +fail: + return NULL; +} + + +struct pipe_context * +xlib_create_softpipe_context( struct pipe_screen *screen, + void *context_private ) +{ + struct pipe_context *pipe; + + pipe = softpipe_create(screen, screen->winsys, NULL); + if (pipe == NULL) + goto fail; + + pipe->priv = context_private; + return pipe; + +fail: + /* Free stuff here */ + return NULL; +} + + +/*********************************************************************** + * Cell piggybacks on softpipe code still. + * + * Should be untangled sufficiently to live in a separate file, at + * least. That would mean removing #ifdef GALLIUM_CELL's from above + * and creating cell-specific versions of either those functions or + * the entire file. + */ +struct pipe_winsys * +xlib_create_cell_winsys( void ) +{ + return xlib_create_softpipe_winsys(); +} + +struct pipe_screen * +xlib_create_cell_screen( struct pipe_winsys *pws ) +{ + return xlib_create_softpipe_screen( pws ); +} + + +struct pipe_context * +xlib_create_cell_context( struct pipe_screen *screen, + void *priv ) +{ +#ifdef GALLIUM_CELL + struct cell_winsys *cws; + struct pipe_context *pipe; + + if (getenv("GALLIUM_NOCELL")) + return xlib_create_softpipe_context( screen, priv ); + + + /* This takes a cell_winsys pointer, but probably that should be + * created and stored at screen creation, not context creation. + * + * The actual cell_winsys value isn't used for anything, so just + * passing NULL for now. + */ + pipe = cell_create_context( screen, NULL); + if (pipe == NULL) + goto fail; + + pipe->priv = priv; + + return pipe; + +fail: +#endif + return NULL; +} diff --git a/src/gallium/winsys/xlib/xlib_softpipe.h b/src/gallium/winsys/xlib/xlib_softpipe.h new file mode 100644 index 0000000000..0de96cc4c6 --- /dev/null +++ b/src/gallium/winsys/xlib/xlib_softpipe.h @@ -0,0 +1,50 @@ + +#ifndef XLIB_SOFTPIPE_H +#define XLIB_SOFTPIPE_H + +struct pipe_winsys; +struct pipe_screen; +struct pipe_context; +struct pipe_surface; +struct xmesa_buffer; + + +struct pipe_winsys * +xlib_create_softpipe_winsys( void ); + +struct pipe_screen * +xlib_create_softpipe_screen( struct pipe_winsys *pws ); + +struct pipe_context * +xlib_create_softpipe_context( struct pipe_screen *screen, + void *context_priv ); + +void +xlib_softpipe_display_surface( struct xmesa_buffer *, + struct pipe_surface * ); + +/*********************************************************************** + * Cell piggybacks on softpipe code still. + * + * Should be untangled sufficiently to live in a separate file, at + * least. That would mean removing #ifdef GALLIUM_CELL's from above + * and creating cell-specific versions of either those functions or + * the entire file. + */ +struct pipe_winsys * +xlib_create_cell_winsys( void ); + +struct pipe_screen * +xlib_create_cell_screen( struct pipe_winsys *pws ); + + +struct pipe_context * +xlib_create_cell_context( struct pipe_screen *screen, + void *priv ); + +void +xlib_cell_display_surface( struct xmesa_buffer *, + struct pipe_surface * ); + + +#endif diff --git a/src/gallium/winsys/xlib/xlib_trace.c b/src/gallium/winsys/xlib/xlib_trace.c new file mode 100644 index 0000000000..45afba7a47 --- /dev/null +++ b/src/gallium/winsys/xlib/xlib_trace.c @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * Brian Paul + */ + + +#include "xlib_softpipe.h" +#include "xlib_trace.h" + +#include "trace/tr_screen.h" +#include "trace/tr_context.h" + + +struct pipe_winsys * +xlib_create_trace_winsys( void ) +{ + return xlib_create_softpipe_winsys(); +} + +struct pipe_screen * +xlib_create_trace_screen( struct pipe_winsys *winsys ) +{ + struct pipe_screen *screen, *trace_screen; + + screen = xlib_create_softpipe_screen( winsys ); + if (screen == NULL) + goto fail; + + /* Wrap it: + */ + trace_screen = trace_screen_create(screen); + if (trace_screen == NULL) + goto fail; + + return trace_screen; + +fail: + /* free stuff */ + return NULL; +} + +struct pipe_context * +xlib_create_trace_context( struct pipe_screen *screen, + void *priv ) +{ + struct pipe_context *pipe, *trace_pipe; + + pipe = xlib_create_softpipe_context( screen, priv ); + if (pipe == NULL) + goto fail; + + /* Wrap it: + */ + trace_pipe = trace_context_create(screen, pipe); + if (trace_pipe == NULL) + goto fail; + + trace_pipe->priv = priv; + + return trace_pipe; + +fail: + return NULL; +} + +void +xlib_trace_display_surface( struct xmesa_buffer *buffer, + struct pipe_surface *surf ) +{ + /* ?? + */ + xlib_softpipe_display_surface( buffer, surf ); +} diff --git a/src/gallium/winsys/xlib/xlib_trace.h b/src/gallium/winsys/xlib/xlib_trace.h new file mode 100644 index 0000000000..c79c0fe34d --- /dev/null +++ b/src/gallium/winsys/xlib/xlib_trace.h @@ -0,0 +1,26 @@ + +#ifndef XLIB_TRACE_H +#define XLIB_TRACE_H + +struct pipe_winsys; +struct pipe_screen; +struct pipe_context; +struct pipe_surface; +struct xmesa_buffer; + +struct pipe_winsys * +xlib_create_trace_winsys( void ); + +struct pipe_screen * +xlib_create_trace_screen( struct pipe_winsys *winsys ); + +struct pipe_context * +xlib_create_trace_context( struct pipe_screen *screen, + void *priv ); + +void +xlib_trace_display_surface( struct xmesa_buffer *buffer, + struct pipe_surface *surf ); + + +#endif diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c deleted file mode 100644 index d28a6423b9..0000000000 --- a/src/gallium/winsys/xlib/xm_api.c +++ /dev/null @@ -1,1422 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 1999-2007 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - -/** - * \file xm_api.c - * - * All the XMesa* API functions. - * - * - * NOTES: - * - * The window coordinate system origin (0,0) is in the lower-left corner - * of the window. X11's window coordinate origin is in the upper-left - * corner of the window. Therefore, most drawing functions in this - * file have to flip Y coordinates. - * - * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile - * in support for the MIT Shared Memory extension. If enabled, when you - * use an Ximage for the back buffer in double buffered mode, the "swap" - * operation will be faster. You must also link with -lXext. - * - * Byte swapping: If the Mesa host and the X display use a different - * byte order then there's some trickiness to be aware of when using - * XImages. The byte ordering used for the XImage is that of the X - * display, not the Mesa host. - * The color-to-pixel encoding for True/DirectColor must be done - * according to the display's visual red_mask, green_mask, and blue_mask. - * If XPutPixel is used to put a pixel into an XImage then XPutPixel will - * do byte swapping if needed. If one wants to directly "poke" the pixel - * into the XImage's buffer then the pixel must be byte swapped first. - * - */ - -#ifdef __CYGWIN__ -#undef WIN32 -#undef __WIN32__ -#endif - -#include "glxheader.h" -#include "GL/xmesa.h" -#include "xmesaP.h" -#include "main/context.h" -#include "main/framebuffer.h" - -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" - -#include "xm_winsys_aub.h" - -/** - * Global X driver lock - */ -pipe_mutex _xmesa_lock; - - -int xmesa_mode; - - -/**********************************************************************/ -/***** X Utility Functions *****/ -/**********************************************************************/ - - -/** - * Return the host's byte order as LSBFirst or MSBFirst ala X. - */ -#ifndef XFree86Server -static int host_byte_order( void ) -{ - int i = 1; - char *cptr = (char *) &i; - return (*cptr==1) ? LSBFirst : MSBFirst; -} -#endif - - -/** - * Check if the X Shared Memory extension is available. - * Return: 0 = not available - * 1 = shared XImage support available - * 2 = shared Pixmap support available also - */ -int xmesa_check_for_xshm( XMesaDisplay *display ) -{ -#if defined(USE_XSHM) && !defined(XFree86Server) - int major, minor, ignore; - Bool pixmaps; - - if (getenv("SP_NO_RAST")) - return 0; - - if (getenv("MESA_NOSHM")) { - return 0; - } - - if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { - if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { - return (pixmaps==True) ? 2 : 1; - } - else { - return 0; - } - } - else { - return 0; - } -#else - /* No XSHM support */ - return 0; -#endif -} - - -/** - * Return the true number of bits per pixel for XImages. - * For example, if we request a 24-bit deep visual we may actually need/get - * 32bpp XImages. This function returns the appropriate bpp. - * Input: dpy - the X display - * visinfo - desribes the visual to be used for XImages - * Return: true number of bits per pixel for XImages - */ -static int -bits_per_pixel( XMesaVisual xmv ) -{ -#ifdef XFree86Server - const int depth = xmv->nplanes; - int i; - assert(depth > 0); - for (i = 0; i < screenInfo.numPixmapFormats; i++) { - if (screenInfo.formats[i].depth == depth) - return screenInfo.formats[i].bitsPerPixel; - } - return depth; /* should never get here, but this should be safe */ -#else - XMesaDisplay *dpy = xmv->display; - XMesaVisualInfo visinfo = xmv->visinfo; - XMesaImage *img; - int bitsPerPixel; - /* Create a temporary XImage */ - img = XCreateImage( dpy, visinfo->visual, visinfo->depth, - ZPixmap, 0, /*format, offset*/ - (char*) MALLOC(8), /*data*/ - 1, 1, /*width, height*/ - 32, /*bitmap_pad*/ - 0 /*bytes_per_line*/ - ); - assert(img); - /* grab the bits/pixel value */ - bitsPerPixel = img->bits_per_pixel; - /* free the XImage */ - _mesa_free( img->data ); - img->data = NULL; - XMesaDestroyImage( img ); - return bitsPerPixel; -#endif -} - - - -/* - * Determine if a given X window ID is valid (window exists). - * Do this by calling XGetWindowAttributes() for the window and - * checking if we catch an X error. - * Input: dpy - the display - * win - the window to check for existance - * Return: GL_TRUE - window exists - * GL_FALSE - window doesn't exist - */ -#ifndef XFree86Server -static GLboolean WindowExistsFlag; - -static int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr ) -{ - (void) dpy; - if (xerr->error_code == BadWindow) { - WindowExistsFlag = GL_FALSE; - } - return 0; -} - -static GLboolean window_exists( XMesaDisplay *dpy, Window win ) -{ - XWindowAttributes wa; - int (*old_handler)( XMesaDisplay*, XErrorEvent* ); - WindowExistsFlag = GL_TRUE; - old_handler = XSetErrorHandler(window_exists_err_handler); - XGetWindowAttributes( dpy, win, &wa ); /* dummy request */ - XSetErrorHandler(old_handler); - return WindowExistsFlag; -} - -static Status -get_drawable_size( XMesaDisplay *dpy, Drawable d, uint *width, uint *height ) -{ - Window root; - Status stat; - int xpos, ypos; - unsigned int w, h, bw, depth; - stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); - *width = w; - *height = h; - return stat; -} -#endif - - -/** - * Return the size of the window (or pixmap) that corresponds to the - * given XMesaBuffer. - * \param width returns width in pixels - * \param height returns height in pixels - */ -static void -xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b, - GLuint *width, GLuint *height) -{ -#ifdef XFree86Server - *width = MIN2(b->drawable->width, MAX_WIDTH); - *height = MIN2(b->drawable->height, MAX_HEIGHT); -#else - Status stat; - - pipe_mutex_lock(_xmesa_lock); - XSync(b->xm_visual->display, 0); /* added for Chromium */ - stat = get_drawable_size(dpy, b->drawable, width, height); - pipe_mutex_unlock(_xmesa_lock); - - if (!stat) { - /* probably querying a window that's recently been destroyed */ - _mesa_warning(NULL, "XGetGeometry failed!\n"); - *width = *height = 1; - } -#endif -} - - -/** - * Choose the pixel format for the given visual. - * This will tell the gallium driver how to pack pixel data into - * drawing surfaces. - */ -static GLuint -choose_pixel_format(XMesaVisual v) -{ - if ( GET_REDMASK(v) == 0x0000ff - && GET_GREENMASK(v) == 0x00ff00 - && GET_BLUEMASK(v) == 0xff0000 - && v->BitsPerPixel == 32) { - if (CHECK_BYTE_ORDER(v)) { - /* no byteswapping needed */ - return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */; - } - else { - return PIPE_FORMAT_R8G8B8A8_UNORM; - } - } - else if ( GET_REDMASK(v) == 0xff0000 - && GET_GREENMASK(v) == 0x00ff00 - && GET_BLUEMASK(v) == 0x0000ff - && v->BitsPerPixel == 32) { - if (CHECK_BYTE_ORDER(v)) { - /* no byteswapping needed */ - return PIPE_FORMAT_A8R8G8B8_UNORM; - } - else { - return PIPE_FORMAT_B8G8R8A8_UNORM; - } - } - else if ( GET_REDMASK(v) == 0xf800 - && GET_GREENMASK(v) == 0x07e0 - && GET_BLUEMASK(v) == 0x001f - && CHECK_BYTE_ORDER(v) - && v->BitsPerPixel == 16) { - /* 5-6-5 RGB */ - return PIPE_FORMAT_R5G6B5_UNORM; - } - - assert(0); - return 0; -} - - - -/**********************************************************************/ -/***** Linked list of XMesaBuffers *****/ -/**********************************************************************/ - -XMesaBuffer XMesaBufferList = NULL; - - -/** - * Allocate a new XMesaBuffer object which corresponds to the given drawable. - * Note that XMesaBuffer is derived from GLframebuffer. - * The new XMesaBuffer will not have any size (Width=Height=0). - * - * \param d the corresponding X drawable (window or pixmap) - * \param type either WINDOW, PIXMAP or PBUFFER, describing d - * \param vis the buffer's visual - * \param cmap the window's colormap, if known. - * \return new XMesaBuffer or NULL if any problem - */ -static XMesaBuffer -create_xmesa_buffer(XMesaDrawable d, BufferType type, - XMesaVisual vis, XMesaColormap cmap) -{ - XMesaBuffer b; - GLframebuffer *fb; - enum pipe_format colorFormat, depthFormat, stencilFormat; - uint width, height; - - ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER); - - b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer); - if (!b) - return NULL; - - b->drawable = d; - - b->xm_visual = vis; - b->type = type; - b->cmap = cmap; - - /* determine PIPE_FORMATs for buffers */ - colorFormat = choose_pixel_format(vis); - - if (vis->mesa_visual.depthBits == 0) - depthFormat = PIPE_FORMAT_NONE; -#ifdef GALLIUM_CELL /* XXX temporary for Cell! */ - else - depthFormat = PIPE_FORMAT_S8Z24_UNORM; -#else - else if (vis->mesa_visual.depthBits <= 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (vis->mesa_visual.depthBits <= 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_Z32_UNORM; -#endif - - if (vis->mesa_visual.stencilBits == 8) { - if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) - stencilFormat = depthFormat; - else - stencilFormat = PIPE_FORMAT_S8_UNORM; - } - else { - /* no stencil */ - stencilFormat = PIPE_FORMAT_NONE; - if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) { - /* use 24-bit Z, undefined stencil channel */ - depthFormat = PIPE_FORMAT_X8Z24_UNORM; - } - } - - - get_drawable_size(vis->display, d, &width, &height); - - /* - * Create framebuffer, but we'll plug in our own renderbuffers below. - */ - b->stfb = st_create_framebuffer(&vis->mesa_visual, - colorFormat, depthFormat, stencilFormat, - width, height, - (void *) b); - fb = &b->stfb->Base; - - /* - * Create scratch XImage for xmesa_display_surface() - */ - b->tempImage = XCreateImage(vis->display, - vis->visinfo->visual, - vis->visinfo->depth, - ZPixmap, 0, /* format, offset */ - NULL, /* data */ - 0, 0, /* size */ - 32, /* bitmap_pad */ - 0); /* bytes_per_line */ - - /* GLX_EXT_texture_from_pixmap */ - b->TextureTarget = 0; - b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT; - b->TextureMipmap = 0; - - /* insert buffer into linked list */ - b->Next = XMesaBufferList; - XMesaBufferList = b; - - return b; -} - - -/** - * Find an XMesaBuffer by matching X display and colormap but NOT matching - * the notThis buffer. - */ -XMesaBuffer -xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis) -{ - XMesaBuffer b; - for (b = XMesaBufferList; b; b = b->Next) { - if (b->xm_visual->display == dpy && - b->cmap == cmap && - b != notThis) { - return b; - } - } - return NULL; -} - - -/** - * Remove buffer from linked list, delete if no longer referenced. - */ -static void -xmesa_free_buffer(XMesaBuffer buffer) -{ - XMesaBuffer prev = NULL, b; - - for (b = XMesaBufferList; b; b = b->Next) { - if (b == buffer) { - struct gl_framebuffer *fb = &buffer->stfb->Base; - - /* unlink buffer from list */ - if (prev) - prev->Next = buffer->Next; - else - XMesaBufferList = buffer->Next; - - /* mark as delete pending */ - fb->DeletePending = GL_TRUE; - - /* Since the X window for the XMesaBuffer is going away, we don't - * want to dereference this pointer in the future. - */ - b->drawable = 0; - - buffer->tempImage->data = NULL; - XDestroyImage(buffer->tempImage); - - /* Unreference. If count = zero we'll really delete the buffer */ - _mesa_unreference_framebuffer(&fb); - - XFreeGC(b->xm_visual->display, b->gc); - - free(buffer); - - return; - } - /* continue search */ - prev = b; - } - /* buffer not found in XMesaBufferList */ - _mesa_problem(NULL,"xmesa_free_buffer() - buffer not found\n"); -} - - - -/**********************************************************************/ -/***** Misc Private Functions *****/ -/**********************************************************************/ - - -/** - * When a context is bound for the first time, we can finally finish - * initializing the context's visual and buffer information. - * \param v the XMesaVisual to initialize - * \param b the XMesaBuffer to initialize (may be NULL) - * \param rgb_flag TRUE = RGBA mode, FALSE = color index mode - * \param window the window/pixmap we're rendering into - * \param cmap the colormap associated with the window/pixmap - * \return GL_TRUE=success, GL_FALSE=failure - */ -static GLboolean -initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, - GLboolean rgb_flag, XMesaDrawable window, - XMesaColormap cmap) -{ -#ifdef XFree86Server - int client = (window) ? CLIENT_ID(window->id) : 0; -#endif - - ASSERT(!b || b->xm_visual == v); - - /* Save true bits/pixel */ - v->BitsPerPixel = bits_per_pixel(v); - assert(v->BitsPerPixel > 0); - - if (rgb_flag == GL_FALSE) { - /* COLOR-INDEXED WINDOW: not supported*/ - return GL_FALSE; - } - else { - /* RGB WINDOW: - * We support RGB rendering into almost any kind of visual. - */ - const int xclass = v->mesa_visual.visualType; - if (xclass != GLX_TRUE_COLOR && xclass == !GLX_DIRECT_COLOR) { - _mesa_warning(NULL, - "XMesa: RGB mode rendering not supported in given visual.\n"); - return GL_FALSE; - } - v->mesa_visual.indexBits = 0; - - if (v->BitsPerPixel == 32) { - /* We use XImages for all front/back buffers. If an X Window or - * X Pixmap is 32bpp, there's no guarantee that the alpha channel - * will be preserved. For XImages we're in luck. - */ - v->mesa_visual.alphaBits = 8; - } - } - - /* - * If MESA_INFO env var is set print out some debugging info - * which can help Brian figure out what's going on when a user - * reports bugs. - */ - if (_mesa_getenv("MESA_INFO")) { - _mesa_printf("X/Mesa visual = %p\n", (void *) v); - _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level); - _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v)); - _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); - } - - if (b && window) { - /* these should have been set in create_xmesa_buffer */ - ASSERT(b->drawable == window); - - /* Setup for single/double buffering */ - if (v->mesa_visual.doubleBufferMode) { - /* Double buffered */ - b->shm = xmesa_check_for_xshm( v->display ); - } - - /* X11 graphics context */ -#ifdef XFree86Server - b->gc = CreateScratchGC(v->display, window->depth); -#else - b->gc = XCreateGC( v->display, window, 0, NULL ); -#endif - XMesaSetFunction( v->display, b->gc, GXcopy ); - } - - return GL_TRUE; -} - - - -#define NUM_VISUAL_TYPES 6 - -/** - * Convert an X visual type to a GLX visual type. - * - * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) - * to be converted. - * \return If \c visualType is a valid X visual type, a GLX visual type will - * be returned. Otherwise \c GLX_NONE will be returned. - * - * \note - * This code was lifted directly from lib/GL/glx/glcontextmodes.c in the - * DRI CVS tree. - */ -static GLint -xmesa_convert_from_x_visual_type( int visualType ) -{ - static const int glx_visual_types[ NUM_VISUAL_TYPES ] = { - GLX_STATIC_GRAY, GLX_GRAY_SCALE, - GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, - GLX_TRUE_COLOR, GLX_DIRECT_COLOR - }; - - return ( (unsigned) visualType < NUM_VISUAL_TYPES ) - ? glx_visual_types[ visualType ] : GLX_NONE; -} - - -/**********************************************************************/ -/***** Public Functions *****/ -/**********************************************************************/ - - -/* - * Create a new X/Mesa visual. - * Input: display - X11 display - * visinfo - an XVisualInfo pointer - * rgb_flag - GL_TRUE = RGB mode, - * GL_FALSE = color index mode - * alpha_flag - alpha buffer requested? - * db_flag - GL_TRUE = double-buffered, - * GL_FALSE = single buffered - * stereo_flag - stereo visual? - * ximage_flag - GL_TRUE = use an XImage for back buffer, - * GL_FALSE = use an off-screen pixmap for back buffer - * depth_size - requested bits/depth values, or zero - * stencil_size - requested bits/stencil values, or zero - * accum_red_size - requested bits/red accum values, or zero - * accum_green_size - requested bits/green accum values, or zero - * accum_blue_size - requested bits/blue accum values, or zero - * accum_alpha_size - requested bits/alpha accum values, or zero - * num_samples - number of samples/pixel if multisampling, or zero - * level - visual level, usually 0 - * visualCaveat - ala the GLX extension, usually GLX_NONE - * Return; a new XMesaVisual or 0 if error. - */ -PUBLIC -XMesaVisual XMesaCreateVisual( XMesaDisplay *display, - XMesaVisualInfo visinfo, - GLboolean rgb_flag, - GLboolean alpha_flag, - GLboolean db_flag, - GLboolean stereo_flag, - GLboolean ximage_flag, - GLint depth_size, - GLint stencil_size, - GLint accum_red_size, - GLint accum_green_size, - GLint accum_blue_size, - GLint accum_alpha_size, - GLint num_samples, - GLint level, - GLint visualCaveat ) -{ - XMesaVisual v; - GLint red_bits, green_bits, blue_bits, alpha_bits; - -#ifndef XFree86Server - /* For debugging only */ - if (_mesa_getenv("MESA_XSYNC")) { - /* This makes debugging X easier. - * In your debugger, set a breakpoint on _XError to stop when an - * X protocol error is generated. - */ - XSynchronize( display, 1 ); - } -#endif - - v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual); - if (!v) { - return NULL; - } - - v->display = display; - - /* Save a copy of the XVisualInfo struct because the user may X_mesa_free() - * the struct but we may need some of the information contained in it - * at a later time. - */ -#ifndef XFree86Server - v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo)); - if(!v->visinfo) { - _mesa_free(v); - return NULL; - } - MEMCPY(v->visinfo, visinfo, sizeof(*visinfo)); -#endif - - v->ximage_flag = ximage_flag; - -#ifdef XFree86Server - /* We could calculate these values by ourselves. nplanes is either the sum - * of the red, green, and blue bits or the number index bits. - * ColormapEntries is either (1U << index_bits) or - * (1U << max(redBits, greenBits, blueBits)). - */ - assert(visinfo->nplanes > 0); - v->nplanes = visinfo->nplanes; - v->ColormapEntries = visinfo->ColormapEntries; - - v->mesa_visual.redMask = visinfo->redMask; - v->mesa_visual.greenMask = visinfo->greenMask; - v->mesa_visual.blueMask = visinfo->blueMask; - v->mesa_visual.visualID = visinfo->vid; - v->mesa_visual.screen = 0; /* FIXME: What should be done here? */ -#else - v->mesa_visual.redMask = visinfo->red_mask; - v->mesa_visual.greenMask = visinfo->green_mask; - v->mesa_visual.blueMask = visinfo->blue_mask; - v->mesa_visual.visualID = visinfo->visualid; - v->mesa_visual.screen = visinfo->screen; -#endif - -#if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus)) - v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class); -#else - v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class); -#endif - - v->mesa_visual.visualRating = visualCaveat; - - if (alpha_flag) - v->mesa_visual.alphaBits = 8; - - (void) initialize_visual_and_buffer( v, NULL, rgb_flag, 0, 0 ); - - { - const int xclass = v->mesa_visual.visualType; - if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { - red_bits = _mesa_bitcount(GET_REDMASK(v)); - green_bits = _mesa_bitcount(GET_GREENMASK(v)); - blue_bits = _mesa_bitcount(GET_BLUEMASK(v)); - } - else { - /* this is an approximation */ - int depth; - depth = GET_VISUAL_DEPTH(v); - red_bits = depth / 3; - depth -= red_bits; - green_bits = depth / 2; - depth -= green_bits; - blue_bits = depth; - alpha_bits = 0; - assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) ); - } - alpha_bits = v->mesa_visual.alphaBits; - } - - _mesa_initialize_visual( &v->mesa_visual, - rgb_flag, db_flag, stereo_flag, - red_bits, green_bits, - blue_bits, alpha_bits, - v->mesa_visual.indexBits, - depth_size, - stencil_size, - accum_red_size, accum_green_size, - accum_blue_size, accum_alpha_size, - 0 ); - - /* XXX minor hack */ - v->mesa_visual.level = level; - return v; -} - - -PUBLIC -void XMesaDestroyVisual( XMesaVisual v ) -{ -#ifndef XFree86Server - _mesa_free(v->visinfo); -#endif - _mesa_free(v); -} - - - -/** - * Create a new XMesaContext. - * \param v the XMesaVisual - * \param share_list another XMesaContext with which to share display - * lists or NULL if no sharing is wanted. - * \return an XMesaContext or NULL if error. - */ -PUBLIC -XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) -{ - static GLboolean firstTime = GL_TRUE; - struct pipe_context *pipe; - XMesaContext c; - GLcontext *mesaCtx; - uint pf; - - if (firstTime) { - pipe_mutex_init(_xmesa_lock); - firstTime = GL_FALSE; - } - - /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */ - c = (XMesaContext) CALLOC_STRUCT(xmesa_context); - if (!c) - return NULL; - - pf = choose_pixel_format(v); - assert(pf); - - c->xm_visual = v; - c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ - - if (!getenv("XM_AUB")) { - xmesa_mode = XMESA_SOFTPIPE; - pipe = xmesa_create_pipe_context( c, pf ); - } - else { - xmesa_mode = XMESA_AUB; - pipe = xmesa_create_i965simple(xmesa_get_pipe_winsys_aub(v)); - } - - if (pipe == NULL) - goto fail; - - c->st = st_create_context(pipe, &v->mesa_visual, - share_list ? share_list->st : NULL); - if (c->st == NULL) - goto fail; - - mesaCtx = c->st->ctx; - c->st->ctx->DriverCtx = c; - -#if 00 - _mesa_enable_sw_extensions(mesaCtx); - _mesa_enable_1_3_extensions(mesaCtx); - _mesa_enable_1_4_extensions(mesaCtx); - _mesa_enable_1_5_extensions(mesaCtx); - _mesa_enable_2_0_extensions(mesaCtx); -#endif - -#ifdef XFree86Server - /* If we're running in the X server, do bounds checking to prevent - * segfaults and server crashes! - */ - mesaCtx->Const.CheckArrayBounds = GL_TRUE; -#endif - - return c; - - fail: - if (c->st) - st_destroy_context(c->st); - else if (pipe) - pipe->destroy(pipe); - FREE(c); - return NULL; -} - - - -PUBLIC -void XMesaDestroyContext( XMesaContext c ) -{ - struct pipe_screen *screen = c->st->pipe->screen; - st_destroy_context(c->st); - /* FIXME: We should destroy the screen here, but if we do so, surfaces may - * outlive it, causing segfaults - screen->destroy(screen); - */ - _mesa_free(c); -} - - - -/** - * Private function for creating an XMesaBuffer which corresponds to an - * X window or pixmap. - * \param v the window's XMesaVisual - * \param w the window we're wrapping - * \return new XMesaBuffer or NULL if error - */ -PUBLIC XMesaBuffer -XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w) -{ -#ifndef XFree86Server - XWindowAttributes attr; -#endif - XMesaBuffer b; - XMesaColormap cmap; - int depth; - - assert(v); - assert(w); - - /* Check that window depth matches visual depth */ -#ifdef XFree86Server - depth = ((XMesaDrawable)w)->depth; -#else - XGetWindowAttributes( v->display, w, &attr ); - depth = attr.depth; -#endif - if (GET_VISUAL_DEPTH(v) != depth) { - _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n", - GET_VISUAL_DEPTH(v), depth); - return NULL; - } - - /* Find colormap */ -#ifdef XFree86Server - cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP); -#else - if (attr.colormap) { - cmap = attr.colormap; - } - else { - _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w); - /* this is weird, a window w/out a colormap!? */ - /* OK, let's just allocate a new one and hope for the best */ - cmap = XCreateColormap(v->display, w, attr.visual, AllocNone); - } -#endif - - b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap); - if (!b) - return NULL; - - if (!initialize_visual_and_buffer( v, b, v->mesa_visual.rgbMode, - (XMesaDrawable) w, cmap )) { - xmesa_free_buffer(b); - return NULL; - } - - return b; -} - - - -/** - * Create a new XMesaBuffer from an X pixmap. - * - * \param v the XMesaVisual - * \param p the pixmap - * \param cmap the colormap, may be 0 if using a \c GLX_TRUE_COLOR or - * \c GLX_DIRECT_COLOR visual for the pixmap - * \returns new XMesaBuffer or NULL if error - */ -PUBLIC XMesaBuffer -XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap) -{ - XMesaBuffer b; - - assert(v); - - b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap); - if (!b) - return NULL; - - if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, - (XMesaDrawable) p, cmap)) { - xmesa_free_buffer(b); - return NULL; - } - - return b; -} - - -/** - * For GLX_EXT_texture_from_pixmap - */ -XMesaBuffer -XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p, - XMesaColormap cmap, - int format, int target, int mipmap) -{ - GET_CURRENT_CONTEXT(ctx); - XMesaBuffer b; - GLuint width, height; - - assert(v); - - b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap); - if (!b) - return NULL; - - /* get pixmap size, update framebuffer/renderbuffer dims */ - xmesa_get_window_size(v->display, b, &width, &height); - _mesa_resize_framebuffer(NULL, &(b->stfb->Base), width, height); - - if (target == 0) { - /* examine dims */ - if (ctx->Extensions.ARB_texture_non_power_of_two) { - target = GLX_TEXTURE_2D_EXT; - } - else if ( _mesa_bitcount(width) == 1 - && _mesa_bitcount(height) == 1) { - /* power of two size */ - if (height == 1) { - target = GLX_TEXTURE_1D_EXT; - } - else { - target = GLX_TEXTURE_2D_EXT; - } - } - else if (ctx->Extensions.NV_texture_rectangle) { - target = GLX_TEXTURE_RECTANGLE_EXT; - } - else { - /* non power of two textures not supported */ - XMesaDestroyBuffer(b); - return 0; - } - } - - b->TextureTarget = target; - b->TextureFormat = format; - b->TextureMipmap = mipmap; - - if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, - (XMesaDrawable) p, cmap)) { - xmesa_free_buffer(b); - return NULL; - } - - return b; -} - - - -XMesaBuffer -XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, - unsigned int width, unsigned int height) -{ -#ifndef XFree86Server - XMesaWindow root; - XMesaDrawable drawable; /* X Pixmap Drawable */ - XMesaBuffer b; - - /* allocate pixmap for front buffer */ - root = RootWindow( v->display, v->visinfo->screen ); - drawable = XCreatePixmap(v->display, root, width, height, - v->visinfo->depth); - if (!drawable) - return NULL; - - b = create_xmesa_buffer(drawable, PBUFFER, v, cmap); - if (!b) - return NULL; - - if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, - drawable, cmap)) { - xmesa_free_buffer(b); - return NULL; - } - - return b; -#else - return 0; -#endif -} - - - -/* - * Deallocate an XMesaBuffer structure and all related info. - */ -PUBLIC void -XMesaDestroyBuffer(XMesaBuffer b) -{ - xmesa_free_buffer(b); -} - - -/** - * Query the current window size and update the corresponding GLframebuffer - * and all attached renderbuffers. - * Called when: - * 1. the first time a buffer is bound to a context. - * 2. from the XMesaResizeBuffers() API function. - * 3. SwapBuffers. XXX probabaly from xm_flush_frontbuffer() too... - * Note: it's possible (and legal) for xmctx to be NULL. That can happen - * when resizing a buffer when no rendering context is bound. - */ -void -xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer) -{ - GLuint width, height; - xmesa_get_window_size(drawBuffer->xm_visual->display, drawBuffer, &width, &height); - st_resize_framebuffer(drawBuffer->stfb, width, height); -} - - -/* - * Bind buffer b to context c and make c the current rendering context. - */ -GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b ) -{ - return XMesaMakeCurrent2( c, b, b ); -} - - -/* - * Bind buffer b to context c and make c the current rendering context. - */ -PUBLIC -GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, - XMesaBuffer readBuffer ) -{ - if (c) { - if (!drawBuffer || !readBuffer) - return GL_FALSE; /* must specify buffers! */ - -#if 0 - /* XXX restore this optimization */ - if (&(c->mesa) == _mesa_get_current_context() - && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer - && c->mesa.ReadBuffer == &readBuffer->mesa_buffer - && xmesa_buffer(c->mesa.DrawBuffer)->wasCurrent) { - /* same context and buffer, do nothing */ - return GL_TRUE; - } -#endif - - c->xm_buffer = drawBuffer; - - /* Call this periodically to detect when the user has begun using - * GL rendering from multiple threads. - */ - _glapi_check_multithread(); - - st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb); - - xmesa_check_and_update_buffer_size(c, drawBuffer); - if (readBuffer != drawBuffer) - xmesa_check_and_update_buffer_size(c, readBuffer); - - /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */ - drawBuffer->wasCurrent = GL_TRUE; - } - else { - /* Detach */ - st_make_current( NULL, NULL, NULL ); - } - return GL_TRUE; -} - - -/* - * Unbind the context c from its buffer. - */ -GLboolean XMesaUnbindContext( XMesaContext c ) -{ - /* A no-op for XFree86 integration purposes */ - return GL_TRUE; -} - - -XMesaContext XMesaGetCurrentContext( void ) -{ - GET_CURRENT_CONTEXT(ctx); - if (ctx) { - XMesaContext xmesa = xmesa_context(ctx); - return xmesa; - } - else { - return 0; - } -} - - -XMesaBuffer XMesaGetCurrentBuffer( void ) -{ - GET_CURRENT_CONTEXT(ctx); - if (ctx) { - XMesaBuffer xmbuf = xmesa_buffer(ctx->DrawBuffer); - return xmbuf; - } - else { - return 0; - } -} - - -/* New in Mesa 3.1 */ -XMesaBuffer XMesaGetCurrentReadBuffer( void ) -{ - GET_CURRENT_CONTEXT(ctx); - if (ctx) { - return xmesa_buffer(ctx->ReadBuffer); - } - else { - return 0; - } -} - - -#ifdef XFree86Server -PUBLIC -GLboolean XMesaForceCurrent(XMesaContext c) -{ - if (c) { - _glapi_set_dispatch(c->mesa.CurrentDispatch); - - if (&(c->mesa) != _mesa_get_current_context()) { - _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer); - } - } - else { - _mesa_make_current(NULL, NULL, NULL); - } - return GL_TRUE; -} - - -PUBLIC -GLboolean XMesaLoseCurrent(XMesaContext c) -{ - (void) c; - _mesa_make_current(NULL, NULL, NULL); - return GL_TRUE; -} - - -PUBLIC -GLboolean XMesaCopyContext( XMesaContext xm_src, XMesaContext xm_dst, GLuint mask ) -{ - _mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask); - return GL_TRUE; -} -#endif /* XFree86Server */ - - -#ifndef FX -GLboolean XMesaSetFXmode( GLint mode ) -{ - (void) mode; - return GL_FALSE; -} -#endif - - - -/* - * Copy the back buffer to the front buffer. If there's no back buffer - * this is a no-op. - */ -PUBLIC -void XMesaSwapBuffers( XMesaBuffer b ) -{ - struct pipe_surface *surf; - - /* If we're swapping the buffer associated with the current context - * we have to flush any pending rendering commands first. - */ - st_notify_swapbuffers(b->stfb); - - surf = st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT); - if (surf) { - if (xmesa_mode == XMESA_AUB) - xmesa_display_aub( surf ); - else - xmesa_display_surface(b, surf); - } - - xmesa_check_and_update_buffer_size(NULL, b); -} - - - -/* - * Copy sub-region of back buffer to front buffer - */ -void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height ) -{ - struct pipe_surface *surf_front - = st_get_framebuffer_surface(b->stfb, ST_SURFACE_FRONT_LEFT); - struct pipe_surface *surf_back - = st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT); - struct pipe_context *pipe = NULL; /* XXX fix */ - - if (!surf_front || !surf_back) - return; - - pipe->surface_copy(pipe, - FALSE, - surf_front, x, y, /* dest */ - surf_back, x, y, /* src */ - width, height); -} - - - -/* - * Return the depth buffer associated with an XMesaBuffer. - * Input: b - the XMesa buffer handle - * Output: width, height - size of buffer in pixels - * bytesPerValue - bytes per depth value (2 or 4) - * buffer - pointer to depth buffer values - * Return: GL_TRUE or GL_FALSE to indicate success or failure. - */ -GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height, - GLint *bytesPerValue, void **buffer ) -{ - *width = 0; - *height = 0; - *bytesPerValue = 0; - *buffer = 0; - return GL_FALSE; -} - - -void XMesaFlush( XMesaContext c ) -{ - if (c && c->xm_visual->display) { -#ifdef XFree86Server - /* NOT_NEEDED */ -#else - st_finish(c->st); - XSync( c->xm_visual->display, False ); -#endif - } -} - - - -const char *XMesaGetString( XMesaContext c, int name ) -{ - (void) c; - if (name==XMESA_VERSION) { - return "5.0"; - } - else if (name==XMESA_EXTENSIONS) { - return ""; - } - else { - return NULL; - } -} - - - -XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d ) -{ - XMesaBuffer b; - for (b=XMesaBufferList; b; b=b->Next) { - if (b->drawable == d && b->xm_visual->display == dpy) { - return b; - } - } - return NULL; -} - - -/** - * Free/destroy all XMesaBuffers associated with given display. - */ -void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy) -{ - XMesaBuffer b, next; - for (b = XMesaBufferList; b; b = next) { - next = b->Next; - if (b->xm_visual->display == dpy) { - xmesa_free_buffer(b); - } - } -} - - -/* - * Look for XMesaBuffers whose X window has been destroyed. - * Deallocate any such XMesaBuffers. - */ -void XMesaGarbageCollect( void ) -{ - XMesaBuffer b, next; - for (b=XMesaBufferList; b; b=next) { - next = b->Next; - if (b->xm_visual && - b->xm_visual->display && - b->drawable && - b->type == WINDOW) { -#ifdef XFree86Server - /* NOT_NEEDED */ -#else - XSync(b->xm_visual->display, False); - if (!window_exists( b->xm_visual->display, b->drawable )) { - /* found a dead window, free the ancillary info */ - XMesaDestroyBuffer( b ); - } -#endif - } - } -} - - -unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y, - GLfloat red, GLfloat green, - GLfloat blue, GLfloat alpha ) -{ - /* no longer supported */ - return 0; -} - - -/* - * This is typically called when the window size changes and we need - * to reallocate the buffer's back/depth/stencil/accum buffers. - */ -PUBLIC void -XMesaResizeBuffers( XMesaBuffer b ) -{ - GET_CURRENT_CONTEXT(ctx); - XMesaContext xmctx = xmesa_context(ctx); - if (!xmctx) - return; - xmesa_check_and_update_buffer_size(xmctx, b); -} - - - - -PUBLIC void -XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer, - const int *attrib_list) -{ -} - - - -PUBLIC void -XMesaReleaseTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer) -{ -} - diff --git a/src/gallium/winsys/xlib/xm_image.c b/src/gallium/winsys/xlib/xm_image.c deleted file mode 100644 index 087b4e4c3a..0000000000 --- a/src/gallium/winsys/xlib/xm_image.c +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************** - -Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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. - -**************************************************************************/ - -/* - * Authors: - * Kevin E. Martin - * Brian Paul - */ - -#include -#include - -#include "glxheader.h" -#include "xmesaP.h" - -#ifdef XFree86Server - -#ifdef ROUNDUP -#undef ROUNDUP -#endif - -#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3)) - -XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height, char *data) -{ - XMesaImage *image; - - image = (XMesaImage *)xalloc(sizeof(XMesaImage)); - - if (image) { - image->width = width; - image->height = height; - image->data = data; - /* Always pad to 32 bits */ - image->bytes_per_line = ROUNDUP((bitsPerPixel * width), 32); - image->bits_per_pixel = bitsPerPixel; - } - - return image; -} - -void XMesaDestroyImage(XMesaImage *image) -{ - if (image->data) - free(image->data); - xfree(image); -} - -unsigned long XMesaGetPixel(XMesaImage *image, int x, int y) -{ - CARD8 *row = (CARD8 *)(image->data + y*image->bytes_per_line); - CARD8 *i8; - CARD16 *i16; - CARD32 *i32; - switch (image->bits_per_pixel) { - case 8: - i8 = (CARD8 *)row; - return i8[x]; - break; - case 15: - case 16: - i16 = (CARD16 *)row; - return i16[x]; - break; - case 24: /* WARNING: architecture specific code */ - i8 = (CARD8 *)row; - return (((CARD32)i8[x*3]) | - (((CARD32)i8[x*3+1])<<8) | - (((CARD32)i8[x*3+2])<<16)); - break; - case 32: - i32 = (CARD32 *)row; - return i32[x]; - break; - } - return 0; -} - -#ifndef XMESA_USE_PUTPIXEL_MACRO -void XMesaPutPixel(XMesaImage *image, int x, int y, unsigned long pixel) -{ - CARD8 *row = (CARD8 *)(image->data + y*image->bytes_per_line); - CARD8 *i8; - CARD16 *i16; - CARD32 *i32; - switch (image->bits_per_pixel) { - case 8: - i8 = (CARD8 *)row; - i8[x] = (CARD8)pixel; - break; - case 15: - case 16: - i16 = (CARD16 *)row; - i16[x] = (CARD16)pixel; - break; - case 24: /* WARNING: architecture specific code */ - i8 = (CARD8 *)__row; - i8[x*3] = (CARD8)(p); - i8[x*3+1] = (CARD8)(p>>8); - i8[x*3+2] = (CARD8)(p>>16); - case 32: - i32 = (CARD32 *)row; - i32[x] = (CARD32)pixel; - break; - } -} -#endif - -#endif /* XFree86Server */ diff --git a/src/gallium/winsys/xlib/xm_image.h b/src/gallium/winsys/xlib/xm_image.h deleted file mode 100644 index 2a5e0f3777..0000000000 --- a/src/gallium/winsys/xlib/xm_image.h +++ /dev/null @@ -1,77 +0,0 @@ -/************************************************************************** - -Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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. - -**************************************************************************/ - -/* - * Authors: - * Kevin E. Martin - * Brian Paul - */ - -#ifndef _XM_IMAGE_H_ -#define _XM_IMAGE_H_ - -#define XMESA_USE_PUTPIXEL_MACRO - -extern XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height, - char *data); -extern void XMesaDestroyImage(XMesaImage *image); -extern unsigned long XMesaGetPixel(XMesaImage *image, int x, int y); -#ifdef XMESA_USE_PUTPIXEL_MACRO -#define XMesaPutPixel(__i,__x,__y,__p) \ -{ \ - CARD8 *__row = (CARD8 *)(__i->data + __y*__i->bytes_per_line); \ - CARD8 *__i8; \ - CARD16 *__i16; \ - CARD32 *__i32; \ - switch (__i->bits_per_pixel) { \ - case 8: \ - __i8 = (CARD8 *)__row; \ - __i8[__x] = (CARD8)__p; \ - break; \ - case 15: \ - case 16: \ - __i16 = (CARD16 *)__row; \ - __i16[__x] = (CARD16)__p; \ - break; \ - case 24: /* WARNING: architecture specific code */ \ - __i8 = (CARD8 *)__row; \ - __i8[__x*3] = (CARD8)(__p); \ - __i8[__x*3+1] = (CARD8)(__p>>8); \ - __i8[__x*3+2] = (CARD8)(__p>>16); \ - break; \ - case 32: \ - __i32 = (CARD32 *)__row; \ - __i32[__x] = (CARD32)__p; \ - break; \ - } \ -} -#else -extern void XMesaPutPixel(XMesaImage *image, int x, int y, - unsigned long pixel); -#endif - -#endif /* _XM_IMAGE_H_ */ diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c deleted file mode 100644 index acb5ad8f71..0000000000 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ /dev/null @@ -1,719 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ - -/* - * Authors: - * Keith Whitwell - * Brian Paul - */ - - -#include "glxheader.h" -#include "xmesaP.h" - -#undef ASSERT -#undef Elements - -#include "pipe/p_winsys.h" -#include "pipe/p_format.h" -#include "pipe/p_context.h" -#include "pipe/p_inlines.h" -#include "util/u_math.h" -#include "util/u_memory.h" -#include "softpipe/sp_winsys.h" - -#ifdef GALLIUM_CELL -#include "cell/ppu/cell_context.h" -#include "cell/ppu/cell_screen.h" -#include "cell/ppu/cell_winsys.h" -#else -#define TILE_SIZE 32 /* avoid compilation errors */ -#endif - -#ifdef GALLIUM_TRACE -#include "trace/tr_screen.h" -#include "trace/tr_context.h" -#endif - -#include "xm_winsys_aub.h" - - -/** - * Subclass of pipe_buffer for Xlib winsys. - * Low-level OS/window system memory buffer - */ -struct xm_buffer -{ - struct pipe_buffer base; - boolean userBuffer; /** Is this a user-space buffer? */ - void *data; - void *mapped; - - XImage *tempImage; - int shm; -#if defined(USE_XSHM) && !defined(XFree86Server) - XShmSegmentInfo shminfo; -#endif -}; - - -/** - * Subclass of pipe_winsys for Xlib winsys - */ -struct xmesa_pipe_winsys -{ - struct pipe_winsys base; - struct xmesa_visual *xm_visual; - int shm; -}; - - - -/** Cast wrapper */ -static INLINE struct xm_buffer * -xm_buffer( struct pipe_buffer *buf ) -{ - return (struct xm_buffer *)buf; -} - - -/** - * X Shared Memory Image extension code - */ -#if defined(USE_XSHM) && !defined(XFree86Server) - -#define XSHM_ENABLED(b) ((b)->shm) - -static volatile int mesaXErrorFlag = 0; - -/** - * Catches potential Xlib errors. - */ -static int -mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event) -{ - (void) dpy; - (void) event; - mesaXErrorFlag = 1; - return 0; -} - - -static GLboolean alloc_shm(struct xm_buffer *buf, unsigned size) -{ - XShmSegmentInfo *const shminfo = & buf->shminfo; - - shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); - if (shminfo->shmid < 0) { - return GL_FALSE; - } - - shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); - if (shminfo->shmaddr == (char *) -1) { - shmctl(shminfo->shmid, IPC_RMID, 0); - return GL_FALSE; - } - - shminfo->readOnly = False; - return GL_TRUE; -} - - -/** - * Allocate a shared memory XImage back buffer for the given XMesaBuffer. - */ -static void -alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, - unsigned width, unsigned height) -{ - /* - * We have to do a _lot_ of error checking here to be sure we can - * really use the XSHM extension. It seems different servers trigger - * errors at different points if the extension won't work. Therefore - * we have to be very careful... - */ -#if 0 - GC gc; -#endif - int (*old_handler)(XMesaDisplay *, XErrorEvent *); - - b->tempImage = XShmCreateImage(xmb->xm_visual->display, - xmb->xm_visual->visinfo->visual, - xmb->xm_visual->visinfo->depth, - ZPixmap, - NULL, - &b->shminfo, - width, height); - if (b->tempImage == NULL) { - b->shm = 0; - return; - } - - - mesaXErrorFlag = 0; - old_handler = XSetErrorHandler(mesaHandleXError); - /* This may trigger the X protocol error we're ready to catch: */ - XShmAttach(xmb->xm_visual->display, &b->shminfo); - XSync(xmb->xm_visual->display, False); - - if (mesaXErrorFlag) { - /* we are on a remote display, this error is normal, don't print it */ - XFlush(xmb->xm_visual->display); - mesaXErrorFlag = 0; - XDestroyImage(b->tempImage); - b->tempImage = NULL; - b->shm = 0; - (void) XSetErrorHandler(old_handler); - return; - } - - - /* Finally, try an XShmPutImage to be really sure the extension works */ -#if 0 - gc = XCreateGC(xmb->xm_visual->display, xmb->drawable, 0, NULL); - XShmPutImage(xmb->xm_visual->display, xmb->drawable, gc, - b->tempImage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False); - XSync(xmb->xm_visual->display, False); - XFreeGC(xmb->xm_visual->display, gc); - (void) XSetErrorHandler(old_handler); - if (mesaXErrorFlag) { - XFlush(xmb->xm_visual->display); - mesaXErrorFlag = 0; - XDestroyImage(b->tempImage); - b->tempImage = NULL; - b->shm = 0; - return; - } -#endif -} - -#else - -#define XSHM_ENABLED(b) 0 - -static void -alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, - unsigned width, unsigned height) -{ - b->shm = 0; -} -#endif /* USE_XSHM */ - - - - -/* Most callbacks map direcly onto dri_bufmgr operations: - */ -static void * -xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, - unsigned flags) -{ - struct xm_buffer *xm_buf = xm_buffer(buf); - xm_buf->mapped = xm_buf->data; - return xm_buf->mapped; -} - -static void -xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) -{ - struct xm_buffer *xm_buf = xm_buffer(buf); - xm_buf->mapped = NULL; -} - -static void -xm_buffer_destroy(struct pipe_winsys *pws, - struct pipe_buffer *buf) -{ - struct xm_buffer *oldBuf = xm_buffer(buf); - - if (oldBuf->data) { -#if defined(USE_XSHM) && !defined(XFree86Server) - if (oldBuf->shminfo.shmid >= 0) { - shmdt(oldBuf->shminfo.shmaddr); - shmctl(oldBuf->shminfo.shmid, IPC_RMID, 0); - - oldBuf->shminfo.shmid = -1; - oldBuf->shminfo.shmaddr = (char *) -1; - } - else -#endif - { - if (!oldBuf->userBuffer) { - align_free(oldBuf->data); - } - } - - oldBuf->data = NULL; - } - - free(oldBuf); -} - - -/** - * For Cell. Basically, rearrange the pixels/quads from this layout: - * +--+--+--+--+ - * |p0|p1|p2|p3|.... - * +--+--+--+--+ - * - * to this layout: - * +--+--+ - * |p0|p1|.... - * +--+--+ - * |p2|p3| - * +--+--+ - */ -static void -twiddle_tile(const uint *tileIn, uint *tileOut) -{ - int y, x; - - for (y = 0; y < TILE_SIZE; y+=2) { - for (x = 0; x < TILE_SIZE; x+=2) { - int k = 4 * (y/2 * TILE_SIZE/2 + x/2); - tileOut[y * TILE_SIZE + (x + 0)] = tileIn[k]; - tileOut[y * TILE_SIZE + (x + 1)] = tileIn[k+1]; - tileOut[(y + 1) * TILE_SIZE + (x + 0)] = tileIn[k+2]; - tileOut[(y + 1) * TILE_SIZE + (x + 1)] = tileIn[k+3]; - } - } -} - - - -/** - * Display a surface that's in a tiled configuration. That is, all the - * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory. - */ -static void -xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) -{ - XImage *ximage; - struct xm_buffer *xm_buf = xm_buffer(surf->buffer); - const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE; - uint x, y; - - if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { - alloc_shm_ximage(xm_buf, b, TILE_SIZE, TILE_SIZE); - } - - ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; - - /* check that the XImage has been previously initialized */ - assert(ximage->format); - assert(ximage->bitmap_unit); - - if (!XSHM_ENABLED(xm_buf)) { - /* update XImage's fields */ - ximage->width = TILE_SIZE; - ximage->height = TILE_SIZE; - ximage->bytes_per_line = TILE_SIZE * 4; - } - - for (y = 0; y < surf->height; y += TILE_SIZE) { - for (x = 0; x < surf->width; x += TILE_SIZE) { - uint tmpTile[TILE_SIZE * TILE_SIZE]; - int tx = x / TILE_SIZE; - int ty = y / TILE_SIZE; - int offset = ty * tilesPerRow + tx; - int w = TILE_SIZE; - int h = TILE_SIZE; - - if (y + h > surf->height) - h = surf->height - y; - if (x + w > surf->width) - w = surf->width - x; - - /* offset in pixels */ - offset *= TILE_SIZE * TILE_SIZE; - - if (0 && XSHM_ENABLED(xm_buf)) { - ximage->data = (char *) xm_buf->data + 4 * offset; - /* make copy of tile data */ - memcpy(tmpTile, (uint *) ximage->data, sizeof(tmpTile)); - /* twiddle from temp to ximage in shared memory */ - twiddle_tile(tmpTile, (uint *) ximage->data); - /* display image in shared memory */ -#if defined(USE_XSHM) && !defined(XFree86Server) - XShmPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, x, y, w, h, False); -#endif - } - else { - /* twiddle from ximage buffer to temp tile */ - twiddle_tile((uint *) xm_buf->data + offset, tmpTile); - /* display temp tile data */ - ximage->data = (char *) tmpTile; - XPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, x, y, w, h); - } - } - } -} - - -/** - * Display/copy the image in the surface into the X window specified - * by the XMesaBuffer. - */ -void -xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) -{ - XImage *ximage; - struct xm_buffer *xm_buf = xm_buffer(surf->buffer); - static boolean no_swap = 0; - static boolean firsttime = 1; - static int tileSize = 0; - - if (firsttime) { - no_swap = getenv("SP_NO_RAST") != NULL; -#ifdef GALLIUM_CELL - if (!getenv("GALLIUM_NOCELL")) { - tileSize = 32; /** probably temporary */ - } -#endif - firsttime = 0; - } - - if (no_swap) - return; - - if (tileSize) { - xmesa_display_surface_tiled(b, surf); - return; - } - - if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { - assert(surf->block.width == 1); - assert(surf->block.height == 1); - alloc_shm_ximage(xm_buf, b, surf->stride/surf->block.size, surf->height); - } - - ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; - ximage->data = xm_buf->data; - - /* display image in Window */ - if (XSHM_ENABLED(xm_buf)) { -#if defined(USE_XSHM) && !defined(XFree86Server) - XShmPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, 0, 0, surf->width, surf->height, False); -#endif - } else { - /* check that the XImage has been previously initialized */ - assert(ximage->format); - assert(ximage->bitmap_unit); - - /* update XImage's fields */ - ximage->width = surf->width; - ximage->height = surf->height; - ximage->bytes_per_line = surf->stride; - - XPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, 0, 0, surf->width, surf->height); - } -} - - -static void -xm_flush_frontbuffer(struct pipe_winsys *pws, - struct pipe_surface *surf, - void *context_private) -{ - /* - * The front color buffer is actually just another XImage buffer. - * This function copies that XImage to the actual X Window. - */ - XMesaContext xmctx = (XMesaContext) context_private; - xmesa_display_surface(xmctx->xm_buffer, surf); -} - - - -static const char * -xm_get_name(struct pipe_winsys *pws) -{ - return "Xlib"; -} - - -static struct pipe_buffer * -xm_buffer_create(struct pipe_winsys *pws, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); -#if defined(USE_XSHM) && !defined(XFree86Server) - struct xmesa_pipe_winsys *xpws = (struct xmesa_pipe_winsys *) pws; -#endif - - buffer->base.refcount = 1; - buffer->base.alignment = alignment; - buffer->base.usage = usage; - buffer->base.size = size; - - -#if defined(USE_XSHM) && !defined(XFree86Server) - buffer->shminfo.shmid = -1; - buffer->shminfo.shmaddr = (char *) -1; - - if (xpws->shm && (usage & PIPE_BUFFER_USAGE_PIXEL) != 0) { - buffer->shm = xpws->shm; - - if (alloc_shm(buffer, size)) { - buffer->data = buffer->shminfo.shmaddr; - } - } -#endif - - if (buffer->data == NULL) { - buffer->shm = 0; - - /* align to 16-byte multiple for Cell */ - buffer->data = align_malloc(size, max(alignment, 16)); - } - - return &buffer->base; -} - - -/** - * Create buffer which wraps user-space data. - */ -static struct pipe_buffer * -xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) -{ - struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); - buffer->base.refcount = 1; - buffer->base.size = bytes; - buffer->userBuffer = TRUE; - buffer->data = ptr; - buffer->shm = 0; - - return &buffer->base; -} - - - -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - -static int -xm_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, - unsigned width, unsigned height, - enum pipe_format format, - unsigned flags, - unsigned tex_usage) -{ - const unsigned alignment = 64; - - surf->width = width; - surf->height = height; - surf->format = format; - pf_get_block(format, &surf->block); - surf->nblocksx = pf_get_nblocksx(&surf->block, width); - surf->nblocksy = pf_get_nblocksy(&surf->block, height); - surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); - surf->usage = flags; - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, -#ifdef GALLIUM_CELL /* XXX a bit of a hack */ - surf->stride * round_up(surf->nblocksy, TILE_SIZE)); -#else - surf->stride * surf->nblocksy); -#endif - - if(!surf->buffer) - return -1; - - return 0; -} - - -/** - * Called via winsys->surface_alloc() to create new surfaces. - */ -static struct pipe_surface * -xm_surface_alloc(struct pipe_winsys *ws) -{ - struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); - - assert(ws); - - surface->refcount = 1; - surface->winsys = ws; - - return surface; -} - - - -static void -xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - assert(!surf->texture); - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - winsys_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; -} - - -/* - * Fence functions - basically nothing to do, as we don't create any actual - * fence objects. - */ - -static void -xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence) -{ -} - - -static int -xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - -static int -xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - -/** - * Return pointer to a pipe_winsys object. - * For Xlib, this is a singleton object. - * Nothing special for the Xlib driver so no subclassing or anything. - */ -struct pipe_winsys * -xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) -{ - static struct xmesa_pipe_winsys *ws = NULL; - - if (!ws) { - ws = (struct xmesa_pipe_winsys *) xmesa_create_pipe_winsys_aub(); - } - return &ws->base; -} - - -static struct pipe_winsys * -xmesa_get_pipe_winsys(struct xmesa_visual *xm_vis) -{ - static struct xmesa_pipe_winsys *ws = NULL; - - if (!ws) { - ws = CALLOC_STRUCT(xmesa_pipe_winsys); - - ws->xm_visual = xm_vis; - ws->shm = xmesa_check_for_xshm(xm_vis->display); - - /* Fill in this struct with callbacks that pipe will need to - * communicate with the window system, buffer manager, etc. - */ - ws->base.buffer_create = xm_buffer_create; - ws->base.user_buffer_create = xm_user_buffer_create; - ws->base.buffer_map = xm_buffer_map; - ws->base.buffer_unmap = xm_buffer_unmap; - ws->base.buffer_destroy = xm_buffer_destroy; - - ws->base.surface_alloc = xm_surface_alloc; - ws->base.surface_alloc_storage = xm_surface_alloc_storage; - ws->base.surface_release = xm_surface_release; - - ws->base.fence_reference = xm_fence_reference; - ws->base.fence_signalled = xm_fence_signalled; - ws->base.fence_finish = xm_fence_finish; - - ws->base.flush_frontbuffer = xm_flush_frontbuffer; - ws->base.get_name = xm_get_name; - } - - return &ws->base; -} - - -struct pipe_context * -xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) -{ - struct pipe_winsys *pws; - struct pipe_context *pipe; - - if (getenv("XM_AUB")) { - pws = xmesa_get_pipe_winsys_aub(xmesa->xm_visual); - } - else { - pws = xmesa_get_pipe_winsys(xmesa->xm_visual); - } - -#ifdef GALLIUM_CELL - if (!getenv("GALLIUM_NOCELL")) { - struct cell_winsys *cws = cell_get_winsys(pixelformat); - struct pipe_screen *screen = cell_create_screen(pws); - - pipe = cell_create_context(screen, cws); - } - else -#endif - { - struct pipe_screen *screen = softpipe_create_screen(pws); - - pipe = softpipe_create(screen, pws, NULL); - -#ifdef GALLIUM_TRACE - screen = trace_screen_create(screen); - - pipe = trace_context_create(screen, pipe); -#endif - } - - if (pipe) - pipe->priv = xmesa; - - return pipe; -} diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c deleted file mode 100644 index 56e16a0fb4..0000000000 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ /dev/null @@ -1,590 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ - -/* - * Authors: - * Keith Whitwell - * Brian Paul - */ - - -#include "glxheader.h" -#include "xmesaP.h" - -#include "pipe/p_winsys.h" -#include "pipe/p_inlines.h" -#include "util/u_math.h" -#include "util/u_memory.h" -#include "i965simple/brw_winsys.h" -#include "i965simple/brw_screen.h" -#include "brw_aub.h" -#include "xm_winsys_aub.h" - - - -struct aub_buffer { - char *data; - unsigned offset; - unsigned size; - unsigned refcount; - unsigned map_count; - boolean dump_on_unmap; -}; - - - -struct aub_pipe_winsys { - struct pipe_winsys winsys; - - struct brw_aubfile *aubfile; - - /* This is simple, isn't it: - */ - char *pool; - unsigned size; - unsigned used; -}; - - -/* Turn a pipe winsys into an aub/pipe winsys: - */ -static inline struct aub_pipe_winsys * -aub_pipe_winsys( struct pipe_winsys *winsys ) -{ - return (struct aub_pipe_winsys *)winsys; -} - - - -static INLINE struct aub_buffer * -aub_bo( struct pipe_buffer *bo ) -{ - return (struct aub_buffer *)bo; -} - -static INLINE struct pipe_buffer * -pipe_bo( struct aub_buffer *bo ) -{ - return (struct pipe_buffer *)bo; -} - - - - -static void *aub_buffer_map(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned flags ) -{ - struct aub_buffer *sbo = aub_bo(buf); - - assert(sbo->data); - - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) - sbo->dump_on_unmap = 1; - - sbo->map_count++; - return sbo->data; -} - -static void aub_buffer_unmap(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); - struct aub_buffer *sbo = aub_bo(buf); - - sbo->map_count--; - - if (sbo->map_count == 0 && - sbo->dump_on_unmap) { - - sbo->dump_on_unmap = 0; - - brw_aub_gtt_data( iws->aubfile, - sbo->offset, - sbo->data, - sbo->size, - 0, - 0); - } -} - - -static void -aub_buffer_destroy(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - free(buf); -} - - -void xmesa_buffer_subdata_aub(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned long offset, - unsigned long size, - const void *data, - unsigned aub_type, - unsigned aub_sub_type) -{ - struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); - struct aub_buffer *sbo = aub_bo(buf); - - assert(sbo->size > offset + size); - memcpy(sbo->data + offset, data, size); - - brw_aub_gtt_data( iws->aubfile, - sbo->offset + offset, - sbo->data + offset, - size, - aub_type, - aub_sub_type ); -} - -void xmesa_commands_aub(struct pipe_winsys *winsys, - unsigned *cmds, - unsigned nr_dwords) -{ - struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); - unsigned size = nr_dwords * 4; - - assert(iws->used + size < iws->size); - - brw_aub_gtt_cmds( iws->aubfile, - AUB_BUF_START + iws->used, - cmds, - nr_dwords * sizeof(int) ); - - iws->used += align(size, 4096); -} - - -static struct aub_pipe_winsys *global_winsys = NULL; - -void xmesa_display_aub( /* struct pipe_winsys *winsys, */ - struct pipe_surface *surface ) -{ -// struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); - brw_aub_dump_bmp( global_winsys->aubfile, - surface, - aub_bo(surface->buffer)->offset ); -} - - - -/* Pipe has no concept of pools. We choose the tex/region pool - * for all buffers. - */ -static struct pipe_buffer * -aub_buffer_create(struct pipe_winsys *winsys, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); - struct aub_buffer *sbo = CALLOC_STRUCT(aub_buffer); - - sbo->refcount = 1; - - /* Could reuse buffers that are not referenced in current - * batchbuffer. Can't do that atm, so always reallocate: - */ - assert(iws->used + size < iws->size); - sbo->data = iws->pool + iws->used; - sbo->offset = AUB_BUF_START + iws->used; - iws->used += align(size, 4096); - - sbo->size = size; - - return pipe_bo(sbo); -} - - -static struct pipe_buffer * -aub_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) -{ - struct aub_buffer *sbo; - - /* Lets hope this is meant for upload, not as a result! - */ - sbo = aub_bo(aub_buffer_create( winsys, 0, 0, 0 )); - - sbo->data = ptr; - sbo->size = bytes; - - return pipe_bo(sbo); -} - - -/* The state tracker (should!) keep track of whether the fake - * frontbuffer has been touched by any rendering since the last time - * we copied its contents to the real frontbuffer. Our task is easy: - */ -static void -aub_flush_frontbuffer( struct pipe_winsys *winsys, - struct pipe_surface *surf, - void *context_private) -{ - xmesa_display_aub( surf ); -} - -static struct pipe_surface * -aub_i915_surface_alloc(struct pipe_winsys *winsys) -{ - struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); - if (surf) { - surf->refcount = 1; - surf->winsys = winsys; - } - return surf; -} - - -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - -static int -aub_i915_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, - unsigned width, unsigned height, - enum pipe_format format, - unsigned flags, - unsigned tex_usage) -{ - const unsigned alignment = 64; - - surf->width = width; - surf->height = height; - surf->format = format; - pf_get_block(format, &surf->block); - surf->nblocksx = pf_get_nblocksx(&surf->block, width); - surf->nblocksy = pf_get_nblocksy(&surf->block, height); - surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); - surf->usage = flags; - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->stride * surf->nblocksy); - if(!surf->buffer) - return -1; - - return 0; -} - -static void -aub_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - winsys_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; -} - - - -static const char * -aub_get_name( struct pipe_winsys *winsys ) -{ - return "Aub/xlib"; -} - -struct pipe_winsys * -xmesa_create_pipe_winsys_aub( void ) -{ - struct aub_pipe_winsys *iws = CALLOC_STRUCT( aub_pipe_winsys ); - - /* Fill in this struct with callbacks that pipe will need to - * communicate with the window system, buffer manager, etc. - * - * Pipe would be happy with a malloc based memory manager, but - * the SwapBuffers implementation in this winsys driver requires - * that rendering be done to an appropriate _DriBufferObject. - */ - iws->winsys.buffer_create = aub_buffer_create; - iws->winsys.user_buffer_create = aub_user_buffer_create; - iws->winsys.buffer_map = aub_buffer_map; - iws->winsys.buffer_unmap = aub_buffer_unmap; - iws->winsys.buffer_destroy = aub_buffer_destroy; - iws->winsys.flush_frontbuffer = aub_flush_frontbuffer; - iws->winsys.get_name = aub_get_name; - - iws->winsys.surface_alloc = aub_i915_surface_alloc; - iws->winsys.surface_alloc_storage = aub_i915_surface_alloc_storage; - iws->winsys.surface_release = aub_i915_surface_release; - - iws->aubfile = brw_aubfile_create(); - iws->size = AUB_BUF_SIZE; - iws->pool = malloc(AUB_BUF_SIZE); - - /* HACK: static copy of this pointer: - */ - assert(global_winsys == NULL); - global_winsys = iws; - - return &iws->winsys; -} - - -void -xmesa_destroy_pipe_winsys_aub( struct pipe_winsys *winsys ) - -{ - struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); - brw_aub_destroy(iws->aubfile); - free(iws->pool); - free(iws); -} - - - - - - - -#define IWS_BATCHBUFFER_SIZE 1024 - -struct aub_brw_winsys { - struct brw_winsys winsys; /**< batch buffer funcs */ - struct aub_context *aub; - - struct pipe_winsys *pipe_winsys; - - unsigned batch_data[IWS_BATCHBUFFER_SIZE]; - unsigned batch_nr; - unsigned batch_size; - unsigned batch_alloc; -}; - - -/* Turn a i965simple winsys into an aub/i965simple winsys: - */ -static inline struct aub_brw_winsys * -aub_brw_winsys( struct brw_winsys *sws ) -{ - return (struct aub_brw_winsys *)sws; -} - - -/* Simple batchbuffer interface: - */ - -static unsigned *aub_i965_batch_start( struct brw_winsys *sws, - unsigned dwords, - unsigned relocs ) -{ - struct aub_brw_winsys *iws = aub_brw_winsys(sws); - - if (iws->batch_size < iws->batch_nr + dwords) - return NULL; - - iws->batch_alloc = iws->batch_nr + dwords; - return (void *)1; /* not a valid pointer! */ -} - -static void aub_i965_batch_dword( struct brw_winsys *sws, - unsigned dword ) -{ - struct aub_brw_winsys *iws = aub_brw_winsys(sws); - - assert(iws->batch_nr < iws->batch_alloc); - iws->batch_data[iws->batch_nr++] = dword; -} - -static void aub_i965_batch_reloc( struct brw_winsys *sws, - struct pipe_buffer *buf, - unsigned access_flags, - unsigned delta ) -{ - struct aub_brw_winsys *iws = aub_brw_winsys(sws); - - assert(iws->batch_nr < iws->batch_alloc); - iws->batch_data[iws->batch_nr++] = aub_bo(buf)->offset + delta; -} - -static unsigned aub_i965_get_buffer_offset( struct brw_winsys *sws, - struct pipe_buffer *buf, - unsigned access_flags ) -{ - return aub_bo(buf)->offset; -} - -static void aub_i965_batch_end( struct brw_winsys *sws ) -{ - struct aub_brw_winsys *iws = aub_brw_winsys(sws); - - assert(iws->batch_nr <= iws->batch_alloc); - iws->batch_alloc = 0; -} - -static void aub_i965_batch_flush( struct brw_winsys *sws, - struct pipe_fence_handle **fence ) -{ - struct aub_brw_winsys *iws = aub_brw_winsys(sws); - assert(iws->batch_nr <= iws->batch_size); - - if (iws->batch_nr) { - xmesa_commands_aub( iws->pipe_winsys, - iws->batch_data, - iws->batch_nr ); - } - - iws->batch_nr = 0; -} - - - -static void aub_i965_buffer_subdata_typed(struct brw_winsys *winsys, - struct pipe_buffer *buf, - unsigned long offset, - unsigned long size, - const void *data, - unsigned data_type) -{ - struct aub_brw_winsys *iws = aub_brw_winsys(winsys); - unsigned aub_type = DW_GENERAL_STATE; - unsigned aub_sub_type; - - switch (data_type) { - case BRW_CC_VP: - aub_sub_type = DWGS_COLOR_CALC_VIEWPORT_STATE; - break; - case BRW_CC_UNIT: - aub_sub_type = DWGS_COLOR_CALC_STATE; - break; - case BRW_WM_PROG: - aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; - break; - case BRW_SAMPLER_DEFAULT_COLOR: - aub_sub_type = DWGS_SAMPLER_DEFAULT_COLOR; - break; - case BRW_SAMPLER: - aub_sub_type = DWGS_SAMPLER_STATE; - break; - case BRW_WM_UNIT: - aub_sub_type = DWGS_WINDOWER_IZ_STATE; - break; - case BRW_SF_PROG: - aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; - break; - case BRW_SF_VP: - aub_sub_type = DWGS_STRIPS_FANS_VIEWPORT_STATE; - break; - case BRW_SF_UNIT: - aub_sub_type = DWGS_STRIPS_FANS_STATE; - break; - case BRW_VS_UNIT: - aub_sub_type = DWGS_VERTEX_SHADER_STATE; - break; - case BRW_VS_PROG: - aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; - break; - case BRW_GS_UNIT: - aub_sub_type = DWGS_GEOMETRY_SHADER_STATE; - break; - case BRW_GS_PROG: - aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; - break; - case BRW_CLIP_VP: - aub_sub_type = DWGS_CLIPPER_VIEWPORT_STATE; - break; - case BRW_CLIP_UNIT: - aub_sub_type = DWGS_CLIPPER_STATE; - break; - case BRW_CLIP_PROG: - aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; - break; - case BRW_SS_SURFACE: - aub_type = DW_SURFACE_STATE; - aub_sub_type = DWSS_SURFACE_STATE; - break; - case BRW_SS_SURF_BIND: - aub_type = DW_SURFACE_STATE; - aub_sub_type = DWSS_BINDING_TABLE_STATE; - break; - case BRW_CONSTANT_BUFFER: - aub_type = DW_CONSTANT_URB_ENTRY; - aub_sub_type = 0; - break; - - default: - assert(0); - break; - } - - xmesa_buffer_subdata_aub( iws->pipe_winsys, - buf, - offset, - size, - data, - aub_type, - aub_sub_type ); -} - -/** - * Create i965 hardware rendering context. - */ -struct pipe_context * -xmesa_create_i965simple( struct pipe_winsys *winsys ) -{ -#ifdef GALLIUM_CELL - return NULL; -#else - struct aub_brw_winsys *iws = CALLOC_STRUCT( aub_brw_winsys ); - struct pipe_screen *screen = brw_create_screen(winsys, 0/* XXX pci_id */); - - /* Fill in this struct with callbacks that i965simple will need to - * communicate with the window system, buffer manager, etc. - */ - iws->winsys.batch_start = aub_i965_batch_start; - iws->winsys.batch_dword = aub_i965_batch_dword; - iws->winsys.batch_reloc = aub_i965_batch_reloc; - iws->winsys.batch_end = aub_i965_batch_end; - iws->winsys.batch_flush = aub_i965_batch_flush; - iws->winsys.buffer_subdata_typed = aub_i965_buffer_subdata_typed; - iws->winsys.get_buffer_offset = aub_i965_get_buffer_offset; - - iws->pipe_winsys = winsys; - - iws->batch_size = IWS_BATCHBUFFER_SIZE; - - /* Create the i965simple context: - */ - return brw_create( screen, - &iws->winsys, - 0 ); -#endif -} diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.h b/src/gallium/winsys/xlib/xm_winsys_aub.h deleted file mode 100644 index cc2a755277..0000000000 --- a/src/gallium/winsys/xlib/xm_winsys_aub.h +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 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. - * - **************************************************************************/ - -#ifndef AUB_WINSYS_H -#define AUB_WINSYS_H - -struct pipe_context; -struct pipe_winsys; -struct pipe_buffer; -struct pipe_surface; - -struct pipe_winsys * -xmesa_create_pipe_winsys_aub( void ); - -void -xmesa_destroy_pipe_winsys_aub( struct pipe_winsys *winsys ); - - - -struct pipe_context * -xmesa_create_i965simple( struct pipe_winsys *winsys ); - - - -void xmesa_buffer_subdata_aub(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned long offset, - unsigned long size, - const void *data, - unsigned aub_type, - unsigned aub_sub_type); - -void xmesa_commands_aub(struct pipe_winsys *winsys, - unsigned *cmds, - unsigned nr_dwords); - - -void xmesa_display_aub( /* struct pipe_winsys *winsys, */ - struct pipe_surface *surface ); - -extern struct pipe_winsys * -xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis); - -#endif diff --git a/src/gallium/winsys/xlib/xmesaP.h b/src/gallium/winsys/xlib/xmesaP.h deleted file mode 100644 index fcaeee52bc..0000000000 --- a/src/gallium/winsys/xlib/xmesaP.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 1999-2007 Brian Paul 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ - - -#ifndef XMESAP_H -#define XMESAP_H - - -#include "GL/xmesa.h" -#include "mtypes.h" -#ifdef XFree86Server -#include "xm_image.h" -#endif - -#include "state_tracker/st_context.h" -#include "state_tracker/st_public.h" -#include "pipe/p_thread.h" - - -extern pipe_mutex _xmesa_lock; - -extern XMesaBuffer XMesaBufferList; - -/* - */ -#define XMESA_SOFTPIPE 1 -#define XMESA_AUB 2 -extern int xmesa_mode; - - -/** - * Visual inforation, derived from GLvisual. - * Basically corresponds to an XVisualInfo. - */ -struct xmesa_visual { - GLvisual mesa_visual; /* Device independent visual parameters */ - XMesaDisplay *display; /* The X11 display */ -#ifdef XFree86Server - GLint ColormapEntries; - GLint nplanes; -#else - XMesaVisualInfo visinfo; /* X's visual info (pointer to private copy) */ - XVisualInfo *vishandle; /* Only used in fakeglx.c */ -#endif - GLint BitsPerPixel; /* True bits per pixel for XImages */ - - GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */ -}; - - -/** - * Context info, derived from st_context. - * Basically corresponds to a GLXContext. - */ -struct xmesa_context { - struct st_context *st; - XMesaVisual xm_visual; /** pixel format info */ - XMesaBuffer xm_buffer; /** current drawbuffer */ -}; - - -/** - * Types of X/GLX drawables we might render into. - */ -typedef enum { - WINDOW, /* An X window */ - GLXWINDOW, /* GLX window */ - PIXMAP, /* GLX pixmap */ - PBUFFER /* GLX Pbuffer */ -} BufferType; - - -/** - * Framebuffer information, derived from. - * Basically corresponds to a GLXDrawable. - */ -struct xmesa_buffer { - struct st_framebuffer *stfb; - - GLboolean wasCurrent; /* was ever the current buffer? */ - XMesaVisual xm_visual; /* the X/Mesa visual */ - XMesaDrawable drawable; /* Usually the X window ID */ - XMesaColormap cmap; /* the X colormap */ - BufferType type; /* window, pixmap, pbuffer or glxwindow */ - - XMesaImage *tempImage; - unsigned long selectedEvents;/* for pbuffers only */ - - GLuint shm; /* X Shared Memory extension status: */ - /* 0 = not available */ - /* 1 = XImage support available */ - /* 2 = Pixmap support available too */ -#if defined(USE_XSHM) && !defined(XFree86Server) - XShmSegmentInfo shminfo; -#endif - - XMesaGC gc; /* scratch GC for span, line, tri drawing */ - - /* GLX_EXT_texture_from_pixmap */ - GLint TextureTarget; /** GLX_TEXTURE_1D_EXT, for example */ - GLint TextureFormat; /** GLX_TEXTURE_FORMAT_RGB_EXT, for example */ - GLint TextureMipmap; /** 0 or 1 */ - - struct xmesa_buffer *Next; /* Linked list pointer: */ -}; - - - -/** cast wrapper */ -static INLINE XMesaContext -xmesa_context(GLcontext *ctx) -{ - return (XMesaContext) ctx->DriverCtx; -} - - -/** cast wrapper */ -static INLINE XMesaBuffer -xmesa_buffer(GLframebuffer *fb) -{ - struct st_framebuffer *stfb = (struct st_framebuffer *) fb; - return (XMesaBuffer) st_framebuffer_private(stfb); -} - - -extern void -xmesa_delete_framebuffer(struct gl_framebuffer *fb); - -extern XMesaBuffer -xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis); - -extern void -xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer); - -extern void -xmesa_destroy_buffers_on_display(XMesaDisplay *dpy); - -extern struct pipe_context * -xmesa_create_pipe_context(XMesaContext xm, uint pixelformat); - -static INLINE GLuint -xmesa_buffer_width(XMesaBuffer b) -{ - return b->stfb->Base.Width; -} - -static INLINE GLuint -xmesa_buffer_height(XMesaBuffer b) -{ - return b->stfb->Base.Height; -} - -extern void -xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf); - -extern int -xmesa_check_for_xshm(XMesaDisplay *display); - -#endif -- cgit v1.2.3 From a129c7268acc5a36852fcb006391e1f4b51ce7e1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 8 Jan 2009 08:29:42 -0700 Subject: cell: fix breakage from xlib re-org Some of these fixes are quick band-aids for now. --- src/gallium/winsys/xlib/xlib_brw_context.c | 4 ++++ src/gallium/winsys/xlib/xlib_brw_screen.c | 4 ++++ src/gallium/winsys/xlib/xlib_softpipe.c | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xlib_brw_context.c b/src/gallium/winsys/xlib/xlib_brw_context.c index a2bac0cc93..528473925a 100644 --- a/src/gallium/winsys/xlib/xlib_brw_context.c +++ b/src/gallium/winsys/xlib/xlib_brw_context.c @@ -199,7 +199,11 @@ xlib_create_brw_context( struct pipe_screen *screen, /* Create the i965simple context: */ +#ifdef GALLIUM_CELL + return NULL; +#else return brw_create( screen, &xbcws->brw_context_winsys, 0 ); +#endif } diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c index b0c7977185..9325bdc7a6 100644 --- a/src/gallium/winsys/xlib/xlib_brw_screen.c +++ b/src/gallium/winsys/xlib/xlib_brw_screen.c @@ -352,7 +352,11 @@ xlib_create_brw_winsys( void ) struct pipe_screen * xlib_create_brw_screen( struct pipe_winsys *winsys ) { +#ifdef GALLIUM_CELL + return NULL; +#else return brw_create_screen(winsys, 0/* XXX pci_id */); +#endif } diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index e4aa2d4b6a..79722dd72b 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -708,7 +708,7 @@ xlib_create_cell_winsys( void ) struct pipe_screen * xlib_create_cell_screen( struct pipe_winsys *pws ) { - return xlib_create_softpipe_screen( pws ); + return cell_create_screen( pws ); } -- cgit v1.2.3 From 05f8e41b9567695e9b96276d3ac5734ed2b268a8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Jan 2009 10:40:47 +0000 Subject: xlib: combine and eliminate some header files --- src/gallium/winsys/xlib/xlib_softpipe.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index 79722dd72b..f53d8e02f4 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -33,8 +33,7 @@ */ -#include "glxheader.h" -#include "xmesaP.h" +#include "xm_api.h" #undef ASSERT #undef Elements @@ -109,7 +108,7 @@ static volatile int mesaXErrorFlag = 0; * Catches potential Xlib errors. */ static int -mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event) +mesaHandleXError(Display *dpy, XErrorEvent *event) { (void) dpy; (void) event; @@ -154,7 +153,7 @@ alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, #if 0 GC gc; #endif - int (*old_handler)(XMesaDisplay *, XErrorEvent *); + int (*old_handler)(Display *, XErrorEvent *); b->tempImage = XShmCreateImage(xmb->xm_visual->display, xmb->xm_visual->visinfo->visual, -- cgit v1.2.3 From 75aac1b49665b471a4da79de95441c625923f18f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Jan 2009 14:38:23 +0000 Subject: xlib: disable more cell calls when GALLIUM_CELL not defined --- src/gallium/winsys/xlib/xlib_softpipe.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index f53d8e02f4..2a8bd4681e 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -707,7 +707,11 @@ xlib_create_cell_winsys( void ) struct pipe_screen * xlib_create_cell_screen( struct pipe_winsys *pws ) { +#ifdef GALLIUM_CELL return cell_create_screen( pws ); +#else + return NULL; +#endif } -- cgit v1.2.3 From 61e843ff4bf9b9e8c4a7a8a485cee852a4f1dd86 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Jan 2009 17:52:06 +0000 Subject: xlib: move state tracker to glx/xlib Also, remove makefile hacks. --- src/gallium/winsys/xlib/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 129d038d4f..fbc947f363 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -19,7 +19,7 @@ INCLUDE_DIRS = \ -I$(TOP)/src/mesa/main \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/gallium/state_trackers/xlib \ + -I$(TOP)/src/gallium/state_trackers/glx/xlib \ -I$(TOP)/src/gallium/auxiliary XLIB_WINSYS_SOURCES = \ @@ -38,6 +38,7 @@ XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o) LIBS = \ $(GALLIUM_DRIVERS) \ + $(TOP)/src/gallium/state_trackers/glx/xlib/libxlib.a \ $(TOP)/src/mesa/libglapi.a \ $(TOP)/src/mesa/libmesa.a \ $(GALLIUM_AUXILIARIES) \ @@ -58,13 +59,12 @@ default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) # Make the libGL.so library -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) Makefile $(TOP)/bin/mklib -o $(GL_LIB) \ -linker "$(CC)" \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \ - $(TOP)/src/gallium/state_trackers/xlib/*.o \ --start-group $(LIBS) --end-group $(GL_LIB_DEPS) -- cgit v1.2.3 From 72aa42e59468817798484defe5b3f6dfec0d33e3 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 5 Dec 2008 02:21:55 -0500 Subject: nouveau: Swizzle textures larger than nv04 SIFM limit in parts. Limit of SIFM on nv40 is 1024x1024, not sure about others. --- src/gallium/winsys/drm/nouveau/nv04_surface.c | 90 ++++++++++++++++++++------- 1 file changed, 68 insertions(+), 22 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c index 68338eb814..e9a8a2ac1c 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -82,6 +82,37 @@ nv04_scaled_image_format(enum pipe_format format) } } +static INLINE unsigned +nv04_swizzle_bits(unsigned x, unsigned y) +{ + unsigned u = (x & 0x001) << 0 | + (x & 0x002) << 1 | + (x & 0x004) << 2 | + (x & 0x008) << 3 | + (x & 0x010) << 4 | + (x & 0x020) << 5 | + (x & 0x040) << 6 | + (x & 0x080) << 7 | + (x & 0x100) << 8 | + (x & 0x200) << 9 | + (x & 0x400) << 10 | + (x & 0x800) << 11; + + unsigned v = (y & 0x001) << 1 | + (y & 0x002) << 2 | + (y & 0x004) << 3 | + (y & 0x008) << 4 | + (y & 0x010) << 5 | + (y & 0x020) << 6 | + (y & 0x040) << 7 | + (y & 0x080) << 8 | + (y & 0x100) << 9 | + (y & 0x200) << 10 | + (y & 0x400) << 11 | + (y & 0x800) << 12; + return v | u; +} + static void nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h) @@ -90,19 +121,23 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, struct pipe_surface *dst = nv->surf_dst; struct pipe_surface *src = nv->surf_src; + const unsigned max_w = 1024; + const unsigned max_h = 1024; + const unsigned sub_w = w > max_w ? max_w : w; + const unsigned sub_h = h > max_h ? max_h : h; + unsigned cx = 0; + unsigned cy = 0; + /* POT or GTFO */ assert(!(w & (w - 1)) && !(h & (h - 1))); BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 2); + BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); OUT_RING (chan, nv04_surface_format(dst->format) | log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT | log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, @@ -110,24 +145,35 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); OUT_RING (chan, nv->nvc->NvSwzSurf->handle); - BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); - OUT_RING (chan, nv04_scaled_image_format(src->format)); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); - OUT_RING (chan, 0); - OUT_RING (chan, h << 16 | w); - OUT_RING (chan, 0); - OUT_RING (chan, h << 16 | w); - OUT_RING (chan, 1 << 20); - OUT_RING (chan, 1 << 20); - BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); - OUT_RING (chan, h << 16 | w); - OUT_RING (chan, src->stride | - NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | - NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, 0); + for (cy = 0; cy < h; cy += sub_h) { + for (cx = 0; cx < w; cx += sub_w) { + BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_OFFSET, 1); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, + dst->offset + nv04_swizzle_bits(cx, cy) * dst->block.size, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); + OUT_RING (chan, nv04_scaled_image_format(src->format)); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); + OUT_RING (chan, 0); + OUT_RING (chan, sub_h << 16 | sub_w); + OUT_RING (chan, 0); + OUT_RING (chan, sub_h << 16 | sub_w); + OUT_RING (chan, 1 << 20); + OUT_RING (chan, 1 << 20); + + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); + OUT_RING (chan, sub_h << 16 | sub_w); + OUT_RING (chan, src->stride | + NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | + NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, + src->offset + cy * src->stride + cx * src->block.size, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RING (chan, 0); + } + } } static void -- cgit v1.2.3 From 34c0281879b589dc42d134a10349eac66c7b2f0d Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 5 Dec 2008 02:26:07 -0500 Subject: nouveau: Put dynamic textures in GART for CPU access and don't swizzle. Also flag shadows as dynamic since they're for CPU access as well. --- src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c | 3 ++- src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c index 5276806de6..086f368319 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c @@ -49,7 +49,8 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, if (usage & PIPE_BUFFER_USAGE_PIXEL) { if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) flags |= NOUVEAU_BO_GART; - flags |= NOUVEAU_BO_VRAM; + if (!(usage & NOUVEAU_BUFFER_USAGE_CPU)) + flags |= NOUVEAU_BO_VRAM; switch (dev->chipset & 0xf0) { case 0x50: diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c index 4f6ac9cad0..17c677d83e 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c @@ -112,7 +112,8 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, if (usage & PIPE_BUFFER_USAGE_PIXEL) { if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) flags |= NOUVEAU_BO_GART; - flags |= NOUVEAU_BO_VRAM; + if (!(usage & NOUVEAU_BUFFER_USAGE_CPU)) + flags |= NOUVEAU_BO_VRAM; } if (usage & PIPE_BUFFER_USAGE_VERTEX) { -- cgit v1.2.3 From 7289c388f442fe532de52058f9167bc331920b1a Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 6 Dec 2008 15:45:00 -0500 Subject: nouveau: Use PIPE_BUFFER_USAGE_CPU_* instead of custom. --- src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c index 086f368319..fe10479db7 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c @@ -49,7 +49,7 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, if (usage & PIPE_BUFFER_USAGE_PIXEL) { if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) flags |= NOUVEAU_BO_GART; - if (!(usage & NOUVEAU_BUFFER_USAGE_CPU)) + if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE)) flags |= NOUVEAU_BO_VRAM; switch (dev->chipset & 0xf0) { diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c index 17c677d83e..d841eb4a04 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c @@ -112,7 +112,7 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, if (usage & PIPE_BUFFER_USAGE_PIXEL) { if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) flags |= NOUVEAU_BO_GART; - if (!(usage & NOUVEAU_BUFFER_USAGE_CPU)) + if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE)) flags |= NOUVEAU_BO_VRAM; } -- cgit v1.2.3 From af2a856caa84755d3b1a0a887d000ce7dc3221dd Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Thu, 11 Dec 2008 17:55:16 -0500 Subject: nouveau: Add busy() query, determines if BOs can be mapped immediately. --- src/gallium/winsys/drm/nouveau/nouveau_bo.c | 34 ++++++++++++++++++++++++++ src/gallium/winsys/drm/nouveau/nouveau_drmif.h | 3 +++ 2 files changed, 37 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nouveau_bo.c b/src/gallium/winsys/drm/nouveau/nouveau_bo.c index b5942994d9..76b98bed67 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/drm/nouveau/nouveau_bo.c @@ -272,6 +272,40 @@ nouveau_bo_del(struct nouveau_bo **bo) nouveau_bo_del_cb(nvbo); } +int +nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_fence *fence; + + if (!nvbo) + return -EINVAL; + + /* If the buffer is pending it must be busy, unless + * both are RD, in which case we can allow access */ + if (nvbo->pending) { + if ((nvbo->pending->flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD && + (flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD) + return 0; + else + return 1; + } + + if (flags & NOUVEAU_BO_WR) + fence = nvbo->fence; + else + fence = nvbo->wr_fence; + + /* If the buffer is not pending and doesn't have a fence + * that conflicts with our flags then it can't be busy + */ + if (!fence) + return 0; + else + /* If the fence is signalled the buffer is not busy, else is busy */ + return !nouveau_fence(fence)->signalled; +} + int nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags) { diff --git a/src/gallium/winsys/drm/nouveau/nouveau_drmif.h b/src/gallium/winsys/drm/nouveau/nouveau_drmif.h index dcd6a5eb0a..5f72800676 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/drm/nouveau/nouveau_drmif.h @@ -286,6 +286,9 @@ nouveau_bo_set_status(struct nouveau_bo *, uint32_t flags); extern void nouveau_bo_del(struct nouveau_bo **); +extern int +nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags); + extern int nouveau_bo_map(struct nouveau_bo *, uint32_t flags); -- cgit v1.2.3 From 87e39466dc49e033c4075f99343856637611b438 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Thu, 11 Dec 2008 18:05:59 -0500 Subject: g3dvl: Allocate one set of bufs, let winsys rename them as necessary. --- .../winsys/g3dvl/nouveau/nouveau_winsys_pipe.c | 64 ++++++++++++++++------ 1 file changed, 46 insertions(+), 18 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c index d841eb4a04..17c409e1ce 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c @@ -89,25 +89,10 @@ nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s) } } -static struct pipe_buffer * -nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, - unsigned usage, unsigned size) +static uint32_t +nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage) { - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; - struct nouveau_context *nv = nvpws->nv; - struct nouveau_device *dev = nv->nv_screen->device; - struct nouveau_pipe_buffer *nvbuf; - uint32_t flags; - - nvbuf = calloc(1, sizeof(*nvbuf)); - if (!nvbuf) - return NULL; - nvbuf->base.refcount = 1; - nvbuf->base.alignment = alignment; - nvbuf->base.usage = usage; - nvbuf->base.size = size; - - flags = NOUVEAU_BO_LOCAL; + uint32_t flags = NOUVEAU_BO_LOCAL; if (usage & PIPE_BUFFER_USAGE_PIXEL) { if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) @@ -126,6 +111,29 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, flags |= NOUVEAU_BO_GART; } + return flags; +} + +static struct pipe_buffer * +nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, + unsigned usage, unsigned size) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_context *nv = nvpws->nv; + struct nouveau_device *dev = nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + uint32_t flags; + + nvbuf = calloc(1, sizeof(*nvbuf)); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 1; + nvbuf->base.alignment = alignment; + nvbuf->base.usage = usage; + nvbuf->base.size = size; + + flags = nouveau_flags_from_usage(nv, usage); + if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) { free(nvbuf); return NULL; @@ -176,6 +184,26 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) map_flags |= NOUVEAU_BO_WR; + if ((map_flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_WR && + !nouveau_bo_busy(nvbuf->bo, map_flags)) { + /* XXX: Technically incorrect. If the client maps a buffer for write-only + * and leaves part of the buffer untouched it probably expects those parts + * to remain intact. This is violated because we allocate a whole new buffer + * and don't copy the previous buffer's contents, so this optimization is + * only valid if the client intends to overwrite the whole buffer. + */ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_context *nv = nvpws->nv; + struct nouveau_device *dev = nv->nv_screen->device; + struct nouveau_bo *rename; + uint32_t flags = nouveau_flags_from_usage(nv, buf->usage); + + if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) { + nouveau_bo_del(&nvbuf->bo); + nvbuf->bo = rename; + } + } + if (nouveau_bo_map(nvbuf->bo, map_flags)) return NULL; return nvbuf->bo->map; -- cgit v1.2.3 From 9beb004885ab5be652bcb733a5fd9ee729f89921 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 20 Dec 2008 14:42:29 -0500 Subject: nouveau: Catch some more leaks. --- src/gallium/winsys/drm/nouveau/nouveau_channel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/nouveau_channel.c b/src/gallium/winsys/drm/nouveau/nouveau_channel.c index 3b4dcd1ecf..b7127f8860 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_channel.c +++ b/src/gallium/winsys/drm/nouveau/nouveau_channel.c @@ -118,6 +118,8 @@ nouveau_channel_free(struct nouveau_channel **chan) nouveau_grobj_free(&nvchan->base.gart); nouveau_grobj_free(&nvchan->base.nullobj); + free(nvchan->pb.buffers); + free(nvchan->pb.relocs); cf.channel = nvchan->drm.channel; drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf)); free(nvchan); -- cgit v1.2.3 From 734b3cb182b4b7d1075faf60c1a23ab0a55af356 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 20 Dec 2008 17:37:24 -0500 Subject: g3dvl: Use Gallium thread wrappers. --- src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c index 375634bd05..f292586974 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c @@ -25,12 +25,12 @@ * **************************************************************************/ -#include +#include #include #include "nouveau_context.h" #include "nouveau_screen.h" -static pthread_mutex_t lockMutex = PTHREAD_MUTEX_INITIALIZER; +pipe_static_mutex(lockMutex); static void nouveau_contended_lock(struct nouveau_context *nv, unsigned int flags) @@ -62,7 +62,7 @@ LOCK_HARDWARE(struct nouveau_context *nv) struct nouveau_device_priv *nvdev = nouveau_device(dev); char __ret=0; - pthread_mutex_lock(&lockMutex); + pipe_mutex_lock(lockMutex); assert(!nv->locked); DRM_CAS(nvdev->lock, nvdev->ctx, @@ -88,5 +88,5 @@ UNLOCK_HARDWARE(struct nouveau_context *nv) DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx); - pthread_mutex_unlock(&lockMutex); + pipe_mutex_unlock(lockMutex); } -- cgit v1.2.3 From 8ee238be7587a232beeb56b1dc3b75e1b8fb903e Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 10 Jan 2009 13:30:29 -0500 Subject: nouveau: Factor out common winsys bits into libnouveaudrm.a --- src/gallium/winsys/drm/nouveau/Makefile | 65 +-- src/gallium/winsys/drm/nouveau/common/Makefile | 32 ++ .../winsys/drm/nouveau/common/Makefile.template | 59 +++ src/gallium/winsys/drm/nouveau/common/nouveau_bo.c | 504 +++++++++++++++++++++ .../winsys/drm/nouveau/common/nouveau_channel.c | 126 ++++++ .../winsys/drm/nouveau/common/nouveau_context.c | 262 +++++++++++ .../winsys/drm/nouveau/common/nouveau_context.h | 86 ++++ .../winsys/drm/nouveau/common/nouveau_device.c | 159 +++++++ .../winsys/drm/nouveau/common/nouveau_dma.c | 219 +++++++++ .../winsys/drm/nouveau/common/nouveau_dma.h | 143 ++++++ .../winsys/drm/nouveau/common/nouveau_dri.h | 28 ++ .../winsys/drm/nouveau/common/nouveau_drmif.h | 313 +++++++++++++ .../winsys/drm/nouveau/common/nouveau_fence.c | 214 +++++++++ .../winsys/drm/nouveau/common/nouveau_grobj.c | 107 +++++ .../winsys/drm/nouveau/common/nouveau_local.h | 115 +++++ .../winsys/drm/nouveau/common/nouveau_lock.c | 72 +++ .../winsys/drm/nouveau/common/nouveau_notifier.c | 137 ++++++ .../winsys/drm/nouveau/common/nouveau_pushbuf.c | 270 +++++++++++ .../winsys/drm/nouveau/common/nouveau_resource.c | 116 +++++ .../winsys/drm/nouveau/common/nouveau_screen.c | 31 ++ .../winsys/drm/nouveau/common/nouveau_screen.h | 27 ++ .../winsys/drm/nouveau/common/nouveau_winsys.c | 161 +++++++ .../drm/nouveau/common/nouveau_winsys_pipe.c | 229 ++++++++++ .../drm/nouveau/common/nouveau_winsys_pipe.h | 39 ++ .../drm/nouveau/common/nouveau_winsys_softpipe.c | 101 +++++ .../winsys/drm/nouveau/common/nv04_surface.c | 466 +++++++++++++++++++ .../winsys/drm/nouveau/common/nv50_surface.c | 194 ++++++++ src/gallium/winsys/drm/nouveau/dri/Makefile | 31 ++ .../winsys/drm/nouveau/dri/nouveau_context_dri.c | 124 +++++ .../winsys/drm/nouveau/dri/nouveau_context_dri.h | 49 ++ .../winsys/drm/nouveau/dri/nouveau_screen_dri.c | 259 +++++++++++ .../winsys/drm/nouveau/dri/nouveau_screen_dri.h | 13 + .../winsys/drm/nouveau/dri/nouveau_swapbuffers.c | 112 +++++ .../winsys/drm/nouveau/dri/nouveau_swapbuffers.h | 10 + src/gallium/winsys/drm/nouveau/nouveau_bo.c | 504 --------------------- src/gallium/winsys/drm/nouveau/nouveau_channel.c | 128 ------ src/gallium/winsys/drm/nouveau/nouveau_context.c | 346 -------------- src/gallium/winsys/drm/nouveau/nouveau_context.h | 113 ----- src/gallium/winsys/drm/nouveau/nouveau_device.c | 159 ------- src/gallium/winsys/drm/nouveau/nouveau_dma.c | 219 --------- src/gallium/winsys/drm/nouveau/nouveau_dma.h | 143 ------ src/gallium/winsys/drm/nouveau/nouveau_dri.h | 28 -- src/gallium/winsys/drm/nouveau/nouveau_drmif.h | 313 ------------- src/gallium/winsys/drm/nouveau/nouveau_fence.c | 214 --------- src/gallium/winsys/drm/nouveau/nouveau_grobj.c | 107 ----- src/gallium/winsys/drm/nouveau/nouveau_local.h | 117 ----- src/gallium/winsys/drm/nouveau/nouveau_lock.c | 94 ---- src/gallium/winsys/drm/nouveau/nouveau_notifier.c | 137 ------ src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c | 271 ----------- src/gallium/winsys/drm/nouveau/nouveau_resource.c | 116 ----- src/gallium/winsys/drm/nouveau/nouveau_screen.c | 265 ----------- src/gallium/winsys/drm/nouveau/nouveau_screen.h | 20 - .../winsys/drm/nouveau/nouveau_swapbuffers.c | 86 ---- .../winsys/drm/nouveau/nouveau_swapbuffers.h | 10 - src/gallium/winsys/drm/nouveau/nouveau_winsys.c | 161 ------- .../winsys/drm/nouveau/nouveau_winsys_pipe.c | 207 --------- .../winsys/drm/nouveau/nouveau_winsys_pipe.h | 34 -- .../winsys/drm/nouveau/nouveau_winsys_softpipe.c | 86 ---- src/gallium/winsys/drm/nouveau/nv04_surface.c | 466 ------------------- src/gallium/winsys/drm/nouveau/nv50_surface.c | 194 -------- src/gallium/winsys/g3dvl/nouveau/Makefile | 48 +- src/gallium/winsys/g3dvl/nouveau/nouveau_context.c | 370 --------------- src/gallium/winsys/g3dvl/nouveau/nouveau_context.h | 105 ----- .../winsys/g3dvl/nouveau/nouveau_context_vl.c | 172 +++++++ .../winsys/g3dvl/nouveau/nouveau_context_vl.h | 39 ++ src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c | 91 ---- src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h | 24 - .../winsys/g3dvl/nouveau/nouveau_screen_vl.c | 88 ++++ .../winsys/g3dvl/nouveau/nouveau_screen_vl.h | 20 + .../winsys/g3dvl/nouveau/nouveau_swapbuffers.c | 61 ++- 70 files changed, 5217 insertions(+), 5212 deletions(-) create mode 100644 src/gallium/winsys/drm/nouveau/common/Makefile create mode 100644 src/gallium/winsys/drm/nouveau/common/Makefile.template create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_bo.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_channel.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_context.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_context.h create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_device.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_dma.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_dma.h create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_dri.h create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_fence.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_local.h create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_lock.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_resource.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_screen.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_screen.h create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h create mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nv04_surface.c create mode 100644 src/gallium/winsys/drm/nouveau/common/nv50_surface.c create mode 100644 src/gallium/winsys/drm/nouveau/dri/Makefile create mode 100644 src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c create mode 100644 src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h create mode 100644 src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c create mode 100644 src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h create mode 100644 src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c create mode 100644 src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_bo.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_channel.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_context.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_context.h delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_device.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_dma.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_dma.h delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_dri.h delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_drmif.h delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_fence.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_grobj.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_local.h delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_lock.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_notifier.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_resource.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_screen.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_screen.h delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_winsys.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h delete mode 100644 src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c delete mode 100644 src/gallium/winsys/drm/nouveau/nv04_surface.c delete mode 100644 src/gallium/winsys/drm/nouveau/nv50_surface.c delete mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_context.c delete mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_context.h create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.h delete mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c delete mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile index 81562ca78d..b5735329ec 100644 --- a/src/gallium/winsys/drm/nouveau/Makefile +++ b/src/gallium/winsys/drm/nouveau/Makefile @@ -1,46 +1,25 @@ - TOP = ../../../../.. include $(TOP)/configs/current -LIBNAME = nouveau_dri.so - -MINIGLX_SOURCES = - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.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_bo.c \ - nouveau_channel.c \ - nouveau_context.c \ - nouveau_device.c \ - nouveau_dma.c \ - nouveau_fence.c \ - nouveau_grobj.c \ - nouveau_lock.c \ - nouveau_notifier.c \ - nouveau_pushbuf.c \ - nouveau_resource.c \ - nouveau_screen.c \ - nouveau_swapbuffers.c \ - nouveau_winsys.c \ - nouveau_winsys_pipe.c \ - nouveau_winsys_softpipe.c \ - nv04_surface.c \ - nv50_surface.c - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - -include ../Makefile.template - -symlinks: + +SUBDIRS = common dri + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` + rm -f `find . -name depend` + + +# Dummy install target +install: diff --git a/src/gallium/winsys/drm/nouveau/common/Makefile b/src/gallium/winsys/drm/nouveau/common/Makefile new file mode 100644 index 0000000000..06f558959d --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/Makefile @@ -0,0 +1,32 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +LIBNAME = nouveaudrm + +C_SOURCES = \ + nouveau_bo.c \ + nouveau_channel.c \ + nouveau_context.c \ + nouveau_device.c \ + nouveau_dma.c \ + nouveau_fence.c \ + nouveau_grobj.c \ + nouveau_lock.c \ + nouveau_notifier.c \ + nouveau_pushbuf.c \ + nouveau_resource.c \ + nouveau_screen.c \ + nouveau_winsys.c \ + nouveau_winsys_pipe.c \ + nouveau_winsys_softpipe.c \ + nv04_surface.c \ + nv50_surface.c + + +include ./Makefile.template + +DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \ + && pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") +symlinks: + diff --git a/src/gallium/winsys/drm/nouveau/common/Makefile.template b/src/gallium/winsys/drm/nouveau/common/Makefile.template new file mode 100644 index 0000000000..e40836e0a8 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/Makefile.template @@ -0,0 +1,59 @@ +# -*-makefile-*- + +COMMON_SOURCES = + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(CPP_SOURCES:.cpp=.o) \ + $(ASM_SOURCES:.S=.o) + + +### Include directories +INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/include \ + $(DRIVER_INCLUDES) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) + + +$(LIBNAME): $(OBJECTS) Makefile Makefile.template + $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) + + +depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean:: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +include depend diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_bo.c b/src/gallium/winsys/drm/nouveau/common/nouveau_bo.c new file mode 100644 index 0000000000..76b98bed67 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_bo.c @@ -0,0 +1,504 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" +#include "nouveau_local.h" + +static void +nouveau_mem_free(struct nouveau_device *dev, struct drm_nouveau_mem_alloc *ma, + void **map) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct drm_nouveau_mem_free mf; + + if (map && *map) { + drmUnmap(*map, ma->size); + *map = NULL; + } + + if (ma->size) { + mf.offset = ma->offset; + mf.flags = ma->flags; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_MEM_FREE, + &mf, sizeof(mf)); + ma->size = 0; + } +} + +static int +nouveau_mem_alloc(struct nouveau_device *dev, unsigned size, unsigned align, + uint32_t flags, struct drm_nouveau_mem_alloc *ma, void **map) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + int ret; + + ma->alignment = align; + ma->size = size; + ma->flags = flags; + if (map) + ma->flags |= NOUVEAU_MEM_MAPPED; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_MEM_ALLOC, ma, + sizeof(struct drm_nouveau_mem_alloc)); + if (ret) + return ret; + + if (map) { + ret = drmMap(nvdev->fd, ma->map_handle, ma->size, map); + if (ret) { + *map = NULL; + nouveau_mem_free(dev, ma, map); + return ret; + } + } + + return 0; +} + +static void +nouveau_bo_tmp_del(void *priv) +{ + struct nouveau_resource *r = priv; + + nouveau_fence_ref(NULL, (struct nouveau_fence **)&r->priv); + nouveau_resource_free(&r); +} + +static unsigned +nouveau_bo_tmp_max(struct nouveau_device_priv *nvdev) +{ + struct nouveau_resource *r = nvdev->sa_heap; + unsigned max = 0; + + while (r) { + if (r->in_use && !nouveau_fence(r->priv)->emitted) { + r = r->next; + continue; + } + + if (max < r->size) + max = r->size; + r = r->next; + } + + return max; +} + +static struct nouveau_resource * +nouveau_bo_tmp(struct nouveau_channel *chan, unsigned size, + struct nouveau_fence *fence) +{ + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_resource *r = NULL; + struct nouveau_fence *ref = NULL; + + if (fence) + nouveau_fence_ref(fence, &ref); + else + nouveau_fence_new(chan, &ref); + assert(ref); + + while (nouveau_resource_alloc(nvdev->sa_heap, size, ref, &r)) { + if (nouveau_bo_tmp_max(nvdev) < size) { + nouveau_fence_ref(NULL, &ref); + return NULL; + } + + nouveau_fence_flush(chan); + } + nouveau_fence_signal_cb(ref, nouveau_bo_tmp_del, r); + + return r; +} + +int +nouveau_bo_init(struct nouveau_device *dev) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + int ret; + + ret = nouveau_mem_alloc(dev, 128*1024, 0, NOUVEAU_MEM_AGP | + NOUVEAU_MEM_PCI, &nvdev->sa, &nvdev->sa_map); + if (ret) + return ret; + + ret = nouveau_resource_init(&nvdev->sa_heap, 0, nvdev->sa.size); + if (ret) { + nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); + return ret; + } + + return 0; +} + +void +nouveau_bo_takedown(struct nouveau_device *dev) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); +} + +int +nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, + int size, struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + int ret; + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo = calloc(1, sizeof(struct nouveau_bo_priv)); + if (!nvbo) + return -ENOMEM; + nvbo->base.device = dev; + nvbo->base.size = size; + nvbo->base.handle = bo_to_ptr(nvbo); + nvbo->drm.alignment = align; + nvbo->refcount = 1; + + if (flags & NOUVEAU_BO_TILED) { + nvbo->tiled = 1; + if (flags & NOUVEAU_BO_ZTILE) + nvbo->tiled |= 2; + flags &= ~NOUVEAU_BO_TILED; + } + + ret = nouveau_bo_set_status(&nvbo->base, flags); + if (ret) { + free(nvbo); + return ret; + } + + *bo = &nvbo->base; + return 0; +} + +int +nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size, + struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo = calloc(1, sizeof(*nvbo)); + if (!nvbo) + return -ENOMEM; + nvbo->base.device = dev; + + nvbo->sysmem = ptr; + nvbo->user = 1; + + nvbo->base.size = size; + nvbo->base.offset = nvbo->drm.offset; + nvbo->base.handle = bo_to_ptr(nvbo); + nvbo->refcount = 1; + *bo = &nvbo->base; + return 0; +} + +int +nouveau_bo_ref(struct nouveau_device *dev, uint64_t handle, + struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo = ptr_to_bo(handle); + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo->refcount++; + *bo = &nvbo->base; + return 0; +} + +static void +nouveau_bo_del_cb(void *priv) +{ + struct nouveau_bo_priv *nvbo = priv; + + nouveau_fence_ref(NULL, &nvbo->fence); + nouveau_mem_free(nvbo->base.device, &nvbo->drm, &nvbo->map); + if (nvbo->sysmem && !nvbo->user) + free(nvbo->sysmem); + free(nvbo); +} + +void +nouveau_bo_del(struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + + if (!bo || !*bo) + return; + nvbo = nouveau_bo(*bo); + *bo = NULL; + + if (--nvbo->refcount) + return; + + if (nvbo->pending) + nouveau_pushbuf_flush(nvbo->pending->channel, 0); + + if (nvbo->fence) + nouveau_fence_signal_cb(nvbo->fence, nouveau_bo_del_cb, nvbo); + else + nouveau_bo_del_cb(nvbo); +} + +int +nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_fence *fence; + + if (!nvbo) + return -EINVAL; + + /* If the buffer is pending it must be busy, unless + * both are RD, in which case we can allow access */ + if (nvbo->pending) { + if ((nvbo->pending->flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD && + (flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD) + return 0; + else + return 1; + } + + if (flags & NOUVEAU_BO_WR) + fence = nvbo->fence; + else + fence = nvbo->wr_fence; + + /* If the buffer is not pending and doesn't have a fence + * that conflicts with our flags then it can't be busy + */ + if (!fence) + return 0; + else + /* If the fence is signalled the buffer is not busy, else is busy */ + return !nouveau_fence(fence)->signalled; +} + +int +nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + + if (!nvbo) + return -EINVAL; + + if (nvbo->pending && + (nvbo->pending->flags & NOUVEAU_BO_WR || flags & NOUVEAU_BO_WR)) { + nouveau_pushbuf_flush(nvbo->pending->channel, 0); + } + + if (flags & NOUVEAU_BO_WR) + nouveau_fence_wait(&nvbo->fence); + else + nouveau_fence_wait(&nvbo->wr_fence); + + if (nvbo->sysmem) + bo->map = nvbo->sysmem; + else + bo->map = nvbo->map; + return 0; +} + +void +nouveau_bo_unmap(struct nouveau_bo *bo) +{ + bo->map = NULL; +} + +static int +nouveau_bo_upload(struct nouveau_bo_priv *nvbo) +{ + if (nvbo->fence) + nouveau_fence_wait(&nvbo->fence); + memcpy(nvbo->map, nvbo->sysmem, nvbo->drm.size); + return 0; +} + +int +nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct drm_nouveau_mem_alloc new; + void *new_map = NULL, *new_sysmem = NULL; + unsigned new_flags = 0, ret; + + assert(!bo->map); + + /* Check current memtype vs requested, if they match do nothing */ + if ((nvbo->drm.flags & NOUVEAU_MEM_FB) && (flags & NOUVEAU_BO_VRAM)) + return 0; + if ((nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) && + (flags & NOUVEAU_BO_GART)) + return 0; + if (nvbo->drm.size == 0 && nvbo->sysmem && (flags & NOUVEAU_BO_LOCAL)) + return 0; + + memset(&new, 0x00, sizeof(new)); + + /* Allocate new memory */ + if (flags & NOUVEAU_BO_VRAM) + new_flags |= NOUVEAU_MEM_FB; + else + if (flags & NOUVEAU_BO_GART) + new_flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI); + + if (nvbo->tiled && flags) { + new_flags |= NOUVEAU_MEM_TILE; + if (nvbo->tiled & 2) + new_flags |= NOUVEAU_MEM_TILE_ZETA; + } + + if (new_flags) { + ret = nouveau_mem_alloc(bo->device, bo->size, + nvbo->drm.alignment, new_flags, + &new, &new_map); + if (ret) + return ret; + } else + if (!nvbo->user) { + new_sysmem = malloc(bo->size); + } + + /* Copy old -> new */ + /*XXX: use M2MF */ + if (nvbo->sysmem || nvbo->map) { + struct nouveau_pushbuf_bo *pbo = nvbo->pending; + nvbo->pending = NULL; + nouveau_bo_map(bo, NOUVEAU_BO_RD); + memcpy(new_map, bo->map, bo->size); + nouveau_bo_unmap(bo); + nvbo->pending = pbo; + } + + /* Free old memory */ + if (nvbo->fence) + nouveau_fence_wait(&nvbo->fence); + nouveau_mem_free(bo->device, &nvbo->drm, &nvbo->map); + if (nvbo->sysmem && !nvbo->user) + free(nvbo->sysmem); + + nvbo->drm = new; + nvbo->map = new_map; + if (!nvbo->user) + nvbo->sysmem = new_sysmem; + bo->flags = flags; + bo->offset = nvbo->drm.offset; + return 0; +} + +static int +nouveau_bo_validate_user(struct nouveau_channel *chan, struct nouveau_bo *bo, + struct nouveau_fence *fence, uint32_t flags) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_resource *r; + + if (nvchan->user_charge + bo->size > nvdev->sa.size) + return 1; + + if (!(flags & NOUVEAU_BO_GART)) + return 1; + + r = nouveau_bo_tmp(chan, bo->size, fence); + if (!r) + return 1; + nvchan->user_charge += bo->size; + + memcpy(nvdev->sa_map + r->start, nvbo->sysmem, bo->size); + + nvbo->offset = nvdev->sa.offset + r->start; + nvbo->flags = NOUVEAU_BO_GART; + return 0; +} + +static int +nouveau_bo_validate_bo(struct nouveau_channel *chan, struct nouveau_bo *bo, + struct nouveau_fence *fence, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + int ret; + + ret = nouveau_bo_set_status(bo, flags); + if (ret) { + nouveau_fence_flush(chan); + + ret = nouveau_bo_set_status(bo, flags); + if (ret) + return ret; + } + + if (nvbo->user) + nouveau_bo_upload(nvbo); + + nvbo->offset = nvbo->drm.offset; + if (nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) + nvbo->flags = NOUVEAU_BO_GART; + else + nvbo->flags = NOUVEAU_BO_VRAM; + + return 0; +} + +int +nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo, + uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_fence *fence = nouveau_pushbuf(chan->pushbuf)->fence; + int ret; + + assert(bo->map == NULL); + + if (nvbo->user) { + ret = nouveau_bo_validate_user(chan, bo, fence, flags); + if (ret) { + ret = nouveau_bo_validate_bo(chan, bo, fence, flags); + if (ret) + return ret; + } + } else { + ret = nouveau_bo_validate_bo(chan, bo, fence, flags); + if (ret) + return ret; + } + + if (flags & NOUVEAU_BO_WR) + nouveau_fence_ref(fence, &nvbo->wr_fence); + nouveau_fence_ref(fence, &nvbo->fence); + return 0; +} + diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_channel.c b/src/gallium/winsys/drm/nouveau/common/nouveau_channel.c new file mode 100644 index 0000000000..b7298131c1 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_channel.c @@ -0,0 +1,126 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include +#include +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +int +nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, + uint32_t tt_ctxdma, struct nouveau_channel **chan) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct nouveau_channel_priv *nvchan; + int ret; + + if (!nvdev || !chan || *chan) + return -EINVAL; + + nvchan = CALLOC_STRUCT(nouveau_channel_priv); + if (!nvchan) + return -ENOMEM; + nvchan->base.device = dev; + + nvchan->drm.fb_ctxdma_handle = fb_ctxdma; + nvchan->drm.tt_ctxdma_handle = tt_ctxdma; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, + &nvchan->drm, sizeof(nvchan->drm)); + if (ret) { + FREE(nvchan); + return ret; + } + + nvchan->base.id = nvchan->drm.channel; + if (nouveau_grobj_ref(&nvchan->base, nvchan->drm.fb_ctxdma_handle, + &nvchan->base.vram) || + nouveau_grobj_ref(&nvchan->base, nvchan->drm.tt_ctxdma_handle, + &nvchan->base.gart)) { + nouveau_channel_free((void *)&nvchan); + return -EINVAL; + } + + ret = drmMap(nvdev->fd, nvchan->drm.ctrl, nvchan->drm.ctrl_size, + (void*)&nvchan->user); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + nvchan->put = &nvchan->user[0x40/4]; + nvchan->get = &nvchan->user[0x44/4]; + nvchan->ref_cnt = &nvchan->user[0x48/4]; + + ret = drmMap(nvdev->fd, nvchan->drm.notifier, nvchan->drm.notifier_size, + (drmAddressPtr)&nvchan->notifier_block); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + ret = drmMap(nvdev->fd, nvchan->drm.cmdbuf, nvchan->drm.cmdbuf_size, + (void*)&nvchan->pushbuf); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + ret = nouveau_grobj_alloc(&nvchan->base, 0x00000000, 0x0030, + &nvchan->base.nullobj); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + nouveau_dma_channel_init(&nvchan->base); + nouveau_pushbuf_init(&nvchan->base); + + *chan = &nvchan->base; + return 0; +} + +void +nouveau_channel_free(struct nouveau_channel **chan) +{ + struct nouveau_channel_priv *nvchan; + struct nouveau_device_priv *nvdev; + struct drm_nouveau_channel_free cf; + + if (!chan || !*chan) + return; + nvchan = nouveau_channel(*chan); + *chan = NULL; + nvdev = nouveau_device(nvchan->base.device); + + FIRE_RING_CH(&nvchan->base); + + nouveau_grobj_free(&nvchan->base.vram); + nouveau_grobj_free(&nvchan->base.gart); + nouveau_grobj_free(&nvchan->base.nullobj); + + FREE(nvchan->pb.buffers); + FREE(nvchan->pb.relocs); + cf.channel = nvchan->drm.channel; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf)); + FREE(nvchan); +} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c new file mode 100644 index 0000000000..2f245046d4 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include +#include "nouveau_context.h" +#include "nouveau_dri.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_winsys_pipe.h" + +static void +nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) +{ + nouveau_grobj_free(&nvc->NvCtxSurf2D); + nouveau_grobj_free(&nvc->NvImageBlit); + nouveau_grobj_free(&nvc->NvGdiRect); + nouveau_grobj_free(&nvc->NvM2MF); + nouveau_grobj_free(&nvc->Nv2D); + nouveau_grobj_free(&nvc->NvSwzSurf); + nouveau_grobj_free(&nvc->NvSIFM); + + nouveau_notifier_free(&nvc->sync_notifier); + + nouveau_channel_free(&nvc->channel); + + FREE(nvc); +} + +static struct nouveau_channel_context * +nouveau_channel_context_create(struct nouveau_device *dev) +{ + struct nouveau_channel_context *nvc; + int ret; + + nvc = CALLOC_STRUCT(nouveau_channel_context); + if (!nvc) + return NULL; + + if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002, + &nvc->channel))) { + NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + nvc->next_handle = 0x80000000; + + if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, + &nvc->sync_notifier))) { + NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + ret = nouveau_surface_channel_create_nv50(nvc); + break; + default: + ret = nouveau_surface_channel_create_nv04(nvc); + break; + } + + if (ret) { + NOUVEAU_ERR("Error initialising surface objects: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + return nvc; +} + +int +nouveau_context_init(struct nouveau_screen *nv_screen, + drm_context_t hHWContext, drmLock *sarea_lock, + struct nouveau_context *nv_share, + struct nouveau_context *nv) +{ + struct pipe_context *pipe = NULL; + struct nouveau_channel_context *nvc = NULL; + struct nouveau_device *dev = nv_screen->device; + int i; + + switch (dev->chipset & 0xf0) { + case 0x10: + case 0x20: + /* NV10 */ + case 0x30: + /* NV30 */ + case 0x40: + case 0x60: + /* NV40 */ + case 0x50: + case 0x80: + case 0x90: + /* G80 */ + break; + default: + NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset); + return 1; + } + + nv->nv_screen = nv_screen; + + { + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + nvdev->ctx = hHWContext; + nvdev->lock = sarea_lock; + } + + /*XXX: Hack up a fake region and buffer object for front buffer. + * This will go away with TTM, replaced with a simple reference + * of the front buffer handle passed to us by the DDX. + */ + { + struct pipe_surface *fb_surf; + struct nouveau_pipe_buffer *fb_buf; + struct nouveau_bo_priv *fb_bo; + + fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); + fb_bo->drm.offset = nv_screen->front_offset; + fb_bo->drm.flags = NOUVEAU_MEM_FB; + fb_bo->drm.size = nv_screen->front_pitch * + nv_screen->front_height; + fb_bo->refcount = 1; + fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; + fb_bo->base.offset = fb_bo->drm.offset; + fb_bo->base.handle = (unsigned long)fb_bo; + fb_bo->base.size = fb_bo->drm.size; + fb_bo->base.device = nv_screen->device; + + fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); + fb_buf->bo = &fb_bo->base; + + fb_surf = calloc(1, sizeof(struct pipe_surface)); + if (nv_screen->front_cpp == 2) + fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; + else + fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; + pf_get_block(fb_surf->format, &fb_surf->block); + fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; + fb_surf->height = nv_screen->front_height; + fb_surf->stride = fb_surf->width * fb_surf->block.size; + fb_surf->refcount = 1; + fb_surf->buffer = &fb_buf->base; + + nv->frontbuffer = fb_surf; + } + + /* Attempt to share a single channel between multiple contexts from + * a single process. + */ + nvc = nv_screen->nvc; + if (!nvc && nv_share) + nvc = nv_share->nvc; + + /*XXX: temporary - disable multi-context/single-channel on pre-NV4x */ + switch (dev->chipset & 0xf0) { + case 0x40: + case 0x60: + /* NV40 class */ + case 0x50: + case 0x80: + case 0x90: + /* G80 class */ + break; + default: + nvc = NULL; + break; + } + + if (!nvc) { + nvc = nouveau_channel_context_create(dev); + if (!nvc) { + NOUVEAU_ERR("Failed initialising GPU context\n"); + return 1; + } + nv_screen->nvc = nvc; + } + + nvc->refcount++; + nv->nvc = nvc; + + /* Find a free slot for a pipe context, allocate a new one if needed */ + nv->pctx_id = -1; + for (i = 0; i < nvc->nr_pctx; i++) { + if (nvc->pctx[i] == NULL) { + nv->pctx_id = i; + break; + } + } + + if (nv->pctx_id < 0) { + nv->pctx_id = nvc->nr_pctx++; + nvc->pctx = + realloc(nvc->pctx, + sizeof(struct pipe_context *) * nvc->nr_pctx); + } + + /* Create pipe */ + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + if (nouveau_surface_init_nv50(nv)) + return 1; + break; + default: + if (nouveau_surface_init_nv04(nv)) + return 1; + break; + } + + if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { + struct pipe_screen *pscreen; + + pipe = nouveau_pipe_create(nv); + if (!pipe) + NOUVEAU_ERR("Couldn't create hw pipe\n"); + pscreen = nvc->pscreen; + + nv->cap.hw_vertex_buffer = + pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF); + nv->cap.hw_index_buffer = + pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF); + } + + if (!pipe) { + NOUVEAU_MSG("Using softpipe\n"); + pipe = nouveau_create_softpipe(nv); + if (!pipe) { + NOUVEAU_ERR("Error creating pipe, bailing\n"); + return 1; + } + } + + pipe->priv = nv; + + return 0; +} + +void +nouveau_context_cleanup(struct nouveau_context *nv) +{ + struct nouveau_channel_context *nvc = nv->nvc; + + assert(nv); + + if (nv->pctx_id >= 0) { + nvc->pctx[nv->pctx_id] = NULL; + if (--nvc->refcount <= 0) { + nouveau_channel_context_destroy(nvc); + nv->nv_screen->nvc = NULL; + } + } + + /* XXX: Who cleans up the pipe? */ +} + diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h new file mode 100644 index 0000000000..b1bdb01bdf --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h @@ -0,0 +1,86 @@ +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +#include "nouveau/nouveau_winsys.h" +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +struct nouveau_channel_context { + struct pipe_screen *pscreen; + int refcount; + + unsigned cur_pctx; + unsigned nr_pctx; + struct pipe_context **pctx; + + struct nouveau_channel *channel; + + struct nouveau_notifier *sync_notifier; + + /* Common */ + struct nouveau_grobj *NvM2MF; + /* NV04-NV40 */ + struct nouveau_grobj *NvCtxSurf2D; + struct nouveau_grobj *NvSwzSurf; + struct nouveau_grobj *NvImageBlit; + struct nouveau_grobj *NvGdiRect; + struct nouveau_grobj *NvSIFM; + /* G80 */ + struct nouveau_grobj *Nv2D; + + uint32_t next_handle; + uint32_t next_subchannel; + uint32_t next_sequence; +}; + +struct nouveau_context { + int locked; + struct nouveau_screen *nv_screen; + struct pipe_surface *frontbuffer; + + struct { + int hw_vertex_buffer; + int hw_index_buffer; + } cap; + + /* Hardware context */ + struct nouveau_channel_context *nvc; + int pctx_id; + + /* pipe_surface accel */ + struct pipe_surface *surf_src, *surf_dst; + unsigned surf_src_offset, surf_dst_offset; + int (*surface_copy_prep)(struct nouveau_context *, + struct pipe_surface *dst, + struct pipe_surface *src); + void (*surface_copy)(struct nouveau_context *, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h); + void (*surface_copy_done)(struct nouveau_context *); + int (*surface_fill)(struct nouveau_context *, struct pipe_surface *, + unsigned, unsigned, unsigned, unsigned, unsigned); +}; + +extern int nouveau_context_init(struct nouveau_screen *nv_screen, + drm_context_t hHWContext, drmLock *sarea_lock, + struct nouveau_context *nv_share, + struct nouveau_context *nv); +extern void nouveau_context_cleanup(struct nouveau_context *nv); + +extern void LOCK_HARDWARE(struct nouveau_context *); +extern void UNLOCK_HARDWARE(struct nouveau_context *); + +extern int +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *); +extern int +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *); +extern int nouveau_surface_init_nv04(struct nouveau_context *); +extern int nouveau_surface_init_nv50(struct nouveau_context *); + +extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int); +extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *); + +/* Must be provided by clients of common code */ +extern void +nouveau_contended_lock(struct nouveau_context *nv); + +#endif diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_device.c b/src/gallium/winsys/drm/nouveau/common/nouveau_device.c new file mode 100644 index 0000000000..92b57b834b --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_device.c @@ -0,0 +1,159 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include +#include +#include "nouveau_drmif.h" + +int +nouveau_device_open_existing(struct nouveau_device **dev, int close, + int fd, drm_context_t ctx) +{ + struct nouveau_device_priv *nvdev; + int ret; + + if (!dev || *dev) + return -EINVAL; + + nvdev = CALLOC_STRUCT(nouveau_device_priv); + if (!nvdev) + return -ENOMEM; + nvdev->fd = fd; + nvdev->ctx = ctx; + nvdev->needs_close = close; + + drmCommandNone(nvdev->fd, DRM_NOUVEAU_CARD_INIT); + + if ((ret = nouveau_bo_init(&nvdev->base))) { + nouveau_device_close((void *)&nvdev); + return ret; + } + + { + uint64_t value; + + ret = nouveau_device_get_param(&nvdev->base, + NOUVEAU_GETPARAM_CHIPSET_ID, + &value); + if (ret) { + nouveau_device_close((void *)&nvdev); + return ret; + } + nvdev->base.chipset = value; + } + + *dev = &nvdev->base; + return 0; +} + +int +nouveau_device_open(struct nouveau_device **dev, const char *busid) +{ + drm_context_t ctx; + int fd, ret; + + if (!dev || *dev) + return -EINVAL; + + fd = drmOpen("nouveau", busid); + if (fd < 0) + return -EINVAL; + + ret = drmCreateContext(fd, &ctx); + if (ret) { + drmClose(fd); + return ret; + } + + ret = nouveau_device_open_existing(dev, 1, fd, ctx); + if (ret) { + drmDestroyContext(fd, ctx); + drmClose(fd); + return ret; + } + + return 0; +} + +void +nouveau_device_close(struct nouveau_device **dev) +{ + struct nouveau_device_priv *nvdev; + + if (dev || !*dev) + return; + nvdev = nouveau_device(*dev); + *dev = NULL; + + nouveau_bo_takedown(&nvdev->base); + + if (nvdev->needs_close) { + drmDestroyContext(nvdev->fd, nvdev->ctx); + drmClose(nvdev->fd); + } + FREE(nvdev); +} + +int +nouveau_device_get_param(struct nouveau_device *dev, + uint64_t param, uint64_t *value) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct drm_nouveau_getparam g; + int ret; + + if (!nvdev || !value) + return -EINVAL; + + g.param = param; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GETPARAM, + &g, sizeof(g)); + if (ret) + return ret; + + *value = g.value; + return 0; +} + +int +nouveau_device_set_param(struct nouveau_device *dev, + uint64_t param, uint64_t value) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct drm_nouveau_setparam s; + int ret; + + if (!nvdev) + return -EINVAL; + + s.param = param; + s.value = value; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_SETPARAM, + &s, sizeof(s)); + if (ret) + return ret; + + return 0; +} + diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_dma.c b/src/gallium/winsys/drm/nouveau/common/nouveau_dma.c new file mode 100644 index 0000000000..f8a8ba04f6 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_dma.c @@ -0,0 +1,219 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" +#include "nouveau_local.h" + +static inline uint32_t +READ_GET(struct nouveau_channel_priv *nvchan) +{ + return *nvchan->get; +} + +static inline void +WRITE_PUT(struct nouveau_channel_priv *nvchan, uint32_t val) +{ + uint32_t put = ((val << 2) + nvchan->dma->base); + volatile int dum; + + NOUVEAU_DMA_BARRIER; + dum = READ_GET(nvchan); + + *nvchan->put = put; + nvchan->dma->put = val; +#ifdef NOUVEAU_DMA_TRACE + NOUVEAU_MSG("WRITE_PUT %d/0x%08x\n", nvchan->drm.channel, put); +#endif + + NOUVEAU_DMA_BARRIER; +} + +static inline int +LOCAL_GET(struct nouveau_dma_priv *dma, uint32_t *val) +{ + uint32_t get = *val; + + if (get >= dma->base && get <= (dma->base + (dma->max << 2))) { + *val = (get - dma->base) >> 2; + return 1; + } + + return 0; +} + +void +nouveau_dma_channel_init(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + int i; + + nvchan->dma = &nvchan->dma_master; + nvchan->dma->base = nvchan->drm.put_base; + nvchan->dma->cur = nvchan->dma->put = 0; + nvchan->dma->max = (nvchan->drm.cmdbuf_size >> 2) - 2; + nvchan->dma->free = nvchan->dma->max - nvchan->dma->cur; + + RING_SPACE_CH(chan, RING_SKIPS); + for (i = 0; i < RING_SKIPS; i++) + OUT_RING_CH(chan, 0); +} + +#define CHECK_TIMEOUT() do { \ + if ((NOUVEAU_TIME_MSEC() - t_start) > NOUVEAU_DMA_TIMEOUT) \ + return - EBUSY; \ +} while(0) + +int +nouveau_dma_wait(struct nouveau_channel *chan, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + uint32_t get, t_start; + + FIRE_RING_CH(chan); + + t_start = NOUVEAU_TIME_MSEC(); + while (dma->free < size) { + CHECK_TIMEOUT(); + + get = READ_GET(nvchan); + if (!LOCAL_GET(dma, &get)) + continue; + + if (dma->put >= get) { + dma->free = dma->max - dma->cur; + + if (dma->free < size) { +#ifdef NOUVEAU_DMA_DEBUG + dma->push_free = 1; +#endif + OUT_RING_CH(chan, 0x20000000 | dma->base); + if (get <= RING_SKIPS) { + /*corner case - will be idle*/ + if (dma->put <= RING_SKIPS) + WRITE_PUT(nvchan, + RING_SKIPS + 1); + + do { + CHECK_TIMEOUT(); + get = READ_GET(nvchan); + if (!LOCAL_GET(dma, &get)) + get = 0; + } while (get <= RING_SKIPS); + } + + WRITE_PUT(nvchan, RING_SKIPS); + dma->cur = dma->put = RING_SKIPS; + dma->free = get - (RING_SKIPS + 1); + } + } else { + dma->free = get - dma->cur - 1; + } + } + + return 0; +} + +#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF +static void +nouveau_dma_parse_pushbuf(struct nouveau_channel *chan, int get, int put) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + unsigned mthd_count = 0; + + while (get != put) { + uint32_t gpuget = (get << 2) + nvchan->drm.put_base; + uint32_t data; + + if (get < 0 || get >= nvchan->drm.cmdbuf_size) { + NOUVEAU_ERR("DMA_PT 0x%08x\n", gpuget); + assert(0); + } + data = nvchan->pushbuf[get++]; + + if (mthd_count) { + NOUVEAU_MSG("0x%08x 0x%08x\n", gpuget, data); + mthd_count--; + continue; + } + + switch (data & 0x60000000) { + case 0x00000000: + mthd_count = (data >> 18) & 0x7ff; + NOUVEAU_MSG("0x%08x 0x%08x MTHD " + "Sc %d Mthd 0x%04x Size %d\n", + gpuget, data, (data>>13) & 7, data & 0x1ffc, + mthd_count); + break; + case 0x20000000: + get = (data & 0x1ffffffc) >> 2; + NOUVEAU_MSG("0x%08x 0x%08x JUMP 0x%08x\n", + gpuget, data, data & 0x1ffffffc); + continue; + case 0x40000000: + mthd_count = (data >> 18) & 0x7ff; + NOUVEAU_MSG("0x%08x 0x%08x NINC " + "Sc %d Mthd 0x%04x Size %d\n", + gpuget, data, (data>>13) & 7, data & 0x1ffc, + mthd_count); + break; + case 0x60000000: + /* DMA_OPCODE_CALL apparently, doesn't seem to work on + * my NV40 at least.. + */ + /* fall-through */ + default: + NOUVEAU_MSG("DMA_PUSHER 0x%08x 0x%08x\n", + gpuget, data); + assert(0); + } + } +} +#endif + +void +nouveau_dma_kickoff(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + + if (dma->cur == dma->put) + return; + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free) { + NOUVEAU_ERR("Packet incomplete: %d left\n", dma->push_free); + return; + } +#endif + +#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF + nouveau_dma_parse_pushbuf(chan, dma->put, dma->cur); +#endif + + WRITE_PUT(nvchan, dma->cur); +} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_dma.h b/src/gallium/winsys/drm/nouveau/common/nouveau_dma.h new file mode 100644 index 0000000000..cfa6d26e82 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_dma.h @@ -0,0 +1,143 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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. + */ + +#ifndef __NOUVEAU_DMA_H__ +#define __NOUVEAU_DMA_H__ + +#include +#include "nouveau_drmif.h" +#include "nouveau_local.h" + +#define RING_SKIPS 8 + +extern int nouveau_dma_wait(struct nouveau_channel *chan, int size); +extern void nouveau_dma_subc_bind(struct nouveau_grobj *); +extern void nouveau_dma_channel_init(struct nouveau_channel *); +extern void nouveau_dma_kickoff(struct nouveau_channel *); + +#ifdef NOUVEAU_DMA_DEBUG +static char faulty[1024]; +#endif + +static inline void +nouveau_dma_out(struct nouveau_channel *chan, uint32_t data) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free == 0) { + NOUVEAU_ERR("No space left in packet at %s\n", faulty); + return; + } + dma->push_free--; +#endif +#ifdef NOUVEAU_DMA_TRACE + { + uint32_t offset = (dma->cur << 2) + dma->base; + NOUVEAU_MSG("\tOUT_RING %d/0x%08x -> 0x%08x\n", + nvchan->drm.channel, offset, data); + } +#endif + nvchan->pushbuf[dma->cur + (dma->base - nvchan->drm.put_base)/4] = data; + dma->cur++; +} + +static inline void +nouveau_dma_outp(struct nouveau_channel *chan, uint32_t *ptr, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + (void)dma; + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free < size) { + NOUVEAU_ERR("Packet too small. Free=%d, Need=%d\n", + dma->push_free, size); + return; + } +#endif +#ifdef NOUVEAU_DMA_TRACE + while (size--) { + nouveau_dma_out(chan, *ptr); + ptr++; + } +#else + memcpy(&nvchan->pushbuf[dma->cur], ptr, size << 2); +#ifdef NOUVEAU_DMA_DEBUG + dma->push_free -= size; +#endif + dma->cur += size; +#endif +} + +static inline void +nouveau_dma_space(struct nouveau_channel *chan, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + + if (dma->free < size) { + if (nouveau_dma_wait(chan, size) && chan->hang_notify) + chan->hang_notify(chan); + } + dma->free -= size; +#ifdef NOUVEAU_DMA_DEBUG + dma->push_free = size; +#endif +} + +static inline void +nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj, + int method, int size, const char* file, int line) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + (void)dma; + +#ifdef NOUVEAU_DMA_TRACE + NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", nvchan->drm.channel, + grobj->handle, grobj->subc, method, size); +#endif + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free) { + NOUVEAU_ERR("Previous packet incomplete: %d left at %s\n", + dma->push_free, faulty); + return; + } + sprintf(faulty,"%s:%d",file,line); +#endif + + nouveau_dma_space(chan, (size + 1)); + nouveau_dma_out(chan, (size << 18) | (grobj->subc << 13) | method); +} + +#define RING_SPACE_CH(ch,sz) nouveau_dma_space((ch), (sz)) +#define BEGIN_RING_CH(ch,gr,m,sz) nouveau_dma_begin((ch), (gr), (m), (sz), __FUNCTION__, __LINE__ ) +#define OUT_RING_CH(ch, data) nouveau_dma_out((ch), (data)) +#define OUT_RINGp_CH(ch,ptr,dwords) nouveau_dma_outp((ch), (void*)(ptr), \ + (dwords)) +#define FIRE_RING_CH(ch) nouveau_dma_kickoff((ch)) +#define WAIT_RING_CH(ch,sz) nouveau_dma_wait((ch), (sz)) + +#endif diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/common/nouveau_dri.h new file mode 100644 index 0000000000..1207c2d609 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_dri.h @@ -0,0 +1,28 @@ +#ifndef _NOUVEAU_DRI_ +#define _NOUVEAU_DRI_ + +#include "xf86drm.h" +#include "drm.h" +#include "nouveau_drm.h" + +struct nouveau_dri { + uint32_t device_id; /**< \brief PCI device ID */ + uint32_t width; /**< \brief width in pixels of display */ + uint32_t height; /**< \brief height in scanlines of display */ + uint32_t depth; /**< \brief depth of display (8, 15, 16, 24) */ + uint32_t bpp; /**< \brief bit depth of display (8, 16, 24, 32) */ + + uint32_t bus_type; /**< \brief ths bus type */ + uint32_t bus_mode; /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */ + + uint32_t front_offset; /**< \brief front buffer offset */ + uint32_t front_pitch; /**< \brief front buffer pitch */ + uint32_t back_offset; /**< \brief private back buffer offset */ + uint32_t back_pitch; /**< \brief private back buffer pitch */ + uint32_t depth_offset; /**< \brief private depth buffer offset */ + uint32_t depth_pitch; /**< \brief private depth buffer pitch */ + +}; + +#endif + diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h b/src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h new file mode 100644 index 0000000000..5f72800676 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h @@ -0,0 +1,313 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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. + */ + +#ifndef __NOUVEAU_DRMIF_H__ +#define __NOUVEAU_DRMIF_H__ + +#include +#include +#include + +#include "nouveau/nouveau_device.h" +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_grobj.h" +#include "nouveau/nouveau_notifier.h" +#include "nouveau/nouveau_bo.h" +#include "nouveau/nouveau_resource.h" +#include "nouveau/nouveau_pushbuf.h" + +struct nouveau_device_priv { + struct nouveau_device base; + + int fd; + drm_context_t ctx; + drmLock *lock; + int needs_close; + + struct drm_nouveau_mem_alloc sa; + void *sa_map; + struct nouveau_resource *sa_heap; +}; +#define nouveau_device(n) ((struct nouveau_device_priv *)(n)) + +extern int +nouveau_device_open_existing(struct nouveau_device **, int close, + int fd, drm_context_t ctx); + +extern int +nouveau_device_open(struct nouveau_device **, const char *busid); + +extern void +nouveau_device_close(struct nouveau_device **); + +extern int +nouveau_device_get_param(struct nouveau_device *, uint64_t param, uint64_t *v); + +extern int +nouveau_device_set_param(struct nouveau_device *, uint64_t param, uint64_t val); + +struct nouveau_fence { + struct nouveau_channel *channel; +}; + +struct nouveau_fence_cb { + struct nouveau_fence_cb *next; + void (*func)(void *); + void *priv; +}; + +struct nouveau_fence_priv { + struct nouveau_fence base; + int refcount; + + struct nouveau_fence *next; + struct nouveau_fence_cb *signal_cb; + + uint32_t sequence; + int emitted; + int signalled; +}; +#define nouveau_fence(n) ((struct nouveau_fence_priv *)(n)) + +extern int +nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **); + +extern int +nouveau_fence_ref(struct nouveau_fence *, struct nouveau_fence **); + +extern int +nouveau_fence_signal_cb(struct nouveau_fence *, void (*)(void *), void *); + +extern void +nouveau_fence_emit(struct nouveau_fence *); + +extern int +nouveau_fence_wait(struct nouveau_fence **); + +extern void +nouveau_fence_flush(struct nouveau_channel *); + +struct nouveau_pushbuf_reloc { + struct nouveau_pushbuf_bo *pbbo; + uint32_t *ptr; + uint32_t flags; + uint32_t data; + uint32_t vor; + uint32_t tor; +}; + +struct nouveau_pushbuf_bo { + struct nouveau_channel *channel; + struct nouveau_bo *bo; + unsigned flags; + unsigned handled; +}; + +#define NOUVEAU_PUSHBUF_MAX_BUFFERS 1024 +#define NOUVEAU_PUSHBUF_MAX_RELOCS 1024 +struct nouveau_pushbuf_priv { + struct nouveau_pushbuf base; + + struct nouveau_fence *fence; + + unsigned nop_jump; + unsigned start; + unsigned size; + + struct nouveau_pushbuf_bo *buffers; + unsigned nr_buffers; + struct nouveau_pushbuf_reloc *relocs; + unsigned nr_relocs; +}; +#define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n)) + +#define pbbo_to_ptr(o) ((uint64_t)(unsigned long)(o)) +#define ptr_to_pbbo(h) ((struct nouveau_pushbuf_bo *)(unsigned long)(h)) +#define pbrel_to_ptr(o) ((uint64_t)(unsigned long)(o)) +#define ptr_to_pbrel(h) ((struct nouveau_pushbuf_reloc *)(unsigned long)(h)) +#define bo_to_ptr(o) ((uint64_t)(unsigned long)(o)) +#define ptr_to_bo(h) ((struct nouveau_bo_priv *)(unsigned long)(h)) + +extern int +nouveau_pushbuf_init(struct nouveau_channel *); + +extern int +nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); + +extern int +nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr, + struct nouveau_bo *, uint32_t data, uint32_t flags, + uint32_t vor, uint32_t tor); + +struct nouveau_dma_priv { + uint32_t base; + uint32_t max; + uint32_t cur; + uint32_t put; + uint32_t free; + + int push_free; +} dma; + +struct nouveau_channel_priv { + struct nouveau_channel base; + + struct drm_nouveau_channel_alloc drm; + + uint32_t *pushbuf; + void *notifier_block; + + volatile uint32_t *user; + volatile uint32_t *put; + volatile uint32_t *get; + volatile uint32_t *ref_cnt; + + struct nouveau_dma_priv dma_master; + struct nouveau_dma_priv dma_bufmgr; + struct nouveau_dma_priv *dma; + + struct nouveau_fence *fence_head; + struct nouveau_fence *fence_tail; + uint32_t fence_sequence; + + struct nouveau_pushbuf_priv pb; + + unsigned user_charge; +}; +#define nouveau_channel(n) ((struct nouveau_channel_priv *)(n)) + +extern int +nouveau_channel_alloc(struct nouveau_device *, uint32_t fb, uint32_t tt, + struct nouveau_channel **); + +extern void +nouveau_channel_free(struct nouveau_channel **); + +struct nouveau_grobj_priv { + struct nouveau_grobj base; +}; +#define nouveau_grobj(n) ((struct nouveau_grobj_priv *)(n)) + +extern int nouveau_grobj_alloc(struct nouveau_channel *, uint32_t handle, + int class, struct nouveau_grobj **); +extern int nouveau_grobj_ref(struct nouveau_channel *, uint32_t handle, + struct nouveau_grobj **); +extern void nouveau_grobj_free(struct nouveau_grobj **); + + +struct nouveau_notifier_priv { + struct nouveau_notifier base; + + struct drm_nouveau_notifierobj_alloc drm; + volatile void *map; +}; +#define nouveau_notifier(n) ((struct nouveau_notifier_priv *)(n)) + +extern int +nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, int count, + struct nouveau_notifier **); + +extern void +nouveau_notifier_free(struct nouveau_notifier **); + +extern void +nouveau_notifier_reset(struct nouveau_notifier *, int id); + +extern uint32_t +nouveau_notifier_status(struct nouveau_notifier *, int id); + +extern uint32_t +nouveau_notifier_return_val(struct nouveau_notifier *, int id); + +extern int +nouveau_notifier_wait_status(struct nouveau_notifier *, int id, int status, + int timeout); + +struct nouveau_bo_priv { + struct nouveau_bo base; + + struct nouveau_pushbuf_bo *pending; + struct nouveau_fence *fence; + struct nouveau_fence *wr_fence; + + struct drm_nouveau_mem_alloc drm; + void *map; + + void *sysmem; + int user; + + int refcount; + + uint64_t offset; + uint64_t flags; + int tiled; +}; +#define nouveau_bo(n) ((struct nouveau_bo_priv *)(n)) + +extern int +nouveau_bo_init(struct nouveau_device *); + +extern void +nouveau_bo_takedown(struct nouveau_device *); + +extern int +nouveau_bo_new(struct nouveau_device *, uint32_t flags, int align, int size, + struct nouveau_bo **); + +extern int +nouveau_bo_user(struct nouveau_device *, void *ptr, int size, + struct nouveau_bo **); + +extern int +nouveau_bo_ref(struct nouveau_device *, uint64_t handle, struct nouveau_bo **); + +extern int +nouveau_bo_set_status(struct nouveau_bo *, uint32_t flags); + +extern void +nouveau_bo_del(struct nouveau_bo **); + +extern int +nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags); + +extern int +nouveau_bo_map(struct nouveau_bo *, uint32_t flags); + +extern void +nouveau_bo_unmap(struct nouveau_bo *); + +extern int +nouveau_bo_validate(struct nouveau_channel *, struct nouveau_bo *, + uint32_t flags); + +extern int +nouveau_resource_init(struct nouveau_resource **heap, unsigned start, + unsigned size); + +extern int +nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, + struct nouveau_resource **); + +extern void +nouveau_resource_free(struct nouveau_resource **); + +#endif diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c b/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c new file mode 100644 index 0000000000..e7b0b4ff07 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c @@ -0,0 +1,214 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" +#include "nouveau_local.h" + +static void +nouveau_fence_del_unsignalled(struct nouveau_fence *fence) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); + struct nouveau_fence *le; + + if (nvchan->fence_head == fence) { + nvchan->fence_head = nouveau_fence(fence)->next; + if (nvchan->fence_head == NULL) + nvchan->fence_tail = NULL; + return; + } + + le = nvchan->fence_head; + while (le && nouveau_fence(le)->next != fence) + le = nouveau_fence(le)->next; + assert(le && nouveau_fence(le)->next == fence); + nouveau_fence(le)->next = nouveau_fence(fence)->next; + if (nvchan->fence_tail == fence) + nvchan->fence_tail = le; +} + +static void +nouveau_fence_del(struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!fence || !*fence) + return; + nvfence = nouveau_fence(*fence); + *fence = NULL; + + if (--nvfence->refcount) + return; + + if (nvfence->emitted && !nvfence->signalled) { + if (nvfence->signal_cb) { + nvfence->refcount++; + nouveau_fence_wait((void *)&nvfence); + return; + } + + nouveau_fence_del_unsignalled(&nvfence->base); + } + free(nvfence); +} + +int +nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!chan || !fence || *fence) + return -EINVAL; + + nvfence = calloc(1, sizeof(struct nouveau_fence_priv)); + if (!nvfence) + return -ENOMEM; + nvfence->base.channel = chan; + nvfence->refcount = 1; + + *fence = &nvfence->base; + return 0; +} + +int +nouveau_fence_ref(struct nouveau_fence *ref, struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!fence) + return -EINVAL; + + if (*fence) { + nouveau_fence_del(fence); + *fence = NULL; + } + + if (ref) { + nvfence = nouveau_fence(ref); + nvfence->refcount++; + *fence = &nvfence->base; + } + + return 0; +} + +int +nouveau_fence_signal_cb(struct nouveau_fence *fence, void (*func)(void *), + void *priv) +{ + struct nouveau_fence_priv *nvfence = nouveau_fence(fence); + struct nouveau_fence_cb *cb; + + if (!nvfence || !func) + return -EINVAL; + + cb = malloc(sizeof(struct nouveau_fence_cb)); + if (!cb) + return -ENOMEM; + + cb->func = func; + cb->priv = priv; + cb->next = nvfence->signal_cb; + nvfence->signal_cb = cb; + return 0; +} + +void +nouveau_fence_emit(struct nouveau_fence *fence) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); + struct nouveau_fence_priv *nvfence = nouveau_fence(fence); + + nvfence->emitted = 1; + nvfence->sequence = ++nvchan->fence_sequence; + if (nvfence->sequence == 0xffffffff) + NOUVEAU_ERR("AII wrap unhandled\n"); + + /*XXX: assumes subc 0 is populated */ + RING_SPACE_CH(fence->channel, 2); + OUT_RING_CH (fence->channel, 0x00040050); + OUT_RING_CH (fence->channel, nvfence->sequence); + + if (nvchan->fence_tail) { + nouveau_fence(nvchan->fence_tail)->next = fence; + } else { + nvchan->fence_head = fence; + } + nvchan->fence_tail = fence; +} + +void +nouveau_fence_flush(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + uint32_t sequence = *nvchan->ref_cnt; + + while (nvchan->fence_head) { + struct nouveau_fence_priv *nvfence; + + nvfence = nouveau_fence(nvchan->fence_head); + if (nvfence->sequence > sequence) + break; + nouveau_fence_del_unsignalled(&nvfence->base); + nvfence->signalled = 1; + + if (nvfence->signal_cb) { + struct nouveau_fence *fence = NULL; + + nouveau_fence_ref(&nvfence->base, &fence); + + while (nvfence->signal_cb) { + struct nouveau_fence_cb *cb; + + cb = nvfence->signal_cb; + nvfence->signal_cb = cb->next; + cb->func(cb->priv); + free(cb); + } + + nouveau_fence_ref(NULL, &fence); + } + } +} + +int +nouveau_fence_wait(struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!fence || !*fence) + return -EINVAL; + nvfence = nouveau_fence(*fence); + + if (nvfence->emitted) { + while (!nvfence->signalled) + nouveau_fence_flush(nvfence->base.channel); + } + nouveau_fence_ref(NULL, fence); + + return 0; +} + diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c b/src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c new file mode 100644 index 0000000000..fb430a25b8 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c @@ -0,0 +1,107 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include +#include "nouveau_drmif.h" + +int +nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle, + int class, struct nouveau_grobj **grobj) +{ + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_grobj_priv *nvgrobj; + struct drm_nouveau_grobj_alloc g; + int ret; + + if (!nvdev || !grobj || *grobj) + return -EINVAL; + + nvgrobj = CALLOC_STRUCT(nouveau_grobj_priv); + if (!nvgrobj) + return -ENOMEM; + nvgrobj->base.channel = chan; + nvgrobj->base.handle = handle; + nvgrobj->base.grclass = class; + + g.channel = chan->id; + g.handle = handle; + g.class = class; + ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GROBJ_ALLOC, + &g, sizeof(g)); + if (ret) { + nouveau_grobj_free((void *)&nvgrobj); + return ret; + } + + *grobj = &nvgrobj->base; + return 0; +} + +int +nouveau_grobj_ref(struct nouveau_channel *chan, uint32_t handle, + struct nouveau_grobj **grobj) +{ + struct nouveau_grobj_priv *nvgrobj; + + if (!chan || !grobj || *grobj) + return -EINVAL; + + nvgrobj = CALLOC_STRUCT(nouveau_grobj_priv); + if (!nvgrobj) + return -ENOMEM; + nvgrobj->base.channel = chan; + nvgrobj->base.handle = handle; + nvgrobj->base.grclass = 0; + + *grobj = &nvgrobj->base; + return 0; +} + +void +nouveau_grobj_free(struct nouveau_grobj **grobj) +{ + struct nouveau_device_priv *nvdev; + struct nouveau_channel_priv *chan; + struct nouveau_grobj_priv *nvgrobj; + + if (!grobj || !*grobj) + return; + nvgrobj = nouveau_grobj(*grobj); + *grobj = NULL; + + + chan = nouveau_channel(nvgrobj->base.channel); + nvdev = nouveau_device(chan->base.device); + + if (nvgrobj->base.grclass) { + struct drm_nouveau_gpuobj_free f; + + f.channel = chan->drm.channel; + f.handle = nvgrobj->base.handle; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, + &f, sizeof(f)); + } + FREE(nvgrobj); +} + diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_local.h b/src/gallium/winsys/drm/nouveau/common/nouveau_local.h new file mode 100644 index 0000000000..877c7a8c47 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_local.h @@ -0,0 +1,115 @@ +#ifndef __NOUVEAU_LOCAL_H__ +#define __NOUVEAU_LOCAL_H__ + +#include "pipe/p_compiler.h" +#include "nouveau_winsys_pipe.h" +#include + +/* Debug output */ +#define NOUVEAU_MSG(fmt, args...) do { \ + fprintf(stdout, "nouveau: "fmt, ##args); \ + fflush(stdout); \ +} while(0) + +#define NOUVEAU_ERR(fmt, args...) do { \ + fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); \ + fflush(stderr); \ +} while(0) + +#define NOUVEAU_TIME_MSEC() 0 + +/* User FIFO control */ +//#define NOUVEAU_DMA_TRACE +//#define NOUVEAU_DMA_DEBUG +//#define NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF +#define NOUVEAU_DMA_BARRIER +#define NOUVEAU_DMA_TIMEOUT 2000 + +/* Push buffer access macros */ +static INLINE void +OUT_RING(struct nouveau_channel *chan, unsigned data) +{ + *(chan->pushbuf->cur++) = (data); +} + +static INLINE void +OUT_RINGp(struct nouveau_channel *chan, uint32_t *data, unsigned size) +{ + memcpy(chan->pushbuf->cur, data, size * 4); + chan->pushbuf->cur += size; +} + +static INLINE void +OUT_RINGf(struct nouveau_channel *chan, float f) +{ + union { uint32_t i; float f; } c; + c.f = f; + OUT_RING(chan, c.i); +} + +static INLINE void +BEGIN_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, + unsigned mthd, unsigned size) +{ + if (chan->pushbuf->remaining < (size + 1)) + nouveau_pushbuf_flush(chan, (size + 1)); + OUT_RING(chan, (gr->subc << 13) | (size << 18) | mthd); + chan->pushbuf->remaining -= (size + 1); +} + +static INLINE void +FIRE_RING(struct nouveau_channel *chan) +{ + nouveau_pushbuf_flush(chan, 0); +} + +static INLINE void +BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc) +{ + gr->subc = subc; + BEGIN_RING(chan, gr, 0x0000, 1); + OUT_RING (chan, gr->handle); +} + +static INLINE void +OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, + data, flags, vor, tor); +} + +/* Raw data + flags depending on FB/TT buffer */ +static INLINE void +OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor); +} + +/* FB/TT object handle */ +static INLINE void +OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned flags) +{ + OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR, + chan->vram->handle, chan->gart->handle); +} + +/* Low 32-bits of offset */ +static INLINE void +OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned delta, unsigned flags) +{ + OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0); +} + +/* High 32-bits of offset */ +static INLINE void +OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned delta, unsigned flags) +{ + OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); +} + +#endif diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_lock.c b/src/gallium/winsys/drm/nouveau/common/nouveau_lock.c new file mode 100644 index 0000000000..e8cf051ed9 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_lock.c @@ -0,0 +1,72 @@ +/************************************************************************** + * + * 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 +#include "nouveau_context.h" +#include "nouveau_screen.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->nv_screen; + 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->nv_screen; + 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/common/nouveau_notifier.c b/src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c new file mode 100644 index 0000000000..01e8f38440 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c @@ -0,0 +1,137 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include + +#include "nouveau_drmif.h" +#include "nouveau_local.h" + +#define NOTIFIER(__v) \ + struct nouveau_notifier_priv *nvnotify = nouveau_notifier(notifier); \ + volatile uint32_t *__v = (void*)nvnotify->map + (id * 32) + +int +nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, + int count, struct nouveau_notifier **notifier) +{ + struct nouveau_notifier_priv *nvnotify; + int ret; + + if (!chan || !notifier || *notifier) + return -EINVAL; + + nvnotify = calloc(1, sizeof(struct nouveau_notifier_priv)); + if (!nvnotify) + return -ENOMEM; + nvnotify->base.channel = chan; + nvnotify->base.handle = handle; + + nvnotify->drm.channel = chan->id; + nvnotify->drm.handle = handle; + nvnotify->drm.count = count; + if ((ret = drmCommandWriteRead(nouveau_device(chan->device)->fd, + DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, + &nvnotify->drm, + sizeof(nvnotify->drm)))) { + nouveau_notifier_free((void *)&nvnotify); + return ret; + } + + nvnotify->map = (void *)nouveau_channel(chan)->notifier_block + + nvnotify->drm.offset; + *notifier = &nvnotify->base; + return 0; +} + +void +nouveau_notifier_free(struct nouveau_notifier **notifier) +{ + + struct nouveau_notifier_priv *nvnotify; + struct nouveau_channel_priv *nvchan; + struct nouveau_device_priv *nvdev; + struct drm_nouveau_gpuobj_free f; + + if (!notifier || !*notifier) + return; + nvnotify = nouveau_notifier(*notifier); + *notifier = NULL; + + nvchan = nouveau_channel(nvnotify->base.channel); + nvdev = nouveau_device(nvchan->base.device); + + f.channel = nvchan->drm.channel; + f.handle = nvnotify->base.handle; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, &f, sizeof(f)); + free(nvnotify); +} + +void +nouveau_notifier_reset(struct nouveau_notifier *notifier, int id) +{ + NOTIFIER(n); + + n[NV_NOTIFY_TIME_0 /4] = 0x00000000; + n[NV_NOTIFY_TIME_1 /4] = 0x00000000; + n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000; + n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS << + NV_NOTIFY_STATE_STATUS_SHIFT); +} + +uint32_t +nouveau_notifier_status(struct nouveau_notifier *notifier, int id) +{ + NOTIFIER(n); + + return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; +} + +uint32_t +nouveau_notifier_return_val(struct nouveau_notifier *notifier, int id) +{ + NOTIFIER(n); + + return n[NV_NOTIFY_RETURN_VALUE/4]; +} + +int +nouveau_notifier_wait_status(struct nouveau_notifier *notifier, int id, + int status, int timeout) +{ + NOTIFIER(n); + uint32_t time = 0, t_start = NOUVEAU_TIME_MSEC(); + + while (time <= timeout) { + uint32_t v; + + v = n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; + if (v == status) + return 0; + + if (timeout) + time = NOUVEAU_TIME_MSEC() - t_start; + } + + return -EBUSY; +} + diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c b/src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c new file mode 100644 index 0000000000..7c094eb795 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c @@ -0,0 +1,270 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include +#include +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +#define PB_BUFMGR_DWORDS (4096 / 2) +#define PB_MIN_USER_DWORDS 2048 + +static int +nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; + + assert((min + 1) <= nvchan->dma->max); + + /* Wait for enough space in push buffer */ + min = min < PB_MIN_USER_DWORDS ? PB_MIN_USER_DWORDS : min; + min += 1; /* a bit extra for the NOP */ + if (nvchan->dma->free < min) + WAIT_RING_CH(chan, min); + + /* Insert NOP, may turn into a jump later */ + RING_SPACE_CH(chan, 1); + nvpb->nop_jump = nvchan->dma->cur; + OUT_RING_CH(chan, 0); + + /* Any remaining space is available to the user */ + nvpb->start = nvchan->dma->cur; + nvpb->size = nvchan->dma->free; + nvpb->base.channel = chan; + nvpb->base.remaining = nvpb->size; + nvpb->base.cur = &nvchan->pushbuf[nvpb->start]; + + /* Create a new fence object for this "frame" */ + nouveau_fence_ref(NULL, &nvpb->fence); + nouveau_fence_new(chan, &nvpb->fence); + + return 0; +} + +int +nouveau_pushbuf_init(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *m = &nvchan->dma_master; + struct nouveau_dma_priv *b = &nvchan->dma_bufmgr; + int i; + + if (!nvchan) + return -EINVAL; + + /* Reassign last bit of push buffer for a "separate" bufmgr + * ring buffer + */ + m->max -= PB_BUFMGR_DWORDS; + m->free -= PB_BUFMGR_DWORDS; + + b->base = m->base + ((m->max + 2) << 2); + b->max = PB_BUFMGR_DWORDS - 2; + b->cur = b->put = 0; + b->free = b->max - b->cur; + + /* Some NOPs just to be safe + *XXX: RING_SKIPS + */ + nvchan->dma = b; + RING_SPACE_CH(chan, 8); + for (i = 0; i < 8; i++) + OUT_RING_CH(chan, 0); + nvchan->dma = m; + + nouveau_pushbuf_space(chan, 0); + chan->pushbuf = &nvchan->pb.base; + + nvchan->pb.buffers = CALLOC(NOUVEAU_PUSHBUF_MAX_BUFFERS, + sizeof(struct nouveau_pushbuf_bo)); + nvchan->pb.relocs = CALLOC(NOUVEAU_PUSHBUF_MAX_RELOCS, + sizeof(struct nouveau_pushbuf_reloc)); + return 0; +} + +static uint32_t +nouveau_pushbuf_calc_reloc(struct nouveau_bo *bo, + struct nouveau_pushbuf_reloc *r) +{ + uint32_t push; + + if (r->flags & NOUVEAU_BO_LOW) { + push = bo->offset + r->data; + } else + if (r->flags & NOUVEAU_BO_HIGH) { + push = (bo->offset + r->data) >> 32; + } else { + push = r->data; + } + + if (r->flags & NOUVEAU_BO_OR) { + if (bo->flags & NOUVEAU_BO_VRAM) + push |= r->vor; + else + push |= r->tor; + } + + return push; +} + +/* This would be our TTM "superioctl" */ +int +nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; + int ret, i; + + if (nvpb->base.remaining == nvpb->size) + return 0; + + nouveau_fence_flush(chan); + + nvpb->size -= nvpb->base.remaining; + nvchan->dma->cur += nvpb->size; + nvchan->dma->free -= nvpb->size; + assert(nvchan->dma->cur <= nvchan->dma->max); + + nvchan->dma = &nvchan->dma_bufmgr; + nvchan->pushbuf[nvpb->nop_jump] = 0x20000000 | + (nvchan->dma->base + (nvchan->dma->cur << 2)); + + /* Validate buffers + apply relocations */ + nvchan->user_charge = 0; + for (i = 0; i < nvpb->nr_relocs; i++) { + struct nouveau_pushbuf_reloc *r = &nvpb->relocs[i]; + struct nouveau_pushbuf_bo *pbbo = r->pbbo; + struct nouveau_bo *bo = pbbo->bo; + + /* Validated, mem matches presumed, no relocation necessary */ + if (pbbo->handled & 2) { + if (!(pbbo->handled & 1)) + assert(0); + continue; + } + + /* Not yet validated, do it now */ + if (!(pbbo->handled & 1)) { + ret = nouveau_bo_validate(chan, bo, pbbo->flags); + if (ret) { + assert(0); + return ret; + } + pbbo->handled |= 1; + + if (bo->offset == nouveau_bo(bo)->offset && + bo->flags == nouveau_bo(bo)->flags) { + pbbo->handled |= 2; + continue; + } + bo->offset = nouveau_bo(bo)->offset; + bo->flags = nouveau_bo(bo)->flags; + } + + /* Apply the relocation */ + *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); + } + nvpb->nr_relocs = 0; + + /* Dereference all buffers on validate list */ + for (i = 0; i < nvpb->nr_buffers; i++) { + struct nouveau_pushbuf_bo *pbbo = &nvpb->buffers[i]; + + nouveau_bo(pbbo->bo)->pending = NULL; + nouveau_bo_del(&pbbo->bo); + } + nvpb->nr_buffers = 0; + + /* Switch back to user's ring */ + RING_SPACE_CH(chan, 1); + OUT_RING_CH(chan, 0x20000000 | ((nvpb->start << 2) + + nvchan->dma_master.base)); + nvchan->dma = &nvchan->dma_master; + + /* Fence + kickoff */ + nouveau_fence_emit(nvpb->fence); + FIRE_RING_CH(chan); + + /* Allocate space for next push buffer */ + ret = nouveau_pushbuf_space(chan, min); + assert(!ret); + + return 0; +} + +static struct nouveau_pushbuf_bo * +nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) +{ + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_pushbuf_bo *pbbo; + + if (nvbo->pending) + return nvbo->pending; + + if (nvpb->nr_buffers >= NOUVEAU_PUSHBUF_MAX_BUFFERS) + return NULL; + pbbo = nvpb->buffers + nvpb->nr_buffers++; + nvbo->pending = pbbo; + + nouveau_bo_ref(bo->device, bo->handle, &pbbo->bo); + pbbo->channel = chan; + pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + pbbo->handled = 0; + return pbbo; +} + +int +nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, + struct nouveau_bo *bo, uint32_t data, uint32_t flags, + uint32_t vor, uint32_t tor) +{ + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); + struct nouveau_pushbuf_bo *pbbo; + struct nouveau_pushbuf_reloc *r; + + if (nvpb->nr_relocs >= NOUVEAU_PUSHBUF_MAX_RELOCS) + return -ENOMEM; + + pbbo = nouveau_pushbuf_emit_buffer(chan, bo); + if (!pbbo) + return -ENOMEM; + pbbo->flags |= (flags & NOUVEAU_BO_RDWR); + pbbo->flags &= (flags | NOUVEAU_BO_RDWR); + + r = nvpb->relocs + nvpb->nr_relocs++; + r->pbbo = pbbo; + r->ptr = ptr; + r->flags = flags; + r->data = data; + r->vor = vor; + r->tor = tor; + + if (flags & NOUVEAU_BO_DUMMY) + *(uint32_t *)ptr = 0; + else + *(uint32_t *)ptr = nouveau_pushbuf_calc_reloc(bo, r); + return 0; +} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_resource.c b/src/gallium/winsys/drm/nouveau/common/nouveau_resource.c new file mode 100644 index 0000000000..766fd279fe --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_resource.c @@ -0,0 +1,116 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 +#include +#include +#include "nouveau_drmif.h" +#include "nouveau_local.h" + +int +nouveau_resource_init(struct nouveau_resource **heap, + unsigned start, unsigned size) +{ + struct nouveau_resource *r; + + r = CALLOC_STRUCT(nouveau_resource); + if (!r) + return 1; + + r->start = start; + r->size = size; + *heap = r; + return 0; +} + +int +nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, + struct nouveau_resource **res) +{ + struct nouveau_resource *r; + + if (!heap || !size || !res || *res) + return 1; + + while (heap) { + if (!heap->in_use && heap->size >= size) { + r = CALLOC_STRUCT(nouveau_resource); + if (!r) + return 1; + + r->start = (heap->start + heap->size) - size; + r->size = size; + r->in_use = 1; + r->priv = priv; + + heap->size -= size; + + r->next = heap->next; + if (heap->next) + heap->next->prev = r; + r->prev = heap; + heap->next = r; + + *res = r; + return 0; + } + + heap = heap->next; + } + + return 1; +} + +void +nouveau_resource_free(struct nouveau_resource **res) +{ + struct nouveau_resource *r; + + if (!res || !*res) + return; + r = *res; + *res = NULL; + + r->in_use = 0; + + if (r->next && !r->next->in_use) { + struct nouveau_resource *new = r->next; + + new->prev = r->prev; + if (r->prev) + r->prev->next = new; + new->size += r->size; + new->start = r->start; + + free(r); + r = new; + } + + if (r->prev && !r->prev->in_use) { + r->prev->next = r->next; + if (r->next) + r->next->prev = r->prev; + r->prev->size += r->size; + FREE(r); + } + +} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/common/nouveau_screen.c new file mode 100644 index 0000000000..422fbf0207 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_screen.c @@ -0,0 +1,31 @@ +#include +#include "nouveau_dri.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" + +int +nouveau_screen_init(struct nouveau_dri *nv_dri, int dev_fd, + struct nouveau_screen *nv_screen) +{ + int ret; + + ret = nouveau_device_open_existing(&nv_screen->device, 0, + dev_fd, 0); + if (ret) { + NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret); + return 1; + } + + nv_screen->front_offset = nv_dri->front_offset; + nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8); + nv_screen->front_cpp = nv_dri->bpp / 8; + nv_screen->front_height = nv_dri->height; + + return 0; +} + +void +nouveau_screen_cleanup(struct nouveau_screen *nv_screen) +{ + nouveau_device_close(&nv_screen->device); +} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_screen.h b/src/gallium/winsys/drm/nouveau/common/nouveau_screen.h new file mode 100644 index 0000000000..3e68e219d8 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_screen.h @@ -0,0 +1,27 @@ +#ifndef __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_SCREEN_H__ + +#include + +struct nouveau_device; +struct nouveau_dri; + +struct nouveau_screen { + struct nouveau_device *device; + + uint32_t front_offset; + uint32_t front_pitch; + uint32_t front_cpp; + uint32_t front_height; + + void *nvc; +}; + +int +nouveau_screen_init(struct nouveau_dri *nv_dri, int dev_fd, + struct nouveau_screen *nv_screen); + +void +nouveau_screen_cleanup(struct nouveau_screen *nv_screen); + +#endif diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c new file mode 100644 index 0000000000..364340e1d3 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c @@ -0,0 +1,161 @@ +#include "util/u_memory.h" + +#include "nouveau_context.h" +#include "nouveau_screen.h" +#include "nouveau_winsys_pipe.h" + +#include "nouveau/nouveau_winsys.h" + +static int +nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count, + struct nouveau_notifier **notify) +{ + struct nouveau_context *nv = nvws->nv; + + return nouveau_notifier_alloc(nv->nvc->channel, nv->nvc->next_handle++, + count, notify); +} + +static int +nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass, + struct nouveau_grobj **grobj) +{ + struct nouveau_context *nv = nvws->nv; + struct nouveau_channel *chan = nv->nvc->channel; + int ret; + + ret = nouveau_grobj_alloc(chan, nv->nvc->next_handle++, + grclass, grobj); + if (ret) + return ret; + + assert(nv->nvc->next_subchannel < 7); + BIND_RING(chan, *grobj, nv->nvc->next_subchannel++); + return 0; +} + +static int +nouveau_pipe_surface_copy(struct nouveau_winsys *nvws, struct pipe_surface *dst, + unsigned dx, unsigned dy, struct pipe_surface *src, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_context *nv = nvws->nv; + + if (nv->surface_copy_prep(nv, dst, src)) + return 1; + nv->surface_copy(nv, dx, dy, sx, sy, w, h); + nv->surface_copy_done(nv); + + return 0; +} + +static int +nouveau_pipe_surface_fill(struct nouveau_winsys *nvws, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + if (nvws->nv->surface_fill(nvws->nv, dst, dx, dy, w, h, value)) + return 1; + 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) +{ + return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, + nouveau_buffer(buf)->bo, + data, flags, vor, tor); +} + +static int +nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size, + struct pipe_fence_handle **fence) +{ + if (fence) { + struct nouveau_pushbuf *pb = nvws->channel->pushbuf; + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(pb); + struct nouveau_fence *ref = NULL; + + nouveau_fence_ref(nvpb->fence, &ref); + *fence = (struct pipe_fence_handle *)ref; + } + + return nouveau_pushbuf_flush(nvws->channel, size); +} + +struct pipe_context * +nouveau_pipe_create(struct nouveau_context *nv) +{ + struct nouveau_channel_context *nvc = nv->nvc; + struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); + struct pipe_screen *(*hws_create)(struct pipe_winsys *, + struct nouveau_winsys *); + struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); + struct pipe_winsys *ws; + unsigned chipset = nv->nv_screen->device->chipset; + + if (!nvws) + return NULL; + + switch (chipset & 0xf0) { + case 0x10: + hws_create = nv10_screen_create; + hw_create = nv10_create; + break; + case 0x20: + hws_create = nv20_screen_create; + hw_create = nv20_create; + break; + case 0x30: + hws_create = nv30_screen_create; + hw_create = nv30_create; + break; + case 0x40: + case 0x60: + hws_create = nv40_screen_create; + hw_create = nv40_create; + break; + case 0x50: + case 0x80: + case 0x90: + hws_create = nv50_screen_create; + hw_create = nv50_create; + break; + default: + NOUVEAU_ERR("Unknown chipset NV%02x\n", chipset); + return NULL; + } + + nvws->nv = nv; + nvws->channel = nv->nvc->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->surface_copy = nouveau_pipe_surface_copy; + nvws->surface_fill = nouveau_pipe_surface_fill; + + ws = nouveau_create_pipe_winsys(nv); + + if (!nvc->pscreen) + nvc->pscreen = hws_create(ws, nvws); + nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id); + return nvc->pctx[nv->pctx_id]; +} + diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c new file mode 100644 index 0000000000..6895137506 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c @@ -0,0 +1,229 @@ +#include +#include +#include +#include +#include "nouveau_context.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_winsys_pipe.h" + +static const char * +nouveau_get_name(struct pipe_winsys *pws) +{ + return "Nouveau/DRI"; +} + +static uint32_t +nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage) +{ + struct nouveau_device *dev = nv->nv_screen->device; + uint32_t flags = NOUVEAU_BO_LOCAL; + + 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 (dev->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 (nv->cap.hw_vertex_buffer) + flags |= NOUVEAU_BO_GART; + } + + if (usage & PIPE_BUFFER_USAGE_INDEX) { + if (nv->cap.hw_index_buffer) + flags |= NOUVEAU_BO_GART; + } + + return flags; +} + +static struct pipe_buffer * +nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, + unsigned usage, unsigned size) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_context *nv = nvpws->nv; + struct nouveau_device *dev = nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + uint32_t flags; + + nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 1; + nvbuf->base.alignment = alignment; + nvbuf->base.usage = usage; + nvbuf->base.size = size; + + flags = nouveau_flags_from_usage(nv, flags); + + 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 *pws, void *ptr, unsigned bytes) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_device *dev = nvpws->nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + + nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 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_winsys *ws, struct pipe_buffer *buf) +{ + struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + + nouveau_bo_del(&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_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; + + /* XXX: Technically incorrect. If the client maps a buffer for write-only + * and leaves part of the buffer untouched it probably expects those parts + * to remain intact. This is violated because we allocate a whole new buffer + * and don't copy the previous buffer's contents, so this optimization is + * only valid if the client intends to overwrite the whole buffer. + */ + if ((map_flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_WR && + !nouveau_bo_busy(nvbuf->bo, map_flags)) { + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_context *nv = nvpws->nv; + struct nouveau_device *dev = nv->nv_screen->device; + struct nouveau_bo *rename; + uint32_t flags = nouveau_flags_from_usage(nv, buf->usage); + + if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) { + nouveau_bo_del(&nvbuf->bo); + nvbuf->bo = rename; + } + } + + 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_buffer(buf); + + nouveau_bo_unmap(nvbuf->bo); +} + +static INLINE struct nouveau_fence * +nouveau_pipe_fence(struct pipe_fence_handle *pfence) +{ + return (struct nouveau_fence *)pfence; +} + +static void +nouveau_pipe_fence_reference(struct pipe_winsys *ws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *pfence) +{ + nouveau_fence_ref((void *)pfence, (void *)ptr); +} + +static int +nouveau_pipe_fence_signalled(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, unsigned flag) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)ws; + struct nouveau_fence *fence = nouveau_pipe_fence(pfence); + + if (nouveau_fence(fence)->signalled == 0) + nouveau_fence_flush(nvpws->nv->nvc->channel); + + return !nouveau_fence(fence)->signalled; +} + +static int +nouveau_pipe_fence_finish(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, unsigned flag) +{ + struct nouveau_fence *fence = nouveau_pipe_fence(pfence); + struct nouveau_fence *ref = NULL; + + nouveau_fence_ref(fence, &ref); + return nouveau_fence_wait(&ref); +} + +static void +nouveau_destroy(struct pipe_winsys *pws) +{ + FREE(pws); +} + +struct pipe_winsys * +nouveau_create_pipe_winsys(struct nouveau_context *nv) +{ + struct nouveau_pipe_winsys *nvpws; + struct pipe_winsys *pws; + + nvpws = CALLOC_STRUCT(nouveau_pipe_winsys); + if (!nvpws) + return NULL; + nvpws->nv = nv; + pws = &nvpws->pws; + + pws->flush_frontbuffer = nouveau_flush_frontbuffer; + + pws->buffer_create = nouveau_pipe_bo_create; + pws->buffer_destroy = nouveau_pipe_bo_del; + pws->user_buffer_create = nouveau_pipe_bo_user_create; + pws->buffer_map = nouveau_pipe_bo_map; + pws->buffer_unmap = nouveau_pipe_bo_unmap; + + pws->fence_reference = nouveau_pipe_fence_reference; + pws->fence_signalled = nouveau_pipe_fence_signalled; + pws->fence_finish = nouveau_pipe_fence_finish; + + pws->get_name = nouveau_get_name; + pws->destroy = nouveau_destroy; + + return &nvpws->pws; +} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h new file mode 100644 index 0000000000..14c728690d --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h @@ -0,0 +1,39 @@ +#ifndef NOUVEAU_PIPE_WINSYS_H +#define NOUVEAU_PIPE_WINSYS_H + +#include "pipe/p_context.h" +#include "pipe/p_winsys.h" +#include "nouveau_context.h" + +struct nouveau_pipe_buffer { + struct pipe_buffer base; + struct nouveau_bo *bo; +}; + +static inline struct nouveau_pipe_buffer * +nouveau_buffer(struct pipe_buffer *buf) +{ + return (struct nouveau_pipe_buffer *)buf; +} + +struct nouveau_pipe_winsys { + struct pipe_winsys pws; + + struct nouveau_context *nv; +}; + +extern struct pipe_winsys * +nouveau_create_pipe_winsys(struct nouveau_context *nv); + +struct pipe_context * +nouveau_create_softpipe(struct nouveau_context *nv); + +struct pipe_context * +nouveau_pipe_create(struct nouveau_context *nv); + +/* Must be provided by clients of common code */ +extern void +nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, + void *context_private); + +#endif diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c new file mode 100644 index 0000000000..04def600f4 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c @@ -0,0 +1,101 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include +#include +#include +#include +#include +#include +#include "nouveau_context.h" +#include "nouveau_winsys_pipe.h" + +struct nouveau_softpipe_winsys { + struct softpipe_winsys sws; + struct nouveau_context *nv; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean +nouveau_is_format_supported(struct softpipe_winsys *sws, + enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + }; + + return FALSE; +} + +struct pipe_context * +nouveau_create_softpipe(struct nouveau_context *nv) +{ + struct nouveau_softpipe_winsys *nvsws; + struct pipe_screen *pscreen; + struct pipe_winsys *ws; + struct pipe_context *pipe; + + ws = nouveau_create_pipe_winsys(nv); + if (!ws) + return NULL; + pscreen = softpipe_create_screen(ws); + if (!pscreen) { + ws->destroy(ws); + return NULL; + } + nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys); + if (!nvsws) { + ws->destroy(ws); + pscreen->destroy(pscreen); + return NULL; + } + + nvsws->sws.is_format_supported = nouveau_is_format_supported; + nvsws->nv = nv; + + pipe = softpipe_create(pscreen, ws, &nvsws->sws); + if (!pipe) { + ws->destroy(ws); + pscreen->destroy(pscreen); + FREE(nvsws); + return NULL; + } + + return pipe; +} + diff --git a/src/gallium/winsys/drm/nouveau/common/nv04_surface.c b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c new file mode 100644 index 0000000000..e9a8a2ac1c --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c @@ -0,0 +1,466 @@ +#include "pipe/p_context.h" +#include "pipe/p_format.h" + +#include "nouveau_context.h" + +static INLINE int log2i(int i) +{ + int r = 0; + + if (i & 0xffff0000) { + i >>= 16; + r += 16; + } + if (i & 0x0000ff00) { + i >>= 8; + r += 8; + } + if (i & 0x000000f0) { + i >>= 4; + r += 4; + } + if (i & 0x0000000c) { + i >>= 2; + r += 2; + } + if (i & 0x00000002) { + r += 1; + } + return r; +} + +static INLINE int +nv04_surface_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; + case PIPE_FORMAT_R16_SNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; + case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_A8R8G8B8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8; + case PIPE_FORMAT_Z24S8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; + default: + return -1; + } +} + +static INLINE int +nv04_rect_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + default: + return -1; + } +} + +static INLINE int +nv04_scaled_image_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A1R5G5B5_UNORM: + return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5; + case PIPE_FORMAT_A8R8G8B8_UNORM: + return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8; + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_R16_SNORM: + return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; + default: + return -1; + } +} + +static INLINE unsigned +nv04_swizzle_bits(unsigned x, unsigned y) +{ + unsigned u = (x & 0x001) << 0 | + (x & 0x002) << 1 | + (x & 0x004) << 2 | + (x & 0x008) << 3 | + (x & 0x010) << 4 | + (x & 0x020) << 5 | + (x & 0x040) << 6 | + (x & 0x080) << 7 | + (x & 0x100) << 8 | + (x & 0x200) << 9 | + (x & 0x400) << 10 | + (x & 0x800) << 11; + + unsigned v = (y & 0x001) << 1 | + (y & 0x002) << 2 | + (y & 0x004) << 3 | + (y & 0x008) << 4 | + (y & 0x010) << 5 | + (y & 0x020) << 6 | + (y & 0x040) << 7 | + (y & 0x080) << 8 | + (y & 0x100) << 9 | + (y & 0x200) << 10 | + (y & 0x400) << 11 | + (y & 0x800) << 12; + return v | u; +} + +static void +nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct pipe_surface *dst = nv->surf_dst; + struct pipe_surface *src = nv->surf_src; + + const unsigned max_w = 1024; + const unsigned max_h = 1024; + const unsigned sub_w = w > max_w ? max_w : w; + const unsigned sub_h = h > max_h ? max_h : h; + unsigned cx = 0; + unsigned cy = 0; + + /* POT or GTFO */ + assert(!(w & (w - 1)) && !(h & (h - 1))); + + BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); + OUT_RING (chan, nv04_surface_format(dst->format) | + log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT | + log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); + + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); + OUT_RING (chan, nv->nvc->NvSwzSurf->handle); + + for (cy = 0; cy < h; cy += sub_h) { + for (cx = 0; cx < w; cx += sub_w) { + BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_OFFSET, 1); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, + dst->offset + nv04_swizzle_bits(cx, cy) * dst->block.size, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); + OUT_RING (chan, nv04_scaled_image_format(src->format)); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); + OUT_RING (chan, 0); + OUT_RING (chan, sub_h << 16 | sub_w); + OUT_RING (chan, 0); + OUT_RING (chan, sub_h << 16 | sub_w); + OUT_RING (chan, 1 << 20); + OUT_RING (chan, 1 << 20); + + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); + OUT_RING (chan, sub_h << 16 | sub_w); + OUT_RING (chan, src->stride | + NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | + NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, + src->offset + cy * src->stride + cx * src->block.size, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RING (chan, 0); + } + } +} + +static void +nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct pipe_surface *dst = nv->surf_dst; + struct pipe_surface *src = nv->surf_src; + unsigned dst_offset, src_offset; + + dst_offset = dst->offset + (dy * dst->stride) + (dx * dst->block.size); + src_offset = src->offset + (sy * src->stride) + (sx * src->block.size); + + while (h) { + int count = (h > 2047) ? 2047 : h; + + BEGIN_RING(chan, nv->nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src_offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst_offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); + OUT_RING (chan, src->stride); + OUT_RING (chan, dst->stride); + OUT_RING (chan, w * src->block.size); + OUT_RING (chan, count); + OUT_RING (chan, 0x0101); + OUT_RING (chan, 0); + + h -= count; + src_offset += src->stride * count; + dst_offset += dst->stride * count; + } +} + +static void +nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_channel *chan = nv->nvc->channel; + + BEGIN_RING(chan, nv->nvc->NvImageBlit, 0x0300, 3); + OUT_RING (chan, (sy << 16) | sx); + OUT_RING (chan, (dy << 16) | dx); + OUT_RING (chan, ( h << 16) | w); +} + +static int +nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, + struct pipe_surface *src) +{ + struct nouveau_channel *chan = nv->nvc->channel; + int format; + + if (src->format != dst->format) + return 1; + + /* Setup transfer to swizzle the texture to vram if needed */ + /* FIXME/TODO: check proper limits of this operation */ + if (src->texture && dst->texture) { + unsigned int src_linear = src->texture->tex_usage & + NOUVEAU_TEXTURE_USAGE_LINEAR; + unsigned int dst_linear = dst->texture->tex_usage & + NOUVEAU_TEXTURE_USAGE_LINEAR; + if (src_linear ^ dst_linear) { + nv->surface_copy = nv04_surface_copy_swizzle; + nv->surf_dst = dst; + nv->surf_src = src; + return 0; + } + } + + /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback + * to NV_MEMORY_TO_MEMORY_FORMAT in this case. + */ + if ((src->offset & 63) || (dst->offset & 63)) { + BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + nv->surface_copy = nv04_surface_copy_m2mf; + nv->surf_dst = dst; + nv->surf_src = src; + return 0; + + } + + if ((format = nv04_surface_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad surface format 0x%x\n", dst->format); + return 1; + } + nv->surface_copy = nv04_surface_copy_blit; + + BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, format); + OUT_RING (chan, (dst->stride << 16) | src->stride); + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + return 0; +} + +static void +nv04_surface_copy_done(struct nouveau_context *nv) +{ + FIRE_RING(nv->nvc->channel); +} + +static int +nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *surf2d = nv->nvc->NvCtxSurf2D; + struct nouveau_grobj *rect = nv->nvc->NvGdiRect; + int cs2d_format, gdirect_format; + + if ((cs2d_format = nv04_surface_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad format = %d\n", dst->format); + return 1; + } + + if ((gdirect_format = nv04_rect_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad format = %d\n", dst->format); + return 1; + } + + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, cs2d_format); + OUT_RING (chan, (dst->stride << 16) | dst->stride); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); + OUT_RING (chan, gdirect_format); + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); + OUT_RING (chan, value); + BEGIN_RING(chan, rect, + NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); + OUT_RING (chan, (dx << 16) | dy); + OUT_RING (chan, ( w << 16) | h); + + FIRE_RING(chan); + return 0; +} + +int +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) +{ + struct nouveau_channel *chan = nvc->channel; + unsigned chipset = nvc->channel->device->chipset, class; + int ret; + + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, 0x39, + &nvc->NvM2MF))) { + NOUVEAU_ERR("Error creating m2mf object: %d\n", ret); + return 1; + } + BIND_RING (chan, nvc->NvM2MF, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + + class = chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : + NV10_CONTEXT_SURFACES_2D; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvCtxSurf2D))) { + NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); + return 1; + } + BIND_RING (chan, nvc->NvCtxSurf2D, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RING (chan, nvc->channel->vram->handle); + OUT_RING (chan, nvc->channel->vram->handle); + + class = chipset < 0x10 ? NV04_IMAGE_BLIT : NV12_IMAGE_BLIT; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvImageBlit))) { + NOUVEAU_ERR("Error creating blit object: %d\n", ret); + return 1; + } + BIND_RING (chan, nvc->NvImageBlit, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); + OUT_RING (chan, nvc->NvCtxSurf2D->handle); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); + OUT_RING (chan, NV04_IMAGE_BLIT_OPERATION_SRCCOPY); + + class = NV04_GDI_RECTANGLE_TEXT; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvGdiRect))) { + NOUVEAU_ERR("Error creating rect object: %d\n", ret); + return 1; + } + BIND_RING (chan, nvc->NvGdiRect, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); + OUT_RING (chan, nvc->NvCtxSurf2D->handle); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); + BEGIN_RING(chan, nvc->NvGdiRect, + NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + + switch (chipset & 0xf0) { + case 0x00: + case 0x10: + class = NV04_SWIZZLED_SURFACE; + break; + case 0x20: + class = NV20_SWIZZLED_SURFACE; + break; + case 0x30: + class = NV30_SWIZZLED_SURFACE; + break; + case 0x40: + case 0x60: + class = NV40_SWIZZLED_SURFACE; + break; + default: + /* Famous last words: this really can't happen.. */ + assert(0); + break; + } + + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvSwzSurf); + if (ret) { + NOUVEAU_ERR("Error creating swizzled surface: %d\n", ret); + return 1; + } + + BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); + + if (chipset < 0x10) { + class = NV04_SCALED_IMAGE_FROM_MEMORY; + } else + if (chipset < 0x40) { + class = NV10_SCALED_IMAGE_FROM_MEMORY; + } else { + class = NV40_SCALED_IMAGE_FROM_MEMORY; + } + + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvSIFM); + if (ret) { + NOUVEAU_ERR("Error creating scaled image object: %d\n", ret); + return 1; + } + + BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); + + return 0; +} + +int +nouveau_surface_init_nv04(struct nouveau_context *nv) +{ + nv->surface_copy_prep = nv04_surface_copy_prep; + nv->surface_copy = nv04_surface_copy_blit; + nv->surface_copy_done = nv04_surface_copy_done; + nv->surface_fill = nv04_surface_fill; + return 0; +} + diff --git a/src/gallium/winsys/drm/nouveau/common/nv50_surface.c b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c new file mode 100644 index 0000000000..c8ab7f690f --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c @@ -0,0 +1,194 @@ +#include "pipe/p_context.h" +#include "pipe/p_format.h" + +#include "nouveau_context.h" + +static INLINE int +nv50_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV50_2D_DST_FORMAT_32BPP; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return NV50_2D_DST_FORMAT_24BPP; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV50_2D_DST_FORMAT_16BPP; + case PIPE_FORMAT_A8_UNORM: + return NV50_2D_DST_FORMAT_8BPP; + default: + return -1; + } +} + +static int +nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; + struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->bo; + int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; + int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); + + surf_format = nv50_format(surf->format); + if (surf_format < 0) + return 1; + + if (!nouveau_bo(bo)->tiled) { + BEGIN_RING(chan, eng2d, mthd, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, mthd + 0x14, 5); + OUT_RING (chan, surf->stride); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + OUT_RELOCh(chan, bo, surf->offset, flags); + OUT_RELOCl(chan, bo, surf->offset, flags); + } else { + BEGIN_RING(chan, eng2d, mthd, 5); + OUT_RING (chan, surf_format); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, mthd + 0x18, 4); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + OUT_RELOCh(chan, bo, surf->offset, flags); + OUT_RELOCl(chan, bo, surf->offset, flags); + } + +#if 0 + if (dst) { + BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + } +#endif + + return 0; +} + +static int +nv50_surface_copy_prep(struct nouveau_context *nv, + struct pipe_surface *dst, struct pipe_surface *src) +{ + int ret; + + assert(src->format == dst->format); + + ret = nv50_surface_set(nv, dst, 1); + if (ret) + return ret; + + ret = nv50_surface_set(nv, src, 0); + if (ret) + return ret; + + return 0; +} + +static void +nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; + + BEGIN_RING(chan, eng2d, 0x088c, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4); + OUT_RING (chan, dx); + OUT_RING (chan, dy); + OUT_RING (chan, w); + OUT_RING (chan, h); + BEGIN_RING(chan, eng2d, 0x08c0, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, 0x08d0, 4); + OUT_RING (chan, 0); + OUT_RING (chan, sx); + OUT_RING (chan, 0); + OUT_RING (chan, sy); +} + +static void +nv50_surface_copy_done(struct nouveau_context *nv) +{ + FIRE_RING(nv->nvc->channel); +} + +static int +nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; + int rect_format, ret; + + rect_format = nv50_format(dst->format); + if (rect_format < 0) + return 1; + + ret = nv50_surface_set(nv, dst, 1); + if (ret) + return ret; + + BEGIN_RING(chan, eng2d, 0x0580, 3); + OUT_RING (chan, 4); + OUT_RING (chan, rect_format); + OUT_RING (chan, value); + + BEGIN_RING(chan, eng2d, NV50_2D_RECT_X1, 4); + OUT_RING (chan, dx); + OUT_RING (chan, dy); + OUT_RING (chan, dx + w); + OUT_RING (chan, dy + h); + + FIRE_RING(chan); + return 0; +} + +int +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) +{ + struct nouveau_channel *chan = nvc->channel; + struct nouveau_grobj *eng2d = NULL; + int ret; + + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d); + if (ret) + return ret; + nvc->Nv2D = eng2d; + + BIND_RING (chan, eng2d, nvc->next_subchannel++); + BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4); + OUT_RING (chan, nvc->sync_notifier->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1); + OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); + BEGIN_RING(chan, eng2d, 0x0290, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, 0x0888, 1); + OUT_RING (chan, 1); + + return 0; +} + +int +nouveau_surface_init_nv50(struct nouveau_context *nv) +{ + nv->surface_copy_prep = nv50_surface_copy_prep; + nv->surface_copy = nv50_surface_copy; + nv->surface_copy_done = nv50_surface_copy_done; + nv->surface_fill = nv50_surface_fill; + return 0; +} + diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/winsys/drm/nouveau/dri/Makefile new file mode 100644 index 0000000000..e129e42e97 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/dri/Makefile @@ -0,0 +1,31 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +LIBNAME = nouveau_dri.so + +MINIGLX_SOURCES = + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.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_dri.c \ + nouveau_screen_dri.c \ + nouveau_swapbuffers.c \ + ../common/libnouveaudrm.a + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c new file mode 100644 index 0000000000..006978b182 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c @@ -0,0 +1,124 @@ +#include
+#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../common/nouveau_winsys_pipe.h" +#include "../common/nouveau_dri.h" +#include "../common/nouveau_local.h" +#include "nouveau_context_dri.h" +#include "nouveau_screen_dri.h" + +#ifdef DEBUG +static const struct dri_debug_control debug_control[] = { + { "bo", DEBUG_BO }, + { NULL, 0 } +}; +int __nouveau_debug = 0; +#endif + +GLboolean +nouveau_context_create(const __GLcontextModes *glVis, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate) +{ + __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv; + struct nouveau_screen_dri *nv_screen = driScrnPriv->private; + struct nouveau_context_dri *nv = CALLOC_STRUCT(nouveau_context_dri); + struct st_context *st_share = NULL; + struct nouveau_context_dri *nv_share = NULL; + struct pipe_context *pipe; + + if (sharedContextPrivate) { + st_share = ((struct nouveau_context_dri *)sharedContextPrivate)->st; + nv_share = st_share->pipe->priv; + } + + if (nouveau_context_init(&nv_screen->base, driContextPriv->hHWContext, + (drmLock *)&driScrnPriv->pSAREA->lock, + nv_share, &nv->base)) { + return GL_FALSE; + } + + pipe = nv->base.nvc->pctx[nv->base.pctx_id]; + driContextPriv->driverPrivate = (void *)nv; + //nv->nv_screen = nv_screen; + nv->dri_screen = driScrnPriv; + + driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, + nv->dri_screen->myNum, "nouveau"); +#ifdef DEBUG + __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"), + debug_control); +#endif + + nv->st = st_create_context(pipe, glVis, st_share); + return GL_TRUE; +} + +void +nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) +{ + struct nouveau_context_dri *nv = driContextPriv->driverPrivate; + + assert(nv); + + st_finish(nv->st); + st_destroy_context(nv->st); + + nouveau_context_cleanup(&nv->base); + + FREE(nv); +} + +GLboolean +nouveau_context_bind(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) +{ + struct nouveau_context_dri *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_dri *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_dri.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h new file mode 100644 index 0000000000..8257790d47 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h @@ -0,0 +1,49 @@ +#ifndef __NOUVEAU_CONTEXT_DRI_H__ +#define __NOUVEAU_CONTEXT_DRI_H__ + +#include +#include +#include +#include "../common/nouveau_context.h" +#include "../common/nouveau_drmif.h" +#include "../common/nouveau_dma.h" + +struct nouveau_framebuffer { + struct st_framebuffer *stfb; +}; + +struct nouveau_context_dri { + struct nouveau_context base; + 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; +}; + +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 *); + +#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_screen_dri.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c new file mode 100644 index 0000000000..1d7c92376f --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c @@ -0,0 +1,259 @@ +#include +#include +#include + +#include +#include +#include +#include +#include "../common/nouveau_dri.h" +#include "../common/nouveau_local.h" +#include "nouveau_context_dri.h" +#include "nouveau_screen_dri.h" +#include "nouveau_swapbuffers.h" + +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 +#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 const __DRIconfig ** +nouveau_screen_create(__DRIscreenPrivate *psp) +{ + struct nouveau_dri *nv_dri = psp->pDevPriv; + struct nouveau_screen_dri *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_dri); + if (!nv_screen) + return NULL; + + driParseOptionInfo(&nv_screen->option_cache, + __driConfigOptions, __driNConfigOptions); + + if (nouveau_screen_init(nv_dri, psp->fd, &nv_screen->base)) { + FREE(nv_screen); + return NULL; + } + + 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_dri *nv_screen = driScrnPriv->private; + + driScrnPriv->private = NULL; + nouveau_screen_cleanup(&nv_screen->base); + 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_dri.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h new file mode 100644 index 0000000000..1498087819 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h @@ -0,0 +1,13 @@ +#ifndef __NOUVEAU_SCREEN_DRI_H__ +#define __NOUVEAU_SCREEN_DRI_H__ + +#include "../common/nouveau_screen.h" +#include "xmlconfig.h" + +struct nouveau_screen_dri { + struct nouveau_screen base; + __DRIscreenPrivate *driScrnPriv; + driOptionCache option_cache; +}; + +#endif diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c new file mode 100644 index 0000000000..38461b2b0c --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c @@ -0,0 +1,112 @@ +#include
+#include +#include + +#include +#include +#include +#include + +#include "../common/nouveau_local.h" +#include "nouveau_context_dri.h" +#include "nouveau_screen_dri.h" +#include "nouveau_swapbuffers.h" + +void +nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct nouveau_context_dri *nv = dPriv->driContextPriv->driverPrivate; + drm_clip_rect_t *pbox; + int nbox, i; + + LOCK_HARDWARE(&nv->base); + if (!dPriv->numClipRects) { + UNLOCK_HARDWARE(&nv->base); + return; + } + pbox = dPriv->pClipRects; + nbox = dPriv->numClipRects; + + nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf); + 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; + + nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h); + } + + FIRE_RING(nv->base.nvc->channel); + UNLOCK_HARDWARE(&nv->base); + + 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; + + surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); + 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; + + surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); + if (surf) { + st_notify_swapbuffers(nvfb->stfb); + nouveau_copy_buffer(dPriv, surf, NULL); + } +} + +void +nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, + void *context_private) +{ + struct nouveau_context_dri *nv = context_private; + __DRIdrawablePrivate *dPriv = nv->dri_drawable; + + nouveau_copy_buffer(dPriv, surf, NULL); +} + +void +nouveau_contended_lock(struct nouveau_context *nv) +{ + struct nouveau_context_dri *nv_sub = (struct nouveau_context_dri*)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 new file mode 100644 index 0000000000..825d3da6da --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h @@ -0,0 +1,10 @@ +#ifndef __NOUVEAU_SWAPBUFFERS_H__ +#define __NOUVEAU_SWAPBUFFERS_H__ + +extern void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *, + const drm_clip_rect_t *); +extern void nouveau_copy_sub_buffer(__DRIdrawablePrivate *, + int x, int y, int w, int h); +extern void nouveau_swap_buffers(__DRIdrawablePrivate *); + +#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_bo.c b/src/gallium/winsys/drm/nouveau/nouveau_bo.c deleted file mode 100644 index 76b98bed67..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_bo.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" -#include "nouveau_local.h" - -static void -nouveau_mem_free(struct nouveau_device *dev, struct drm_nouveau_mem_alloc *ma, - void **map) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct drm_nouveau_mem_free mf; - - if (map && *map) { - drmUnmap(*map, ma->size); - *map = NULL; - } - - if (ma->size) { - mf.offset = ma->offset; - mf.flags = ma->flags; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_MEM_FREE, - &mf, sizeof(mf)); - ma->size = 0; - } -} - -static int -nouveau_mem_alloc(struct nouveau_device *dev, unsigned size, unsigned align, - uint32_t flags, struct drm_nouveau_mem_alloc *ma, void **map) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - int ret; - - ma->alignment = align; - ma->size = size; - ma->flags = flags; - if (map) - ma->flags |= NOUVEAU_MEM_MAPPED; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_MEM_ALLOC, ma, - sizeof(struct drm_nouveau_mem_alloc)); - if (ret) - return ret; - - if (map) { - ret = drmMap(nvdev->fd, ma->map_handle, ma->size, map); - if (ret) { - *map = NULL; - nouveau_mem_free(dev, ma, map); - return ret; - } - } - - return 0; -} - -static void -nouveau_bo_tmp_del(void *priv) -{ - struct nouveau_resource *r = priv; - - nouveau_fence_ref(NULL, (struct nouveau_fence **)&r->priv); - nouveau_resource_free(&r); -} - -static unsigned -nouveau_bo_tmp_max(struct nouveau_device_priv *nvdev) -{ - struct nouveau_resource *r = nvdev->sa_heap; - unsigned max = 0; - - while (r) { - if (r->in_use && !nouveau_fence(r->priv)->emitted) { - r = r->next; - continue; - } - - if (max < r->size) - max = r->size; - r = r->next; - } - - return max; -} - -static struct nouveau_resource * -nouveau_bo_tmp(struct nouveau_channel *chan, unsigned size, - struct nouveau_fence *fence) -{ - struct nouveau_device_priv *nvdev = nouveau_device(chan->device); - struct nouveau_resource *r = NULL; - struct nouveau_fence *ref = NULL; - - if (fence) - nouveau_fence_ref(fence, &ref); - else - nouveau_fence_new(chan, &ref); - assert(ref); - - while (nouveau_resource_alloc(nvdev->sa_heap, size, ref, &r)) { - if (nouveau_bo_tmp_max(nvdev) < size) { - nouveau_fence_ref(NULL, &ref); - return NULL; - } - - nouveau_fence_flush(chan); - } - nouveau_fence_signal_cb(ref, nouveau_bo_tmp_del, r); - - return r; -} - -int -nouveau_bo_init(struct nouveau_device *dev) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - int ret; - - ret = nouveau_mem_alloc(dev, 128*1024, 0, NOUVEAU_MEM_AGP | - NOUVEAU_MEM_PCI, &nvdev->sa, &nvdev->sa_map); - if (ret) - return ret; - - ret = nouveau_resource_init(&nvdev->sa_heap, 0, nvdev->sa.size); - if (ret) { - nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); - return ret; - } - - return 0; -} - -void -nouveau_bo_takedown(struct nouveau_device *dev) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); -} - -int -nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, - int size, struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo; - int ret; - - if (!dev || !bo || *bo) - return -EINVAL; - - nvbo = calloc(1, sizeof(struct nouveau_bo_priv)); - if (!nvbo) - return -ENOMEM; - nvbo->base.device = dev; - nvbo->base.size = size; - nvbo->base.handle = bo_to_ptr(nvbo); - nvbo->drm.alignment = align; - nvbo->refcount = 1; - - if (flags & NOUVEAU_BO_TILED) { - nvbo->tiled = 1; - if (flags & NOUVEAU_BO_ZTILE) - nvbo->tiled |= 2; - flags &= ~NOUVEAU_BO_TILED; - } - - ret = nouveau_bo_set_status(&nvbo->base, flags); - if (ret) { - free(nvbo); - return ret; - } - - *bo = &nvbo->base; - return 0; -} - -int -nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size, - struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo; - - if (!dev || !bo || *bo) - return -EINVAL; - - nvbo = calloc(1, sizeof(*nvbo)); - if (!nvbo) - return -ENOMEM; - nvbo->base.device = dev; - - nvbo->sysmem = ptr; - nvbo->user = 1; - - nvbo->base.size = size; - nvbo->base.offset = nvbo->drm.offset; - nvbo->base.handle = bo_to_ptr(nvbo); - nvbo->refcount = 1; - *bo = &nvbo->base; - return 0; -} - -int -nouveau_bo_ref(struct nouveau_device *dev, uint64_t handle, - struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo = ptr_to_bo(handle); - - if (!dev || !bo || *bo) - return -EINVAL; - - nvbo->refcount++; - *bo = &nvbo->base; - return 0; -} - -static void -nouveau_bo_del_cb(void *priv) -{ - struct nouveau_bo_priv *nvbo = priv; - - nouveau_fence_ref(NULL, &nvbo->fence); - nouveau_mem_free(nvbo->base.device, &nvbo->drm, &nvbo->map); - if (nvbo->sysmem && !nvbo->user) - free(nvbo->sysmem); - free(nvbo); -} - -void -nouveau_bo_del(struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo; - - if (!bo || !*bo) - return; - nvbo = nouveau_bo(*bo); - *bo = NULL; - - if (--nvbo->refcount) - return; - - if (nvbo->pending) - nouveau_pushbuf_flush(nvbo->pending->channel, 0); - - if (nvbo->fence) - nouveau_fence_signal_cb(nvbo->fence, nouveau_bo_del_cb, nvbo); - else - nouveau_bo_del_cb(nvbo); -} - -int -nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_fence *fence; - - if (!nvbo) - return -EINVAL; - - /* If the buffer is pending it must be busy, unless - * both are RD, in which case we can allow access */ - if (nvbo->pending) { - if ((nvbo->pending->flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD && - (flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD) - return 0; - else - return 1; - } - - if (flags & NOUVEAU_BO_WR) - fence = nvbo->fence; - else - fence = nvbo->wr_fence; - - /* If the buffer is not pending and doesn't have a fence - * that conflicts with our flags then it can't be busy - */ - if (!fence) - return 0; - else - /* If the fence is signalled the buffer is not busy, else is busy */ - return !nouveau_fence(fence)->signalled; -} - -int -nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - - if (!nvbo) - return -EINVAL; - - if (nvbo->pending && - (nvbo->pending->flags & NOUVEAU_BO_WR || flags & NOUVEAU_BO_WR)) { - nouveau_pushbuf_flush(nvbo->pending->channel, 0); - } - - if (flags & NOUVEAU_BO_WR) - nouveau_fence_wait(&nvbo->fence); - else - nouveau_fence_wait(&nvbo->wr_fence); - - if (nvbo->sysmem) - bo->map = nvbo->sysmem; - else - bo->map = nvbo->map; - return 0; -} - -void -nouveau_bo_unmap(struct nouveau_bo *bo) -{ - bo->map = NULL; -} - -static int -nouveau_bo_upload(struct nouveau_bo_priv *nvbo) -{ - if (nvbo->fence) - nouveau_fence_wait(&nvbo->fence); - memcpy(nvbo->map, nvbo->sysmem, nvbo->drm.size); - return 0; -} - -int -nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct drm_nouveau_mem_alloc new; - void *new_map = NULL, *new_sysmem = NULL; - unsigned new_flags = 0, ret; - - assert(!bo->map); - - /* Check current memtype vs requested, if they match do nothing */ - if ((nvbo->drm.flags & NOUVEAU_MEM_FB) && (flags & NOUVEAU_BO_VRAM)) - return 0; - if ((nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) && - (flags & NOUVEAU_BO_GART)) - return 0; - if (nvbo->drm.size == 0 && nvbo->sysmem && (flags & NOUVEAU_BO_LOCAL)) - return 0; - - memset(&new, 0x00, sizeof(new)); - - /* Allocate new memory */ - if (flags & NOUVEAU_BO_VRAM) - new_flags |= NOUVEAU_MEM_FB; - else - if (flags & NOUVEAU_BO_GART) - new_flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI); - - if (nvbo->tiled && flags) { - new_flags |= NOUVEAU_MEM_TILE; - if (nvbo->tiled & 2) - new_flags |= NOUVEAU_MEM_TILE_ZETA; - } - - if (new_flags) { - ret = nouveau_mem_alloc(bo->device, bo->size, - nvbo->drm.alignment, new_flags, - &new, &new_map); - if (ret) - return ret; - } else - if (!nvbo->user) { - new_sysmem = malloc(bo->size); - } - - /* Copy old -> new */ - /*XXX: use M2MF */ - if (nvbo->sysmem || nvbo->map) { - struct nouveau_pushbuf_bo *pbo = nvbo->pending; - nvbo->pending = NULL; - nouveau_bo_map(bo, NOUVEAU_BO_RD); - memcpy(new_map, bo->map, bo->size); - nouveau_bo_unmap(bo); - nvbo->pending = pbo; - } - - /* Free old memory */ - if (nvbo->fence) - nouveau_fence_wait(&nvbo->fence); - nouveau_mem_free(bo->device, &nvbo->drm, &nvbo->map); - if (nvbo->sysmem && !nvbo->user) - free(nvbo->sysmem); - - nvbo->drm = new; - nvbo->map = new_map; - if (!nvbo->user) - nvbo->sysmem = new_sysmem; - bo->flags = flags; - bo->offset = nvbo->drm.offset; - return 0; -} - -static int -nouveau_bo_validate_user(struct nouveau_channel *chan, struct nouveau_bo *bo, - struct nouveau_fence *fence, uint32_t flags) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_device_priv *nvdev = nouveau_device(chan->device); - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_resource *r; - - if (nvchan->user_charge + bo->size > nvdev->sa.size) - return 1; - - if (!(flags & NOUVEAU_BO_GART)) - return 1; - - r = nouveau_bo_tmp(chan, bo->size, fence); - if (!r) - return 1; - nvchan->user_charge += bo->size; - - memcpy(nvdev->sa_map + r->start, nvbo->sysmem, bo->size); - - nvbo->offset = nvdev->sa.offset + r->start; - nvbo->flags = NOUVEAU_BO_GART; - return 0; -} - -static int -nouveau_bo_validate_bo(struct nouveau_channel *chan, struct nouveau_bo *bo, - struct nouveau_fence *fence, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - int ret; - - ret = nouveau_bo_set_status(bo, flags); - if (ret) { - nouveau_fence_flush(chan); - - ret = nouveau_bo_set_status(bo, flags); - if (ret) - return ret; - } - - if (nvbo->user) - nouveau_bo_upload(nvbo); - - nvbo->offset = nvbo->drm.offset; - if (nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) - nvbo->flags = NOUVEAU_BO_GART; - else - nvbo->flags = NOUVEAU_BO_VRAM; - - return 0; -} - -int -nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo, - uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_fence *fence = nouveau_pushbuf(chan->pushbuf)->fence; - int ret; - - assert(bo->map == NULL); - - if (nvbo->user) { - ret = nouveau_bo_validate_user(chan, bo, fence, flags); - if (ret) { - ret = nouveau_bo_validate_bo(chan, bo, fence, flags); - if (ret) - return ret; - } - } else { - ret = nouveau_bo_validate_bo(chan, bo, fence, flags); - if (ret) - return ret; - } - - if (flags & NOUVEAU_BO_WR) - nouveau_fence_ref(fence, &nvbo->wr_fence); - nouveau_fence_ref(fence, &nvbo->fence); - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/nouveau_channel.c b/src/gallium/winsys/drm/nouveau/nouveau_channel.c deleted file mode 100644 index b7127f8860..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_channel.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" - -int -nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, - uint32_t tt_ctxdma, struct nouveau_channel **chan) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct nouveau_channel_priv *nvchan; - int ret; - - if (!nvdev || !chan || *chan) - return -EINVAL; - - nvchan = calloc(1, sizeof(struct nouveau_channel_priv)); - if (!nvchan) - return -ENOMEM; - nvchan->base.device = dev; - - nvchan->drm.fb_ctxdma_handle = fb_ctxdma; - nvchan->drm.tt_ctxdma_handle = tt_ctxdma; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, - &nvchan->drm, sizeof(nvchan->drm)); - if (ret) { - free(nvchan); - return ret; - } - - nvchan->base.id = nvchan->drm.channel; - if (nouveau_grobj_ref(&nvchan->base, nvchan->drm.fb_ctxdma_handle, - &nvchan->base.vram) || - nouveau_grobj_ref(&nvchan->base, nvchan->drm.tt_ctxdma_handle, - &nvchan->base.gart)) { - nouveau_channel_free((void *)&nvchan); - return -EINVAL; - } - - ret = drmMap(nvdev->fd, nvchan->drm.ctrl, nvchan->drm.ctrl_size, - (void*)&nvchan->user); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - nvchan->put = &nvchan->user[0x40/4]; - nvchan->get = &nvchan->user[0x44/4]; - nvchan->ref_cnt = &nvchan->user[0x48/4]; - - ret = drmMap(nvdev->fd, nvchan->drm.notifier, nvchan->drm.notifier_size, - (drmAddressPtr)&nvchan->notifier_block); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - - ret = drmMap(nvdev->fd, nvchan->drm.cmdbuf, nvchan->drm.cmdbuf_size, - (void*)&nvchan->pushbuf); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - - ret = nouveau_grobj_alloc(&nvchan->base, 0x00000000, 0x0030, - &nvchan->base.nullobj); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - - nouveau_dma_channel_init(&nvchan->base); - nouveau_pushbuf_init(&nvchan->base); - - *chan = &nvchan->base; - return 0; -} - -void -nouveau_channel_free(struct nouveau_channel **chan) -{ - struct nouveau_channel_priv *nvchan; - struct nouveau_device_priv *nvdev; - struct drm_nouveau_channel_free cf; - - if (!chan || !*chan) - return; - nvchan = nouveau_channel(*chan); - *chan = NULL; - nvdev = nouveau_device(nvchan->base.device); - - FIRE_RING_CH(&nvchan->base); - - nouveau_grobj_free(&nvchan->base.vram); - nouveau_grobj_free(&nvchan->base.gart); - nouveau_grobj_free(&nvchan->base.nullobj); - - free(nvchan->pb.buffers); - free(nvchan->pb.relocs); - cf.channel = nvchan->drm.channel; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf)); - free(nvchan); -} - - diff --git a/src/gallium/winsys/drm/nouveau/nouveau_context.c b/src/gallium/winsys/drm/nouveau/nouveau_context.c deleted file mode 100644 index 74413c408f..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_context.c +++ /dev/null @@ -1,346 +0,0 @@ -#include "main/glheader.h" -#include "glapi/glthread.h" -#include -#include "utils.h" - -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_context.h" -#include "pipe/p_screen.h" - -#include "nouveau_context.h" -#include "nouveau_dri.h" -#include "nouveau_local.h" -#include "nouveau_screen.h" -#include "nouveau_winsys_pipe.h" - -#ifdef DEBUG -static const struct dri_debug_control debug_control[] = { - { "bo", DEBUG_BO }, - { NULL, 0 } -}; -int __nouveau_debug = 0; -#endif - -static void -nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) -{ - nouveau_grobj_free(&nvc->NvCtxSurf2D); - nouveau_grobj_free(&nvc->NvImageBlit); - nouveau_grobj_free(&nvc->NvGdiRect); - nouveau_grobj_free(&nvc->NvM2MF); - nouveau_grobj_free(&nvc->Nv2D); - nouveau_grobj_free(&nvc->NvSwzSurf); - nouveau_grobj_free(&nvc->NvSIFM); - - nouveau_notifier_free(&nvc->sync_notifier); - - nouveau_channel_free(&nvc->channel); - - FREE(nvc); -} - -static struct nouveau_channel_context * -nouveau_channel_context_create(struct nouveau_device *dev) -{ - struct nouveau_channel_context *nvc; - int ret; - - nvc = CALLOC_STRUCT(nouveau_channel_context); - if (!nvc) - return NULL; - - if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002, - &nvc->channel))) { - NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); - nouveau_channel_context_destroy(nvc); - return NULL; - } - - nvc->next_handle = 0x80000000; - - if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, - &nvc->sync_notifier))) { - NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); - nouveau_channel_context_destroy(nvc); - return NULL; - } - - switch (dev->chipset & 0xf0) { - case 0x50: - case 0x80: - case 0x90: - ret = nouveau_surface_channel_create_nv50(nvc); - break; - default: - ret = nouveau_surface_channel_create_nv04(nvc); - break; - } - - if (ret) { - NOUVEAU_ERR("Error initialising surface objects: %d\n", ret); - nouveau_channel_context_destroy(nvc); - return NULL; - } - - return nvc; -} - -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 = CALLOC_STRUCT(nouveau_context); - struct pipe_context *pipe = NULL; - struct st_context *st_share = NULL; - struct nouveau_channel_context *nvc = NULL; - struct nouveau_device *dev = nv_screen->device; - int i; - - if (sharedContextPrivate) { - st_share = ((struct nouveau_context *)sharedContextPrivate)->st; - } - - switch (dev->chipset & 0xf0) { - case 0x10: - case 0x20: - /* NV10 */ - case 0x30: - /* NV30 */ - case 0x40: - case 0x60: - /* NV40 */ - case 0x50: - case 0x80: - case 0x90: - /* G80 */ - break; - default: - NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset); - return GL_FALSE; - } - - driContextPriv->driverPrivate = (void *)nv; - nv->nv_screen = nv_screen; - nv->dri_screen = driScrnPriv; - - { - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - nvdev->ctx = driContextPriv->hHWContext; - nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock; - } - - driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, - nv->dri_screen->myNum, "nouveau"); -#ifdef DEBUG - __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"), - debug_control); -#endif - - /*XXX: Hack up a fake region and buffer object for front buffer. - * This will go away with TTM, replaced with a simple reference - * of the front buffer handle passed to us by the DDX. - */ - { - struct pipe_surface *fb_surf; - struct nouveau_pipe_buffer *fb_buf; - struct nouveau_bo_priv *fb_bo; - - fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); - fb_bo->drm.offset = nv_screen->front_offset; - fb_bo->drm.flags = NOUVEAU_MEM_FB; - fb_bo->drm.size = nv_screen->front_pitch * - nv_screen->front_height; - fb_bo->refcount = 1; - fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; - fb_bo->base.offset = fb_bo->drm.offset; - fb_bo->base.handle = (unsigned long)fb_bo; - fb_bo->base.size = fb_bo->drm.size; - fb_bo->base.device = nv_screen->device; - - fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); - fb_buf->bo = &fb_bo->base; - - fb_surf = calloc(1, sizeof(struct pipe_surface)); - if (nv_screen->front_cpp == 2) - fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; - else - fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; - pf_get_block(fb_surf->format, &fb_surf->block); - fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; - fb_surf->height = nv_screen->front_height; - fb_surf->stride = fb_surf->width * fb_surf->block.size; - fb_surf->refcount = 1; - fb_surf->buffer = &fb_buf->base; - - nv->frontbuffer = fb_surf; - } - - /* Attempt to share a single channel between multiple contexts from - * a single process. - */ - nvc = nv_screen->nvc; - if (!nvc && st_share) { - struct nouveau_context *snv = st_share->pipe->priv; - if (snv) { - nvc = snv->nvc; - } - } - - /*XXX: temporary - disable multi-context/single-channel on pre-NV4x */ - switch (dev->chipset & 0xf0) { - case 0x40: - case 0x60: - /* NV40 class */ - case 0x50: - case 0x80: - case 0x90: - /* G80 class */ - break; - default: - nvc = NULL; - break; - } - - if (!nvc) { - nvc = nouveau_channel_context_create(dev); - if (!nvc) { - NOUVEAU_ERR("Failed initialising GPU context\n"); - return GL_FALSE; - } - nv_screen->nvc = nvc; - } - - nvc->refcount++; - nv->nvc = nvc; - - /* Find a free slot for a pipe context, allocate a new one if needed */ - nv->pctx_id = -1; - for (i = 0; i < nvc->nr_pctx; i++) { - if (nvc->pctx[i] == NULL) { - nv->pctx_id = i; - break; - } - } - - if (nv->pctx_id < 0) { - nv->pctx_id = nvc->nr_pctx++; - nvc->pctx = - realloc(nvc->pctx, - sizeof(struct pipe_context *) * nvc->nr_pctx); - } - - /* Create pipe */ - switch (dev->chipset & 0xf0) { - case 0x50: - case 0x80: - case 0x90: - if (nouveau_surface_init_nv50(nv)) - return GL_FALSE; - break; - default: - if (nouveau_surface_init_nv04(nv)) - return GL_FALSE; - break; - } - - if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { - struct pipe_screen *pscreen; - - pipe = nouveau_pipe_create(nv); - if (!pipe) - NOUVEAU_ERR("Couldn't create hw pipe\n"); - pscreen = nvc->pscreen; - - nv->cap.hw_vertex_buffer = - pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF); - nv->cap.hw_index_buffer = - pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF); - } - - if (!pipe) { - NOUVEAU_MSG("Using softpipe\n"); - pipe = nouveau_create_softpipe(nv); - if (!pipe) { - NOUVEAU_ERR("Error creating pipe, bailing\n"); - return GL_FALSE; - } - } - - pipe->priv = nv; - nv->st = st_create_context(pipe, glVis, st_share); - return GL_TRUE; -} - -void -nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) -{ - struct nouveau_context *nv = driContextPriv->driverPrivate; - struct nouveau_channel_context *nvc = nv->nvc; - - assert(nv); - - st_finish(nv->st); - st_destroy_context(nv->st); - - if (nv->pctx_id >= 0) { - nvc->pctx[nv->pctx_id] = NULL; - if (--nvc->refcount <= 0) { - nouveau_channel_context_destroy(nvc); - nv->nv_screen->nvc = NULL; - } - } - - 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/nouveau_context.h b/src/gallium/winsys/drm/nouveau/nouveau_context.h deleted file mode 100644 index 77e2147a2c..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_context.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef __NOUVEAU_CONTEXT_H__ -#define __NOUVEAU_CONTEXT_H__ - -#include "dri_util.h" -#include "xmlconfig.h" - -#include "nouveau/nouveau_winsys.h" -#include "nouveau_drmif.h" -#include "nouveau_dma.h" - -struct nouveau_framebuffer { - struct st_framebuffer *stfb; -}; - -struct nouveau_channel_context { - struct pipe_screen *pscreen; - int refcount; - - unsigned cur_pctx; - unsigned nr_pctx; - struct pipe_context **pctx; - - struct nouveau_channel *channel; - - struct nouveau_notifier *sync_notifier; - - /* Common */ - struct nouveau_grobj *NvM2MF; - /* NV04-NV40 */ - struct nouveau_grobj *NvCtxSurf2D; - struct nouveau_grobj *NvSwzSurf; - struct nouveau_grobj *NvImageBlit; - struct nouveau_grobj *NvGdiRect; - struct nouveau_grobj *NvSIFM; - /* G80 */ - struct nouveau_grobj *Nv2D; - - uint32_t next_handle; - uint32_t next_subchannel; - uint32_t next_sequence; -}; - -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; - GLboolean locked; - struct nouveau_screen *nv_screen; - struct pipe_surface *frontbuffer; - - struct { - int hw_vertex_buffer; - int hw_index_buffer; - } cap; - - /* Hardware context */ - struct nouveau_channel_context *nvc; - int pctx_id; - - /* pipe_surface accel */ - struct pipe_surface *surf_src, *surf_dst; - unsigned surf_src_offset, surf_dst_offset; - int (*surface_copy_prep)(struct nouveau_context *, - struct pipe_surface *dst, - struct pipe_surface *src); - void (*surface_copy)(struct nouveau_context *, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h); - void (*surface_copy_done)(struct nouveau_context *); - int (*surface_fill)(struct nouveau_context *, struct pipe_surface *, - unsigned, unsigned, unsigned, unsigned, unsigned); -}; - -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 *); - -#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 - -extern void LOCK_HARDWARE(struct nouveau_context *); -extern void UNLOCK_HARDWARE(struct nouveau_context *); - -extern int -nouveau_surface_channel_create_nv04(struct nouveau_channel_context *); -extern int -nouveau_surface_channel_create_nv50(struct nouveau_channel_context *); -extern int nouveau_surface_init_nv04(struct nouveau_context *); -extern int nouveau_surface_init_nv50(struct nouveau_context *); - -extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int); -extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *); - -#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_device.c b/src/gallium/winsys/drm/nouveau/nouveau_device.c deleted file mode 100644 index 0b452fcd02..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_device.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include - -#include "nouveau_drmif.h" - -int -nouveau_device_open_existing(struct nouveau_device **dev, int close, - int fd, drm_context_t ctx) -{ - struct nouveau_device_priv *nvdev; - int ret; - - if (!dev || *dev) - return -EINVAL; - - nvdev = calloc(1, sizeof(*nvdev)); - if (!nvdev) - return -ENOMEM; - nvdev->fd = fd; - nvdev->ctx = ctx; - nvdev->needs_close = close; - - drmCommandNone(nvdev->fd, DRM_NOUVEAU_CARD_INIT); - - if ((ret = nouveau_bo_init(&nvdev->base))) { - nouveau_device_close((void *)&nvdev); - return ret; - } - - { - uint64_t value; - - ret = nouveau_device_get_param(&nvdev->base, - NOUVEAU_GETPARAM_CHIPSET_ID, - &value); - if (ret) { - nouveau_device_close((void *)&nvdev); - return ret; - } - nvdev->base.chipset = value; - } - - *dev = &nvdev->base; - return 0; -} - -int -nouveau_device_open(struct nouveau_device **dev, const char *busid) -{ - drm_context_t ctx; - int fd, ret; - - if (!dev || *dev) - return -EINVAL; - - fd = drmOpen("nouveau", busid); - if (fd < 0) - return -EINVAL; - - ret = drmCreateContext(fd, &ctx); - if (ret) { - drmClose(fd); - return ret; - } - - ret = nouveau_device_open_existing(dev, 1, fd, ctx); - if (ret) { - drmDestroyContext(fd, ctx); - drmClose(fd); - return ret; - } - - return 0; -} - -void -nouveau_device_close(struct nouveau_device **dev) -{ - struct nouveau_device_priv *nvdev; - - if (dev || !*dev) - return; - nvdev = nouveau_device(*dev); - *dev = NULL; - - nouveau_bo_takedown(&nvdev->base); - - if (nvdev->needs_close) { - drmDestroyContext(nvdev->fd, nvdev->ctx); - drmClose(nvdev->fd); - } - free(nvdev); -} - -int -nouveau_device_get_param(struct nouveau_device *dev, - uint64_t param, uint64_t *value) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct drm_nouveau_getparam g; - int ret; - - if (!nvdev || !value) - return -EINVAL; - - g.param = param; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GETPARAM, - &g, sizeof(g)); - if (ret) - return ret; - - *value = g.value; - return 0; -} - -int -nouveau_device_set_param(struct nouveau_device *dev, - uint64_t param, uint64_t value) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct drm_nouveau_setparam s; - int ret; - - if (!nvdev) - return -EINVAL; - - s.param = param; - s.value = value; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_SETPARAM, - &s, sizeof(s)); - if (ret) - return ret; - - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/nouveau_dma.c b/src/gallium/winsys/drm/nouveau/nouveau_dma.c deleted file mode 100644 index f8a8ba04f6..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_dma.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" -#include "nouveau_local.h" - -static inline uint32_t -READ_GET(struct nouveau_channel_priv *nvchan) -{ - return *nvchan->get; -} - -static inline void -WRITE_PUT(struct nouveau_channel_priv *nvchan, uint32_t val) -{ - uint32_t put = ((val << 2) + nvchan->dma->base); - volatile int dum; - - NOUVEAU_DMA_BARRIER; - dum = READ_GET(nvchan); - - *nvchan->put = put; - nvchan->dma->put = val; -#ifdef NOUVEAU_DMA_TRACE - NOUVEAU_MSG("WRITE_PUT %d/0x%08x\n", nvchan->drm.channel, put); -#endif - - NOUVEAU_DMA_BARRIER; -} - -static inline int -LOCAL_GET(struct nouveau_dma_priv *dma, uint32_t *val) -{ - uint32_t get = *val; - - if (get >= dma->base && get <= (dma->base + (dma->max << 2))) { - *val = (get - dma->base) >> 2; - return 1; - } - - return 0; -} - -void -nouveau_dma_channel_init(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - int i; - - nvchan->dma = &nvchan->dma_master; - nvchan->dma->base = nvchan->drm.put_base; - nvchan->dma->cur = nvchan->dma->put = 0; - nvchan->dma->max = (nvchan->drm.cmdbuf_size >> 2) - 2; - nvchan->dma->free = nvchan->dma->max - nvchan->dma->cur; - - RING_SPACE_CH(chan, RING_SKIPS); - for (i = 0; i < RING_SKIPS; i++) - OUT_RING_CH(chan, 0); -} - -#define CHECK_TIMEOUT() do { \ - if ((NOUVEAU_TIME_MSEC() - t_start) > NOUVEAU_DMA_TIMEOUT) \ - return - EBUSY; \ -} while(0) - -int -nouveau_dma_wait(struct nouveau_channel *chan, int size) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - uint32_t get, t_start; - - FIRE_RING_CH(chan); - - t_start = NOUVEAU_TIME_MSEC(); - while (dma->free < size) { - CHECK_TIMEOUT(); - - get = READ_GET(nvchan); - if (!LOCAL_GET(dma, &get)) - continue; - - if (dma->put >= get) { - dma->free = dma->max - dma->cur; - - if (dma->free < size) { -#ifdef NOUVEAU_DMA_DEBUG - dma->push_free = 1; -#endif - OUT_RING_CH(chan, 0x20000000 | dma->base); - if (get <= RING_SKIPS) { - /*corner case - will be idle*/ - if (dma->put <= RING_SKIPS) - WRITE_PUT(nvchan, - RING_SKIPS + 1); - - do { - CHECK_TIMEOUT(); - get = READ_GET(nvchan); - if (!LOCAL_GET(dma, &get)) - get = 0; - } while (get <= RING_SKIPS); - } - - WRITE_PUT(nvchan, RING_SKIPS); - dma->cur = dma->put = RING_SKIPS; - dma->free = get - (RING_SKIPS + 1); - } - } else { - dma->free = get - dma->cur - 1; - } - } - - return 0; -} - -#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF -static void -nouveau_dma_parse_pushbuf(struct nouveau_channel *chan, int get, int put) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - unsigned mthd_count = 0; - - while (get != put) { - uint32_t gpuget = (get << 2) + nvchan->drm.put_base; - uint32_t data; - - if (get < 0 || get >= nvchan->drm.cmdbuf_size) { - NOUVEAU_ERR("DMA_PT 0x%08x\n", gpuget); - assert(0); - } - data = nvchan->pushbuf[get++]; - - if (mthd_count) { - NOUVEAU_MSG("0x%08x 0x%08x\n", gpuget, data); - mthd_count--; - continue; - } - - switch (data & 0x60000000) { - case 0x00000000: - mthd_count = (data >> 18) & 0x7ff; - NOUVEAU_MSG("0x%08x 0x%08x MTHD " - "Sc %d Mthd 0x%04x Size %d\n", - gpuget, data, (data>>13) & 7, data & 0x1ffc, - mthd_count); - break; - case 0x20000000: - get = (data & 0x1ffffffc) >> 2; - NOUVEAU_MSG("0x%08x 0x%08x JUMP 0x%08x\n", - gpuget, data, data & 0x1ffffffc); - continue; - case 0x40000000: - mthd_count = (data >> 18) & 0x7ff; - NOUVEAU_MSG("0x%08x 0x%08x NINC " - "Sc %d Mthd 0x%04x Size %d\n", - gpuget, data, (data>>13) & 7, data & 0x1ffc, - mthd_count); - break; - case 0x60000000: - /* DMA_OPCODE_CALL apparently, doesn't seem to work on - * my NV40 at least.. - */ - /* fall-through */ - default: - NOUVEAU_MSG("DMA_PUSHER 0x%08x 0x%08x\n", - gpuget, data); - assert(0); - } - } -} -#endif - -void -nouveau_dma_kickoff(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - - if (dma->cur == dma->put) - return; - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free) { - NOUVEAU_ERR("Packet incomplete: %d left\n", dma->push_free); - return; - } -#endif - -#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF - nouveau_dma_parse_pushbuf(chan, dma->put, dma->cur); -#endif - - WRITE_PUT(nvchan, dma->cur); -} diff --git a/src/gallium/winsys/drm/nouveau/nouveau_dma.h b/src/gallium/winsys/drm/nouveau/nouveau_dma.h deleted file mode 100644 index cfa6d26e82..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_dma.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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. - */ - -#ifndef __NOUVEAU_DMA_H__ -#define __NOUVEAU_DMA_H__ - -#include -#include "nouveau_drmif.h" -#include "nouveau_local.h" - -#define RING_SKIPS 8 - -extern int nouveau_dma_wait(struct nouveau_channel *chan, int size); -extern void nouveau_dma_subc_bind(struct nouveau_grobj *); -extern void nouveau_dma_channel_init(struct nouveau_channel *); -extern void nouveau_dma_kickoff(struct nouveau_channel *); - -#ifdef NOUVEAU_DMA_DEBUG -static char faulty[1024]; -#endif - -static inline void -nouveau_dma_out(struct nouveau_channel *chan, uint32_t data) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free == 0) { - NOUVEAU_ERR("No space left in packet at %s\n", faulty); - return; - } - dma->push_free--; -#endif -#ifdef NOUVEAU_DMA_TRACE - { - uint32_t offset = (dma->cur << 2) + dma->base; - NOUVEAU_MSG("\tOUT_RING %d/0x%08x -> 0x%08x\n", - nvchan->drm.channel, offset, data); - } -#endif - nvchan->pushbuf[dma->cur + (dma->base - nvchan->drm.put_base)/4] = data; - dma->cur++; -} - -static inline void -nouveau_dma_outp(struct nouveau_channel *chan, uint32_t *ptr, int size) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - (void)dma; - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free < size) { - NOUVEAU_ERR("Packet too small. Free=%d, Need=%d\n", - dma->push_free, size); - return; - } -#endif -#ifdef NOUVEAU_DMA_TRACE - while (size--) { - nouveau_dma_out(chan, *ptr); - ptr++; - } -#else - memcpy(&nvchan->pushbuf[dma->cur], ptr, size << 2); -#ifdef NOUVEAU_DMA_DEBUG - dma->push_free -= size; -#endif - dma->cur += size; -#endif -} - -static inline void -nouveau_dma_space(struct nouveau_channel *chan, int size) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - - if (dma->free < size) { - if (nouveau_dma_wait(chan, size) && chan->hang_notify) - chan->hang_notify(chan); - } - dma->free -= size; -#ifdef NOUVEAU_DMA_DEBUG - dma->push_free = size; -#endif -} - -static inline void -nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj, - int method, int size, const char* file, int line) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - (void)dma; - -#ifdef NOUVEAU_DMA_TRACE - NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", nvchan->drm.channel, - grobj->handle, grobj->subc, method, size); -#endif - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free) { - NOUVEAU_ERR("Previous packet incomplete: %d left at %s\n", - dma->push_free, faulty); - return; - } - sprintf(faulty,"%s:%d",file,line); -#endif - - nouveau_dma_space(chan, (size + 1)); - nouveau_dma_out(chan, (size << 18) | (grobj->subc << 13) | method); -} - -#define RING_SPACE_CH(ch,sz) nouveau_dma_space((ch), (sz)) -#define BEGIN_RING_CH(ch,gr,m,sz) nouveau_dma_begin((ch), (gr), (m), (sz), __FUNCTION__, __LINE__ ) -#define OUT_RING_CH(ch, data) nouveau_dma_out((ch), (data)) -#define OUT_RINGp_CH(ch,ptr,dwords) nouveau_dma_outp((ch), (void*)(ptr), \ - (dwords)) -#define FIRE_RING_CH(ch) nouveau_dma_kickoff((ch)) -#define WAIT_RING_CH(ch,sz) nouveau_dma_wait((ch), (sz)) - -#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/nouveau_dri.h deleted file mode 100644 index 1207c2d609..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_dri.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _NOUVEAU_DRI_ -#define _NOUVEAU_DRI_ - -#include "xf86drm.h" -#include "drm.h" -#include "nouveau_drm.h" - -struct nouveau_dri { - uint32_t device_id; /**< \brief PCI device ID */ - uint32_t width; /**< \brief width in pixels of display */ - uint32_t height; /**< \brief height in scanlines of display */ - uint32_t depth; /**< \brief depth of display (8, 15, 16, 24) */ - uint32_t bpp; /**< \brief bit depth of display (8, 16, 24, 32) */ - - uint32_t bus_type; /**< \brief ths bus type */ - uint32_t bus_mode; /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */ - - uint32_t front_offset; /**< \brief front buffer offset */ - uint32_t front_pitch; /**< \brief front buffer pitch */ - uint32_t back_offset; /**< \brief private back buffer offset */ - uint32_t back_pitch; /**< \brief private back buffer pitch */ - uint32_t depth_offset; /**< \brief private depth buffer offset */ - uint32_t depth_pitch; /**< \brief private depth buffer pitch */ - -}; - -#endif - diff --git a/src/gallium/winsys/drm/nouveau/nouveau_drmif.h b/src/gallium/winsys/drm/nouveau/nouveau_drmif.h deleted file mode 100644 index 5f72800676..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_drmif.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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. - */ - -#ifndef __NOUVEAU_DRMIF_H__ -#define __NOUVEAU_DRMIF_H__ - -#include -#include -#include - -#include "nouveau/nouveau_device.h" -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_grobj.h" -#include "nouveau/nouveau_notifier.h" -#include "nouveau/nouveau_bo.h" -#include "nouveau/nouveau_resource.h" -#include "nouveau/nouveau_pushbuf.h" - -struct nouveau_device_priv { - struct nouveau_device base; - - int fd; - drm_context_t ctx; - drmLock *lock; - int needs_close; - - struct drm_nouveau_mem_alloc sa; - void *sa_map; - struct nouveau_resource *sa_heap; -}; -#define nouveau_device(n) ((struct nouveau_device_priv *)(n)) - -extern int -nouveau_device_open_existing(struct nouveau_device **, int close, - int fd, drm_context_t ctx); - -extern int -nouveau_device_open(struct nouveau_device **, const char *busid); - -extern void -nouveau_device_close(struct nouveau_device **); - -extern int -nouveau_device_get_param(struct nouveau_device *, uint64_t param, uint64_t *v); - -extern int -nouveau_device_set_param(struct nouveau_device *, uint64_t param, uint64_t val); - -struct nouveau_fence { - struct nouveau_channel *channel; -}; - -struct nouveau_fence_cb { - struct nouveau_fence_cb *next; - void (*func)(void *); - void *priv; -}; - -struct nouveau_fence_priv { - struct nouveau_fence base; - int refcount; - - struct nouveau_fence *next; - struct nouveau_fence_cb *signal_cb; - - uint32_t sequence; - int emitted; - int signalled; -}; -#define nouveau_fence(n) ((struct nouveau_fence_priv *)(n)) - -extern int -nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **); - -extern int -nouveau_fence_ref(struct nouveau_fence *, struct nouveau_fence **); - -extern int -nouveau_fence_signal_cb(struct nouveau_fence *, void (*)(void *), void *); - -extern void -nouveau_fence_emit(struct nouveau_fence *); - -extern int -nouveau_fence_wait(struct nouveau_fence **); - -extern void -nouveau_fence_flush(struct nouveau_channel *); - -struct nouveau_pushbuf_reloc { - struct nouveau_pushbuf_bo *pbbo; - uint32_t *ptr; - uint32_t flags; - uint32_t data; - uint32_t vor; - uint32_t tor; -}; - -struct nouveau_pushbuf_bo { - struct nouveau_channel *channel; - struct nouveau_bo *bo; - unsigned flags; - unsigned handled; -}; - -#define NOUVEAU_PUSHBUF_MAX_BUFFERS 1024 -#define NOUVEAU_PUSHBUF_MAX_RELOCS 1024 -struct nouveau_pushbuf_priv { - struct nouveau_pushbuf base; - - struct nouveau_fence *fence; - - unsigned nop_jump; - unsigned start; - unsigned size; - - struct nouveau_pushbuf_bo *buffers; - unsigned nr_buffers; - struct nouveau_pushbuf_reloc *relocs; - unsigned nr_relocs; -}; -#define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n)) - -#define pbbo_to_ptr(o) ((uint64_t)(unsigned long)(o)) -#define ptr_to_pbbo(h) ((struct nouveau_pushbuf_bo *)(unsigned long)(h)) -#define pbrel_to_ptr(o) ((uint64_t)(unsigned long)(o)) -#define ptr_to_pbrel(h) ((struct nouveau_pushbuf_reloc *)(unsigned long)(h)) -#define bo_to_ptr(o) ((uint64_t)(unsigned long)(o)) -#define ptr_to_bo(h) ((struct nouveau_bo_priv *)(unsigned long)(h)) - -extern int -nouveau_pushbuf_init(struct nouveau_channel *); - -extern int -nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); - -extern int -nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr, - struct nouveau_bo *, uint32_t data, uint32_t flags, - uint32_t vor, uint32_t tor); - -struct nouveau_dma_priv { - uint32_t base; - uint32_t max; - uint32_t cur; - uint32_t put; - uint32_t free; - - int push_free; -} dma; - -struct nouveau_channel_priv { - struct nouveau_channel base; - - struct drm_nouveau_channel_alloc drm; - - uint32_t *pushbuf; - void *notifier_block; - - volatile uint32_t *user; - volatile uint32_t *put; - volatile uint32_t *get; - volatile uint32_t *ref_cnt; - - struct nouveau_dma_priv dma_master; - struct nouveau_dma_priv dma_bufmgr; - struct nouveau_dma_priv *dma; - - struct nouveau_fence *fence_head; - struct nouveau_fence *fence_tail; - uint32_t fence_sequence; - - struct nouveau_pushbuf_priv pb; - - unsigned user_charge; -}; -#define nouveau_channel(n) ((struct nouveau_channel_priv *)(n)) - -extern int -nouveau_channel_alloc(struct nouveau_device *, uint32_t fb, uint32_t tt, - struct nouveau_channel **); - -extern void -nouveau_channel_free(struct nouveau_channel **); - -struct nouveau_grobj_priv { - struct nouveau_grobj base; -}; -#define nouveau_grobj(n) ((struct nouveau_grobj_priv *)(n)) - -extern int nouveau_grobj_alloc(struct nouveau_channel *, uint32_t handle, - int class, struct nouveau_grobj **); -extern int nouveau_grobj_ref(struct nouveau_channel *, uint32_t handle, - struct nouveau_grobj **); -extern void nouveau_grobj_free(struct nouveau_grobj **); - - -struct nouveau_notifier_priv { - struct nouveau_notifier base; - - struct drm_nouveau_notifierobj_alloc drm; - volatile void *map; -}; -#define nouveau_notifier(n) ((struct nouveau_notifier_priv *)(n)) - -extern int -nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, int count, - struct nouveau_notifier **); - -extern void -nouveau_notifier_free(struct nouveau_notifier **); - -extern void -nouveau_notifier_reset(struct nouveau_notifier *, int id); - -extern uint32_t -nouveau_notifier_status(struct nouveau_notifier *, int id); - -extern uint32_t -nouveau_notifier_return_val(struct nouveau_notifier *, int id); - -extern int -nouveau_notifier_wait_status(struct nouveau_notifier *, int id, int status, - int timeout); - -struct nouveau_bo_priv { - struct nouveau_bo base; - - struct nouveau_pushbuf_bo *pending; - struct nouveau_fence *fence; - struct nouveau_fence *wr_fence; - - struct drm_nouveau_mem_alloc drm; - void *map; - - void *sysmem; - int user; - - int refcount; - - uint64_t offset; - uint64_t flags; - int tiled; -}; -#define nouveau_bo(n) ((struct nouveau_bo_priv *)(n)) - -extern int -nouveau_bo_init(struct nouveau_device *); - -extern void -nouveau_bo_takedown(struct nouveau_device *); - -extern int -nouveau_bo_new(struct nouveau_device *, uint32_t flags, int align, int size, - struct nouveau_bo **); - -extern int -nouveau_bo_user(struct nouveau_device *, void *ptr, int size, - struct nouveau_bo **); - -extern int -nouveau_bo_ref(struct nouveau_device *, uint64_t handle, struct nouveau_bo **); - -extern int -nouveau_bo_set_status(struct nouveau_bo *, uint32_t flags); - -extern void -nouveau_bo_del(struct nouveau_bo **); - -extern int -nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags); - -extern int -nouveau_bo_map(struct nouveau_bo *, uint32_t flags); - -extern void -nouveau_bo_unmap(struct nouveau_bo *); - -extern int -nouveau_bo_validate(struct nouveau_channel *, struct nouveau_bo *, - uint32_t flags); - -extern int -nouveau_resource_init(struct nouveau_resource **heap, unsigned start, - unsigned size); - -extern int -nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, - struct nouveau_resource **); - -extern void -nouveau_resource_free(struct nouveau_resource **); - -#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_fence.c b/src/gallium/winsys/drm/nouveau/nouveau_fence.c deleted file mode 100644 index e7b0b4ff07..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_fence.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" -#include "nouveau_local.h" - -static void -nouveau_fence_del_unsignalled(struct nouveau_fence *fence) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); - struct nouveau_fence *le; - - if (nvchan->fence_head == fence) { - nvchan->fence_head = nouveau_fence(fence)->next; - if (nvchan->fence_head == NULL) - nvchan->fence_tail = NULL; - return; - } - - le = nvchan->fence_head; - while (le && nouveau_fence(le)->next != fence) - le = nouveau_fence(le)->next; - assert(le && nouveau_fence(le)->next == fence); - nouveau_fence(le)->next = nouveau_fence(fence)->next; - if (nvchan->fence_tail == fence) - nvchan->fence_tail = le; -} - -static void -nouveau_fence_del(struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!fence || !*fence) - return; - nvfence = nouveau_fence(*fence); - *fence = NULL; - - if (--nvfence->refcount) - return; - - if (nvfence->emitted && !nvfence->signalled) { - if (nvfence->signal_cb) { - nvfence->refcount++; - nouveau_fence_wait((void *)&nvfence); - return; - } - - nouveau_fence_del_unsignalled(&nvfence->base); - } - free(nvfence); -} - -int -nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!chan || !fence || *fence) - return -EINVAL; - - nvfence = calloc(1, sizeof(struct nouveau_fence_priv)); - if (!nvfence) - return -ENOMEM; - nvfence->base.channel = chan; - nvfence->refcount = 1; - - *fence = &nvfence->base; - return 0; -} - -int -nouveau_fence_ref(struct nouveau_fence *ref, struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!fence) - return -EINVAL; - - if (*fence) { - nouveau_fence_del(fence); - *fence = NULL; - } - - if (ref) { - nvfence = nouveau_fence(ref); - nvfence->refcount++; - *fence = &nvfence->base; - } - - return 0; -} - -int -nouveau_fence_signal_cb(struct nouveau_fence *fence, void (*func)(void *), - void *priv) -{ - struct nouveau_fence_priv *nvfence = nouveau_fence(fence); - struct nouveau_fence_cb *cb; - - if (!nvfence || !func) - return -EINVAL; - - cb = malloc(sizeof(struct nouveau_fence_cb)); - if (!cb) - return -ENOMEM; - - cb->func = func; - cb->priv = priv; - cb->next = nvfence->signal_cb; - nvfence->signal_cb = cb; - return 0; -} - -void -nouveau_fence_emit(struct nouveau_fence *fence) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); - struct nouveau_fence_priv *nvfence = nouveau_fence(fence); - - nvfence->emitted = 1; - nvfence->sequence = ++nvchan->fence_sequence; - if (nvfence->sequence == 0xffffffff) - NOUVEAU_ERR("AII wrap unhandled\n"); - - /*XXX: assumes subc 0 is populated */ - RING_SPACE_CH(fence->channel, 2); - OUT_RING_CH (fence->channel, 0x00040050); - OUT_RING_CH (fence->channel, nvfence->sequence); - - if (nvchan->fence_tail) { - nouveau_fence(nvchan->fence_tail)->next = fence; - } else { - nvchan->fence_head = fence; - } - nvchan->fence_tail = fence; -} - -void -nouveau_fence_flush(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - uint32_t sequence = *nvchan->ref_cnt; - - while (nvchan->fence_head) { - struct nouveau_fence_priv *nvfence; - - nvfence = nouveau_fence(nvchan->fence_head); - if (nvfence->sequence > sequence) - break; - nouveau_fence_del_unsignalled(&nvfence->base); - nvfence->signalled = 1; - - if (nvfence->signal_cb) { - struct nouveau_fence *fence = NULL; - - nouveau_fence_ref(&nvfence->base, &fence); - - while (nvfence->signal_cb) { - struct nouveau_fence_cb *cb; - - cb = nvfence->signal_cb; - nvfence->signal_cb = cb->next; - cb->func(cb->priv); - free(cb); - } - - nouveau_fence_ref(NULL, &fence); - } - } -} - -int -nouveau_fence_wait(struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!fence || !*fence) - return -EINVAL; - nvfence = nouveau_fence(*fence); - - if (nvfence->emitted) { - while (!nvfence->signalled) - nouveau_fence_flush(nvfence->base.channel); - } - nouveau_fence_ref(NULL, fence); - - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/nouveau_grobj.c b/src/gallium/winsys/drm/nouveau/nouveau_grobj.c deleted file mode 100644 index 51523897d5..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_grobj.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include - -#include "nouveau_drmif.h" - -int -nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle, - int class, struct nouveau_grobj **grobj) -{ - struct nouveau_device_priv *nvdev = nouveau_device(chan->device); - struct nouveau_grobj_priv *nvgrobj; - struct drm_nouveau_grobj_alloc g; - int ret; - - if (!nvdev || !grobj || *grobj) - return -EINVAL; - - nvgrobj = calloc(1, sizeof(*nvgrobj)); - if (!nvgrobj) - return -ENOMEM; - nvgrobj->base.channel = chan; - nvgrobj->base.handle = handle; - nvgrobj->base.grclass = class; - - g.channel = chan->id; - g.handle = handle; - g.class = class; - ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GROBJ_ALLOC, - &g, sizeof(g)); - if (ret) { - nouveau_grobj_free((void *)&nvgrobj); - return ret; - } - - *grobj = &nvgrobj->base; - return 0; -} - -int -nouveau_grobj_ref(struct nouveau_channel *chan, uint32_t handle, - struct nouveau_grobj **grobj) -{ - struct nouveau_grobj_priv *nvgrobj; - - if (!chan || !grobj || *grobj) - return -EINVAL; - - nvgrobj = calloc(1, sizeof(struct nouveau_grobj_priv)); - if (!nvgrobj) - return -ENOMEM; - nvgrobj->base.channel = chan; - nvgrobj->base.handle = handle; - nvgrobj->base.grclass = 0; - - *grobj = &nvgrobj->base; - return 0; -} - -void -nouveau_grobj_free(struct nouveau_grobj **grobj) -{ - struct nouveau_device_priv *nvdev; - struct nouveau_channel_priv *chan; - struct nouveau_grobj_priv *nvgrobj; - - if (!grobj || !*grobj) - return; - nvgrobj = nouveau_grobj(*grobj); - *grobj = NULL; - - - chan = nouveau_channel(nvgrobj->base.channel); - nvdev = nouveau_device(chan->base.device); - - if (nvgrobj->base.grclass) { - struct drm_nouveau_gpuobj_free f; - - f.channel = chan->drm.channel; - f.handle = nvgrobj->base.handle; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, - &f, sizeof(f)); - } - free(nvgrobj); -} - diff --git a/src/gallium/winsys/drm/nouveau/nouveau_local.h b/src/gallium/winsys/drm/nouveau/nouveau_local.h deleted file mode 100644 index e878a40803..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_local.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef __NOUVEAU_LOCAL_H__ -#define __NOUVEAU_LOCAL_H__ - -#include "pipe/p_compiler.h" -#include "nouveau_winsys_pipe.h" -#include - -struct pipe_buffer; - -/* Debug output */ -#define NOUVEAU_MSG(fmt, args...) do { \ - fprintf(stdout, "nouveau: "fmt, ##args); \ - fflush(stdout); \ -} while(0) - -#define NOUVEAU_ERR(fmt, args...) do { \ - fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); \ - fflush(stderr); \ -} while(0) - -#define NOUVEAU_TIME_MSEC() 0 - -/* User FIFO control */ -//#define NOUVEAU_DMA_TRACE -//#define NOUVEAU_DMA_DEBUG -//#define NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF -#define NOUVEAU_DMA_BARRIER -#define NOUVEAU_DMA_TIMEOUT 2000 - -/* Push buffer access macros */ -static INLINE void -OUT_RING(struct nouveau_channel *chan, unsigned data) -{ - *(chan->pushbuf->cur++) = (data); -} - -static INLINE void -OUT_RINGp(struct nouveau_channel *chan, uint32_t *data, unsigned size) -{ - memcpy(chan->pushbuf->cur, data, size * 4); - chan->pushbuf->cur += size; -} - -static INLINE void -OUT_RINGf(struct nouveau_channel *chan, float f) -{ - union { uint32_t i; float f; } c; - c.f = f; - OUT_RING(chan, c.i); -} - -static INLINE void -BEGIN_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, - unsigned mthd, unsigned size) -{ - if (chan->pushbuf->remaining < (size + 1)) - nouveau_pushbuf_flush(chan, (size + 1)); - OUT_RING(chan, (gr->subc << 13) | (size << 18) | mthd); - chan->pushbuf->remaining -= (size + 1); -} - -static INLINE void -FIRE_RING(struct nouveau_channel *chan) -{ - nouveau_pushbuf_flush(chan, 0); -} - -static INLINE void -BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc) -{ - gr->subc = subc; - BEGIN_RING(chan, gr, 0x0000, 1); - OUT_RING (chan, gr->handle); -} - -static INLINE void -OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned data, unsigned flags, unsigned vor, unsigned tor) -{ - nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, - data, flags, vor, tor); -} - -/* Raw data + flags depending on FB/TT buffer */ -static INLINE void -OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned data, unsigned flags, unsigned vor, unsigned tor) -{ - OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor); -} - -/* FB/TT object handle */ -static INLINE void -OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned flags) -{ - OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR, - chan->vram->handle, chan->gart->handle); -} - -/* Low 32-bits of offset */ -static INLINE void -OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned delta, unsigned flags) -{ - OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0); -} - -/* High 32-bits of offset */ -static INLINE void -OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned delta, unsigned flags) -{ - OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); -} - -#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_lock.c b/src/gallium/winsys/drm/nouveau/nouveau_lock.c deleted file mode 100644 index 9adb9ac854..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_lock.c +++ /dev/null @@ -1,94 +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 "main/glheader.h" -#include "glapi/glthread.h" -#include - -#include "nouveau_context.h" -#include "nouveau_screen.h" - -_glthread_DECLARE_STATIC_MUTEX( lockMutex ); - -static void -nouveau_contended_lock(struct nouveau_context *nv, GLuint flags) -{ - __DRIdrawablePrivate *dPriv = nv->dri_drawable; - __DRIscreenPrivate *sPriv = nv->dri_screen; - struct nouveau_screen *nv_screen = nv->nv_screen; - struct nouveau_device *dev = nv_screen->device; - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - drmGetLock(nvdev->fd, nvdev->ctx, flags); - - /* 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); -} - -/* Lock the hardware and validate our state. - */ -void -LOCK_HARDWARE(struct nouveau_context *nv) -{ - struct nouveau_screen *nv_screen = nv->nv_screen; - struct nouveau_device *dev = nv_screen->device; - struct nouveau_device_priv *nvdev = nouveau_device(dev); - char __ret=0; - - _glthread_LOCK_MUTEX(lockMutex); - assert(!nv->locked); - - DRM_CAS(nvdev->lock, nvdev->ctx, - (DRM_LOCK_HELD | nvdev->ctx), __ret); - - if (__ret) - nouveau_contended_lock(nv, 0); - nv->locked = GL_TRUE; -} - - - /* Unlock the hardware using the global current context - */ -void -UNLOCK_HARDWARE(struct nouveau_context *nv) -{ - struct nouveau_screen *nv_screen = nv->nv_screen; - struct nouveau_device *dev = nv_screen->device; - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - assert(nv->locked); - nv->locked = GL_FALSE; - - DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx); - - _glthread_UNLOCK_MUTEX(lockMutex); -} diff --git a/src/gallium/winsys/drm/nouveau/nouveau_notifier.c b/src/gallium/winsys/drm/nouveau/nouveau_notifier.c deleted file mode 100644 index 01e8f38440..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_notifier.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include - -#include "nouveau_drmif.h" -#include "nouveau_local.h" - -#define NOTIFIER(__v) \ - struct nouveau_notifier_priv *nvnotify = nouveau_notifier(notifier); \ - volatile uint32_t *__v = (void*)nvnotify->map + (id * 32) - -int -nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, - int count, struct nouveau_notifier **notifier) -{ - struct nouveau_notifier_priv *nvnotify; - int ret; - - if (!chan || !notifier || *notifier) - return -EINVAL; - - nvnotify = calloc(1, sizeof(struct nouveau_notifier_priv)); - if (!nvnotify) - return -ENOMEM; - nvnotify->base.channel = chan; - nvnotify->base.handle = handle; - - nvnotify->drm.channel = chan->id; - nvnotify->drm.handle = handle; - nvnotify->drm.count = count; - if ((ret = drmCommandWriteRead(nouveau_device(chan->device)->fd, - DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, - &nvnotify->drm, - sizeof(nvnotify->drm)))) { - nouveau_notifier_free((void *)&nvnotify); - return ret; - } - - nvnotify->map = (void *)nouveau_channel(chan)->notifier_block + - nvnotify->drm.offset; - *notifier = &nvnotify->base; - return 0; -} - -void -nouveau_notifier_free(struct nouveau_notifier **notifier) -{ - - struct nouveau_notifier_priv *nvnotify; - struct nouveau_channel_priv *nvchan; - struct nouveau_device_priv *nvdev; - struct drm_nouveau_gpuobj_free f; - - if (!notifier || !*notifier) - return; - nvnotify = nouveau_notifier(*notifier); - *notifier = NULL; - - nvchan = nouveau_channel(nvnotify->base.channel); - nvdev = nouveau_device(nvchan->base.device); - - f.channel = nvchan->drm.channel; - f.handle = nvnotify->base.handle; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, &f, sizeof(f)); - free(nvnotify); -} - -void -nouveau_notifier_reset(struct nouveau_notifier *notifier, int id) -{ - NOTIFIER(n); - - n[NV_NOTIFY_TIME_0 /4] = 0x00000000; - n[NV_NOTIFY_TIME_1 /4] = 0x00000000; - n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000; - n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS << - NV_NOTIFY_STATE_STATUS_SHIFT); -} - -uint32_t -nouveau_notifier_status(struct nouveau_notifier *notifier, int id) -{ - NOTIFIER(n); - - return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; -} - -uint32_t -nouveau_notifier_return_val(struct nouveau_notifier *notifier, int id) -{ - NOTIFIER(n); - - return n[NV_NOTIFY_RETURN_VALUE/4]; -} - -int -nouveau_notifier_wait_status(struct nouveau_notifier *notifier, int id, - int status, int timeout) -{ - NOTIFIER(n); - uint32_t time = 0, t_start = NOUVEAU_TIME_MSEC(); - - while (time <= timeout) { - uint32_t v; - - v = n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; - if (v == status) - return 0; - - if (timeout) - time = NOUVEAU_TIME_MSEC() - t_start; - } - - return -EBUSY; -} - diff --git a/src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c deleted file mode 100644 index 815046ba85..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" - -#define PB_BUFMGR_DWORDS (4096 / 2) -#define PB_MIN_USER_DWORDS 2048 - -static int -nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; - - assert((min + 1) <= nvchan->dma->max); - - /* Wait for enough space in push buffer */ - min = min < PB_MIN_USER_DWORDS ? PB_MIN_USER_DWORDS : min; - min += 1; /* a bit extra for the NOP */ - if (nvchan->dma->free < min) - WAIT_RING_CH(chan, min); - - /* Insert NOP, may turn into a jump later */ - RING_SPACE_CH(chan, 1); - nvpb->nop_jump = nvchan->dma->cur; - OUT_RING_CH(chan, 0); - - /* Any remaining space is available to the user */ - nvpb->start = nvchan->dma->cur; - nvpb->size = nvchan->dma->free; - nvpb->base.channel = chan; - nvpb->base.remaining = nvpb->size; - nvpb->base.cur = &nvchan->pushbuf[nvpb->start]; - - /* Create a new fence object for this "frame" */ - nouveau_fence_ref(NULL, &nvpb->fence); - nouveau_fence_new(chan, &nvpb->fence); - - return 0; -} - -int -nouveau_pushbuf_init(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *m = &nvchan->dma_master; - struct nouveau_dma_priv *b = &nvchan->dma_bufmgr; - int i; - - if (!nvchan) - return -EINVAL; - - /* Reassign last bit of push buffer for a "separate" bufmgr - * ring buffer - */ - m->max -= PB_BUFMGR_DWORDS; - m->free -= PB_BUFMGR_DWORDS; - - b->base = m->base + ((m->max + 2) << 2); - b->max = PB_BUFMGR_DWORDS - 2; - b->cur = b->put = 0; - b->free = b->max - b->cur; - - /* Some NOPs just to be safe - *XXX: RING_SKIPS - */ - nvchan->dma = b; - RING_SPACE_CH(chan, 8); - for (i = 0; i < 8; i++) - OUT_RING_CH(chan, 0); - nvchan->dma = m; - - nouveau_pushbuf_space(chan, 0); - chan->pushbuf = &nvchan->pb.base; - - nvchan->pb.buffers = calloc(NOUVEAU_PUSHBUF_MAX_BUFFERS, - sizeof(struct nouveau_pushbuf_bo)); - nvchan->pb.relocs = calloc(NOUVEAU_PUSHBUF_MAX_RELOCS, - sizeof(struct nouveau_pushbuf_reloc)); - return 0; -} - -static uint32_t -nouveau_pushbuf_calc_reloc(struct nouveau_bo *bo, - struct nouveau_pushbuf_reloc *r) -{ - uint32_t push; - - if (r->flags & NOUVEAU_BO_LOW) { - push = bo->offset + r->data; - } else - if (r->flags & NOUVEAU_BO_HIGH) { - push = (bo->offset + r->data) >> 32; - } else { - push = r->data; - } - - if (r->flags & NOUVEAU_BO_OR) { - if (bo->flags & NOUVEAU_BO_VRAM) - push |= r->vor; - else - push |= r->tor; - } - - return push; -} - -/* This would be our TTM "superioctl" */ -int -nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; - int ret, i; - - if (nvpb->base.remaining == nvpb->size) - return 0; - - nouveau_fence_flush(chan); - - nvpb->size -= nvpb->base.remaining; - nvchan->dma->cur += nvpb->size; - nvchan->dma->free -= nvpb->size; - assert(nvchan->dma->cur <= nvchan->dma->max); - - nvchan->dma = &nvchan->dma_bufmgr; - nvchan->pushbuf[nvpb->nop_jump] = 0x20000000 | - (nvchan->dma->base + (nvchan->dma->cur << 2)); - - /* Validate buffers + apply relocations */ - nvchan->user_charge = 0; - for (i = 0; i < nvpb->nr_relocs; i++) { - struct nouveau_pushbuf_reloc *r = &nvpb->relocs[i]; - struct nouveau_pushbuf_bo *pbbo = r->pbbo; - struct nouveau_bo *bo = pbbo->bo; - - /* Validated, mem matches presumed, no relocation necessary */ - if (pbbo->handled & 2) { - if (!(pbbo->handled & 1)) - assert(0); - continue; - } - - /* Not yet validated, do it now */ - if (!(pbbo->handled & 1)) { - ret = nouveau_bo_validate(chan, bo, pbbo->flags); - if (ret) { - assert(0); - return ret; - } - pbbo->handled |= 1; - - if (bo->offset == nouveau_bo(bo)->offset && - bo->flags == nouveau_bo(bo)->flags) { - pbbo->handled |= 2; - continue; - } - bo->offset = nouveau_bo(bo)->offset; - bo->flags = nouveau_bo(bo)->flags; - } - - /* Apply the relocation */ - *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); - } - nvpb->nr_relocs = 0; - - /* Dereference all buffers on validate list */ - for (i = 0; i < nvpb->nr_buffers; i++) { - struct nouveau_pushbuf_bo *pbbo = &nvpb->buffers[i]; - - nouveau_bo(pbbo->bo)->pending = NULL; - nouveau_bo_del(&pbbo->bo); - } - nvpb->nr_buffers = 0; - - /* Switch back to user's ring */ - RING_SPACE_CH(chan, 1); - OUT_RING_CH(chan, 0x20000000 | ((nvpb->start << 2) + - nvchan->dma_master.base)); - nvchan->dma = &nvchan->dma_master; - - /* Fence + kickoff */ - nouveau_fence_emit(nvpb->fence); - FIRE_RING_CH(chan); - - /* Allocate space for next push buffer */ - ret = nouveau_pushbuf_space(chan, min); - assert(!ret); - - return 0; -} - -static struct nouveau_pushbuf_bo * -nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) -{ - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_pushbuf_bo *pbbo; - - if (nvbo->pending) - return nvbo->pending; - - if (nvpb->nr_buffers >= NOUVEAU_PUSHBUF_MAX_BUFFERS) - return NULL; - pbbo = nvpb->buffers + nvpb->nr_buffers++; - nvbo->pending = pbbo; - - nouveau_bo_ref(bo->device, bo->handle, &pbbo->bo); - pbbo->channel = chan; - pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; - pbbo->handled = 0; - return pbbo; -} - -int -nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, - struct nouveau_bo *bo, uint32_t data, uint32_t flags, - uint32_t vor, uint32_t tor) -{ - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); - struct nouveau_pushbuf_bo *pbbo; - struct nouveau_pushbuf_reloc *r; - - if (nvpb->nr_relocs >= NOUVEAU_PUSHBUF_MAX_RELOCS) - return -ENOMEM; - - pbbo = nouveau_pushbuf_emit_buffer(chan, bo); - if (!pbbo) - return -ENOMEM; - pbbo->flags |= (flags & NOUVEAU_BO_RDWR); - pbbo->flags &= (flags | NOUVEAU_BO_RDWR); - - r = nvpb->relocs + nvpb->nr_relocs++; - r->pbbo = pbbo; - r->ptr = ptr; - r->flags = flags; - r->data = data; - r->vor = vor; - r->tor = tor; - - if (flags & NOUVEAU_BO_DUMMY) - *(uint32_t *)ptr = 0; - else - *(uint32_t *)ptr = nouveau_pushbuf_calc_reloc(bo, r); - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/nouveau_resource.c b/src/gallium/winsys/drm/nouveau/nouveau_resource.c deleted file mode 100644 index 3bbcb5c45e..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_resource.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include - -#include "nouveau_drmif.h" -#include "nouveau_local.h" - -int -nouveau_resource_init(struct nouveau_resource **heap, - unsigned start, unsigned size) -{ - struct nouveau_resource *r; - - r = calloc(1, sizeof(struct nouveau_resource)); - if (!r) - return 1; - - r->start = start; - r->size = size; - *heap = r; - return 0; -} - -int -nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, - struct nouveau_resource **res) -{ - struct nouveau_resource *r; - - if (!heap || !size || !res || *res) - return 1; - - while (heap) { - if (!heap->in_use && heap->size >= size) { - r = calloc(1, sizeof(struct nouveau_resource)); - if (!r) - return 1; - - r->start = (heap->start + heap->size) - size; - r->size = size; - r->in_use = 1; - r->priv = priv; - - heap->size -= size; - - r->next = heap->next; - if (heap->next) - heap->next->prev = r; - r->prev = heap; - heap->next = r; - - *res = r; - return 0; - } - - heap = heap->next; - } - - return 1; -} - -void -nouveau_resource_free(struct nouveau_resource **res) -{ - struct nouveau_resource *r; - - if (!res || !*res) - return; - r = *res; - *res = NULL; - - r->in_use = 0; - - if (r->next && !r->next->in_use) { - struct nouveau_resource *new = r->next; - - new->prev = r->prev; - if (r->prev) - r->prev->next = new; - new->size += r->size; - new->start = r->start; - - free(r); - r = new; - } - - if (r->prev && !r->prev->in_use) { - r->prev->next = r->next; - if (r->next) - r->next->prev = r->prev; - r->prev->size += r->size; - free(r); - } - -} diff --git a/src/gallium/winsys/drm/nouveau/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/nouveau_screen.c deleted file mode 100644 index c6d0c53588..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_screen.c +++ /dev/null @@ -1,265 +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 "nouveau_context.h" -#include "nouveau_drm.h" -#include "nouveau_dri.h" -#include "nouveau_local.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" - -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 -#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 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 }; - int ret; - - 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 GL_FALSE; - } - - nv_screen = CALLOC_STRUCT(nouveau_screen); - if (!nv_screen) - return GL_FALSE; - nv_screen->driScrnPriv = psp; - psp->private = (void *)nv_screen; - - driParseOptionInfo(&nv_screen->option_cache, - __driConfigOptions, __driNConfigOptions); - - if ((ret = nouveau_device_open_existing(&nv_screen->device, 0, - psp->fd, 0))) { - NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret); - return GL_FALSE; - } - - nv_screen->front_offset = nv_dri->front_offset; - nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8); - nv_screen->front_cpp = nv_dri->bpp / 8; - nv_screen->front_height = nv_dri->height; - - 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/nouveau_screen.h b/src/gallium/winsys/drm/nouveau/nouveau_screen.h deleted file mode 100644 index 388d6be9bb..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_screen.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __NOUVEAU_SCREEN_H__ -#define __NOUVEAU_SCREEN_H__ - -#include "xmlconfig.h" - -struct nouveau_screen { - __DRIscreenPrivate *driScrnPriv; - driOptionCache option_cache; - - struct nouveau_device *device; - - uint32_t front_offset; - uint32_t front_pitch; - uint32_t front_cpp; - uint32_t front_height; - - void *nvc; -}; - -#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c deleted file mode 100644 index 70e0104e83..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c +++ /dev/null @@ -1,86 +0,0 @@ -#include "main/glheader.h" -#include "glapi/glthread.h" -#include - -#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_local.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" - -void -nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, - const drm_clip_rect_t *rect) -{ - struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate; - drm_clip_rect_t *pbox; - int nbox, i; - - LOCK_HARDWARE(nv); - if (!dPriv->numClipRects) { - UNLOCK_HARDWARE(nv); - return; - } - pbox = dPriv->pClipRects; - nbox = dPriv->numClipRects; - - nv->surface_copy_prep(nv, nv->frontbuffer, surf); - 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; - - nv->surface_copy(nv, dx, dy, sx, sy, w, h); - } - - FIRE_RING(nv->nvc->channel); - 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; - - surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); - 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; - - surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); - if (surf) { - st_notify_swapbuffers(nvfb->stfb); - nouveau_copy_buffer(dPriv, surf, NULL); - } -} - diff --git a/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h b/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h deleted file mode 100644 index 825d3da6da..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __NOUVEAU_SWAPBUFFERS_H__ -#define __NOUVEAU_SWAPBUFFERS_H__ - -extern void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *, - const drm_clip_rect_t *); -extern void nouveau_copy_sub_buffer(__DRIdrawablePrivate *, - int x, int y, int w, int h); -extern void nouveau_swap_buffers(__DRIdrawablePrivate *); - -#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys.c deleted file mode 100644 index 364340e1d3..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_winsys.c +++ /dev/null @@ -1,161 +0,0 @@ -#include "util/u_memory.h" - -#include "nouveau_context.h" -#include "nouveau_screen.h" -#include "nouveau_winsys_pipe.h" - -#include "nouveau/nouveau_winsys.h" - -static int -nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count, - struct nouveau_notifier **notify) -{ - struct nouveau_context *nv = nvws->nv; - - return nouveau_notifier_alloc(nv->nvc->channel, nv->nvc->next_handle++, - count, notify); -} - -static int -nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass, - struct nouveau_grobj **grobj) -{ - struct nouveau_context *nv = nvws->nv; - struct nouveau_channel *chan = nv->nvc->channel; - int ret; - - ret = nouveau_grobj_alloc(chan, nv->nvc->next_handle++, - grclass, grobj); - if (ret) - return ret; - - assert(nv->nvc->next_subchannel < 7); - BIND_RING(chan, *grobj, nv->nvc->next_subchannel++); - return 0; -} - -static int -nouveau_pipe_surface_copy(struct nouveau_winsys *nvws, struct pipe_surface *dst, - unsigned dx, unsigned dy, struct pipe_surface *src, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_context *nv = nvws->nv; - - if (nv->surface_copy_prep(nv, dst, src)) - return 1; - nv->surface_copy(nv, dx, dy, sx, sy, w, h); - nv->surface_copy_done(nv); - - return 0; -} - -static int -nouveau_pipe_surface_fill(struct nouveau_winsys *nvws, struct pipe_surface *dst, - unsigned dx, unsigned dy, unsigned w, unsigned h, - unsigned value) -{ - if (nvws->nv->surface_fill(nvws->nv, dst, dx, dy, w, h, value)) - return 1; - 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) -{ - return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, - nouveau_buffer(buf)->bo, - data, flags, vor, tor); -} - -static int -nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size, - struct pipe_fence_handle **fence) -{ - if (fence) { - struct nouveau_pushbuf *pb = nvws->channel->pushbuf; - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(pb); - struct nouveau_fence *ref = NULL; - - nouveau_fence_ref(nvpb->fence, &ref); - *fence = (struct pipe_fence_handle *)ref; - } - - return nouveau_pushbuf_flush(nvws->channel, size); -} - -struct pipe_context * -nouveau_pipe_create(struct nouveau_context *nv) -{ - struct nouveau_channel_context *nvc = nv->nvc; - struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); - struct pipe_screen *(*hws_create)(struct pipe_winsys *, - struct nouveau_winsys *); - struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); - struct pipe_winsys *ws; - unsigned chipset = nv->nv_screen->device->chipset; - - if (!nvws) - return NULL; - - switch (chipset & 0xf0) { - case 0x10: - hws_create = nv10_screen_create; - hw_create = nv10_create; - break; - case 0x20: - hws_create = nv20_screen_create; - hw_create = nv20_create; - break; - case 0x30: - hws_create = nv30_screen_create; - hw_create = nv30_create; - break; - case 0x40: - case 0x60: - hws_create = nv40_screen_create; - hw_create = nv40_create; - break; - case 0x50: - case 0x80: - case 0x90: - hws_create = nv50_screen_create; - hw_create = nv50_create; - break; - default: - NOUVEAU_ERR("Unknown chipset NV%02x\n", chipset); - return NULL; - } - - nvws->nv = nv; - nvws->channel = nv->nvc->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->surface_copy = nouveau_pipe_surface_copy; - nvws->surface_fill = nouveau_pipe_surface_fill; - - ws = nouveau_create_pipe_winsys(nv); - - if (!nvc->pscreen) - nvc->pscreen = hws_create(ws, nvws); - nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id); - return nvc->pctx[nv->pctx_id]; -} - diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c deleted file mode 100644 index fe10479db7..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c +++ /dev/null @@ -1,207 +0,0 @@ -#include "pipe/p_winsys.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" - -#include "util/u_memory.h" - -#include "nouveau_context.h" -#include "nouveau_local.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" -#include "nouveau_winsys_pipe.h" - -static void -nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, - void *context_private) -{ - struct nouveau_context *nv = context_private; - __DRIdrawablePrivate *dPriv = nv->dri_drawable; - - nouveau_copy_buffer(dPriv, surf, NULL); -} - -static const char * -nouveau_get_name(struct pipe_winsys *pws) -{ - return "Nouveau/DRI"; -} - -static struct pipe_buffer * -nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, - unsigned usage, unsigned size) -{ - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; - struct nouveau_context *nv = nvpws->nv; - struct nouveau_device *dev = nv->nv_screen->device; - struct nouveau_pipe_buffer *nvbuf; - uint32_t flags; - - nvbuf = calloc(1, sizeof(*nvbuf)); - if (!nvbuf) - return NULL; - nvbuf->base.refcount = 1; - nvbuf->base.alignment = alignment; - nvbuf->base.usage = usage; - nvbuf->base.size = size; - - flags = NOUVEAU_BO_LOCAL; - - 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 (dev->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 (nv->cap.hw_vertex_buffer) - flags |= NOUVEAU_BO_GART; - } - - if (usage & PIPE_BUFFER_USAGE_INDEX) { - if (nv->cap.hw_index_buffer) - flags |= NOUVEAU_BO_GART; - } - - 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 *pws, void *ptr, unsigned bytes) -{ - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; - struct nouveau_device *dev = nvpws->nv->nv_screen->device; - struct nouveau_pipe_buffer *nvbuf; - - nvbuf = calloc(1, sizeof(*nvbuf)); - if (!nvbuf) - return NULL; - nvbuf->base.refcount = 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_winsys *ws, struct pipe_buffer *buf) -{ - struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); - - nouveau_bo_del(&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_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_buffer(buf); - - nouveau_bo_unmap(nvbuf->bo); -} - -static INLINE struct nouveau_fence * -nouveau_pipe_fence(struct pipe_fence_handle *pfence) -{ - return (struct nouveau_fence *)pfence; -} - -static void -nouveau_pipe_fence_reference(struct pipe_winsys *ws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *pfence) -{ - nouveau_fence_ref((void *)pfence, (void *)ptr); -} - -static int -nouveau_pipe_fence_signalled(struct pipe_winsys *ws, - struct pipe_fence_handle *pfence, unsigned flag) -{ - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)ws; - struct nouveau_fence *fence = nouveau_pipe_fence(pfence); - - if (nouveau_fence(fence)->signalled == 0) - nouveau_fence_flush(nvpws->nv->nvc->channel); - - return !nouveau_fence(fence)->signalled; -} - -static int -nouveau_pipe_fence_finish(struct pipe_winsys *ws, - struct pipe_fence_handle *pfence, unsigned flag) -{ - struct nouveau_fence *fence = nouveau_pipe_fence(pfence); - struct nouveau_fence *ref = NULL; - - nouveau_fence_ref(fence, &ref); - return nouveau_fence_wait(&ref); -} - -struct pipe_winsys * -nouveau_create_pipe_winsys(struct nouveau_context *nv) -{ - struct nouveau_pipe_winsys *nvpws; - struct pipe_winsys *pws; - - nvpws = CALLOC_STRUCT(nouveau_pipe_winsys); - if (!nvpws) - return NULL; - nvpws->nv = nv; - pws = &nvpws->pws; - - pws->flush_frontbuffer = nouveau_flush_frontbuffer; - - pws->buffer_create = nouveau_pipe_bo_create; - pws->buffer_destroy = nouveau_pipe_bo_del; - pws->user_buffer_create = nouveau_pipe_bo_user_create; - pws->buffer_map = nouveau_pipe_bo_map; - pws->buffer_unmap = nouveau_pipe_bo_unmap; - - pws->fence_reference = nouveau_pipe_fence_reference; - pws->fence_signalled = nouveau_pipe_fence_signalled; - pws->fence_finish = nouveau_pipe_fence_finish; - - pws->get_name = nouveau_get_name; - - return &nvpws->pws; -} - diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h deleted file mode 100644 index 6a03ac0d77..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef NOUVEAU_PIPE_WINSYS_H -#define NOUVEAU_PIPE_WINSYS_H - -#include "pipe/p_context.h" -#include "pipe/p_winsys.h" -#include "nouveau_context.h" - -struct nouveau_pipe_buffer { - struct pipe_buffer base; - struct nouveau_bo *bo; -}; - -static inline struct nouveau_pipe_buffer * -nouveau_buffer(struct pipe_buffer *buf) -{ - return (struct nouveau_pipe_buffer *)buf; -} - -struct nouveau_pipe_winsys { - struct pipe_winsys pws; - - struct nouveau_context *nv; -}; - -extern struct pipe_winsys * -nouveau_create_pipe_winsys(struct nouveau_context *nv); - -struct pipe_context * -nouveau_create_softpipe(struct nouveau_context *nv); - -struct pipe_context * -nouveau_pipe_create(struct nouveau_context *nv); - -#endif diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c deleted file mode 100644 index 68aade829d..0000000000 --- a/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c +++ /dev/null @@ -1,86 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include "imports.h" - -#include "pipe/p_defines.h" -#include "pipe/p_format.h" -#include "softpipe/sp_winsys.h" - -#include "nouveau_context.h" -#include "nouveau_winsys_pipe.h" - -struct nouveau_softpipe_winsys { - struct softpipe_winsys sws; - struct nouveau_context *nv; -}; - -/** - * Return list of surface formats supported by this driver. - */ -static boolean -nouveau_is_format_supported(struct softpipe_winsys *sws, - enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return TRUE; - default: - break; - }; - - return FALSE; -} - -struct pipe_context * -nouveau_create_softpipe(struct nouveau_context *nv) -{ - struct nouveau_softpipe_winsys *nvsws; - struct pipe_screen *pscreen; - struct pipe_winsys *ws; - - ws = nouveau_create_pipe_winsys(nv); - if (!ws) - return NULL; - pscreen = softpipe_create_screen(ws); - - nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys); - if (!nvsws) - return NULL; - - nvsws->sws.is_format_supported = nouveau_is_format_supported; - nvsws->nv = nv; - - return softpipe_create(pscreen, ws, &nvsws->sws); -} - diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c deleted file mode 100644 index e9a8a2ac1c..0000000000 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ /dev/null @@ -1,466 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_format.h" - -#include "nouveau_context.h" - -static INLINE int log2i(int i) -{ - int r = 0; - - if (i & 0xffff0000) { - i >>= 16; - r += 16; - } - if (i & 0x0000ff00) { - i >>= 8; - r += 8; - } - if (i & 0x000000f0) { - i >>= 4; - r += 4; - } - if (i & 0x0000000c) { - i >>= 2; - r += 2; - } - if (i & 0x00000002) { - r += 1; - } - return r; -} - -static INLINE int -nv04_surface_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; - case PIPE_FORMAT_R16_SNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_A8R8G8B8_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8; - case PIPE_FORMAT_Z24S8_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; - default: - return -1; - } -} - -static INLINE int -nv04_rect_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; - case PIPE_FORMAT_R5G6B5_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; - default: - return -1; - } -} - -static INLINE int -nv04_scaled_image_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A1R5G5B5_UNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5; - case PIPE_FORMAT_A8R8G8B8_UNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; - case PIPE_FORMAT_X8R8G8B8_UNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8; - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_R16_SNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; - default: - return -1; - } -} - -static INLINE unsigned -nv04_swizzle_bits(unsigned x, unsigned y) -{ - unsigned u = (x & 0x001) << 0 | - (x & 0x002) << 1 | - (x & 0x004) << 2 | - (x & 0x008) << 3 | - (x & 0x010) << 4 | - (x & 0x020) << 5 | - (x & 0x040) << 6 | - (x & 0x080) << 7 | - (x & 0x100) << 8 | - (x & 0x200) << 9 | - (x & 0x400) << 10 | - (x & 0x800) << 11; - - unsigned v = (y & 0x001) << 1 | - (y & 0x002) << 2 | - (y & 0x004) << 3 | - (y & 0x008) << 4 | - (y & 0x010) << 5 | - (y & 0x020) << 6 | - (y & 0x040) << 7 | - (y & 0x080) << 8 | - (y & 0x100) << 9 | - (y & 0x200) << 10 | - (y & 0x400) << 11 | - (y & 0x800) << 12; - return v | u; -} - -static void -nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct pipe_surface *dst = nv->surf_dst; - struct pipe_surface *src = nv->surf_src; - - const unsigned max_w = 1024; - const unsigned max_h = 1024; - const unsigned sub_w = w > max_w ? max_w : w; - const unsigned sub_h = h > max_h ? max_h : h; - unsigned cx = 0; - unsigned cy = 0; - - /* POT or GTFO */ - assert(!(w & (w - 1)) && !(h & (h - 1))); - - BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); - OUT_RING (chan, nv04_surface_format(dst->format) | - log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT | - log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); - - BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); - OUT_RING (chan, nv->nvc->NvSwzSurf->handle); - - for (cy = 0; cy < h; cy += sub_h) { - for (cx = 0; cx < w; cx += sub_w) { - BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_OFFSET, 1); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, - dst->offset + nv04_swizzle_bits(cx, cy) * dst->block.size, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); - OUT_RING (chan, nv04_scaled_image_format(src->format)); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); - OUT_RING (chan, 0); - OUT_RING (chan, sub_h << 16 | sub_w); - OUT_RING (chan, 0); - OUT_RING (chan, sub_h << 16 | sub_w); - OUT_RING (chan, 1 << 20); - OUT_RING (chan, 1 << 20); - - BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); - OUT_RING (chan, sub_h << 16 | sub_w); - OUT_RING (chan, src->stride | - NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | - NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, - src->offset + cy * src->stride + cx * src->block.size, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, 0); - } - } -} - -static void -nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct pipe_surface *dst = nv->surf_dst; - struct pipe_surface *src = nv->surf_src; - unsigned dst_offset, src_offset; - - dst_offset = dst->offset + (dy * dst->stride) + (dx * dst->block.size); - src_offset = src->offset + (sy * src->stride) + (sx * src->block.size); - - while (h) { - int count = (h > 2047) ? 2047 : h; - - BEGIN_RING(chan, nv->nvc->NvM2MF, - NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src_offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst_offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RING (chan, src->stride); - OUT_RING (chan, dst->stride); - OUT_RING (chan, w * src->block.size); - OUT_RING (chan, count); - OUT_RING (chan, 0x0101); - OUT_RING (chan, 0); - - h -= count; - src_offset += src->stride * count; - dst_offset += dst->stride * count; - } -} - -static void -nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_channel *chan = nv->nvc->channel; - - BEGIN_RING(chan, nv->nvc->NvImageBlit, 0x0300, 3); - OUT_RING (chan, (sy << 16) | sx); - OUT_RING (chan, (dy << 16) | dx); - OUT_RING (chan, ( h << 16) | w); -} - -static int -nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, - struct pipe_surface *src) -{ - struct nouveau_channel *chan = nv->nvc->channel; - int format; - - if (src->format != dst->format) - return 1; - - /* Setup transfer to swizzle the texture to vram if needed */ - /* FIXME/TODO: check proper limits of this operation */ - if (src->texture && dst->texture) { - unsigned int src_linear = src->texture->tex_usage & - NOUVEAU_TEXTURE_USAGE_LINEAR; - unsigned int dst_linear = dst->texture->tex_usage & - NOUVEAU_TEXTURE_USAGE_LINEAR; - if (src_linear ^ dst_linear) { - nv->surface_copy = nv04_surface_copy_swizzle; - nv->surf_dst = dst; - nv->surf_src = src; - return 0; - } - } - - /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback - * to NV_MEMORY_TO_MEMORY_FORMAT in this case. - */ - if ((src->offset & 63) || (dst->offset & 63)) { - BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF, - NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - nv->surface_copy = nv04_surface_copy_m2mf; - nv->surf_dst = dst; - nv->surf_src = src; - return 0; - - } - - if ((format = nv04_surface_format(dst->format)) < 0) { - NOUVEAU_ERR("Bad surface format 0x%x\n", dst->format); - return 1; - } - nv->surface_copy = nv04_surface_copy_blit; - - BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, - NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, - NV04_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (chan, format); - OUT_RING (chan, (dst->stride << 16) | src->stride); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - return 0; -} - -static void -nv04_surface_copy_done(struct nouveau_context *nv) -{ - FIRE_RING(nv->nvc->channel); -} - -static int -nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, - unsigned dx, unsigned dy, unsigned w, unsigned h, - unsigned value) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *surf2d = nv->nvc->NvCtxSurf2D; - struct nouveau_grobj *rect = nv->nvc->NvGdiRect; - int cs2d_format, gdirect_format; - - if ((cs2d_format = nv04_surface_format(dst->format)) < 0) { - NOUVEAU_ERR("Bad format = %d\n", dst->format); - return 1; - } - - if ((gdirect_format = nv04_rect_format(dst->format)) < 0) { - NOUVEAU_ERR("Bad format = %d\n", dst->format); - return 1; - } - - BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (chan, cs2d_format); - OUT_RING (chan, (dst->stride << 16) | dst->stride); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); - OUT_RING (chan, gdirect_format); - BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); - OUT_RING (chan, value); - BEGIN_RING(chan, rect, - NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); - OUT_RING (chan, (dx << 16) | dy); - OUT_RING (chan, ( w << 16) | h); - - FIRE_RING(chan); - return 0; -} - -int -nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) -{ - struct nouveau_channel *chan = nvc->channel; - unsigned chipset = nvc->channel->device->chipset, class; - int ret; - - if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, 0x39, - &nvc->NvM2MF))) { - NOUVEAU_ERR("Error creating m2mf object: %d\n", ret); - return 1; - } - BIND_RING (chan, nvc->NvM2MF, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvM2MF, - NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - - class = chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : - NV10_CONTEXT_SURFACES_2D; - if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvCtxSurf2D))) { - NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); - return 1; - } - BIND_RING (chan, nvc->NvCtxSurf2D, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvCtxSurf2D, - NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RING (chan, nvc->channel->vram->handle); - OUT_RING (chan, nvc->channel->vram->handle); - - class = chipset < 0x10 ? NV04_IMAGE_BLIT : NV12_IMAGE_BLIT; - if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvImageBlit))) { - NOUVEAU_ERR("Error creating blit object: %d\n", ret); - return 1; - } - BIND_RING (chan, nvc->NvImageBlit, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); - OUT_RING (chan, nvc->NvCtxSurf2D->handle); - BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); - OUT_RING (chan, NV04_IMAGE_BLIT_OPERATION_SRCCOPY); - - class = NV04_GDI_RECTANGLE_TEXT; - if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvGdiRect))) { - NOUVEAU_ERR("Error creating rect object: %d\n", ret); - return 1; - } - BIND_RING (chan, nvc->NvGdiRect, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); - OUT_RING (chan, nvc->NvCtxSurf2D->handle); - BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); - OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); - BEGIN_RING(chan, nvc->NvGdiRect, - NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); - OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); - - switch (chipset & 0xf0) { - case 0x00: - case 0x10: - class = NV04_SWIZZLED_SURFACE; - break; - case 0x20: - class = NV20_SWIZZLED_SURFACE; - break; - case 0x30: - class = NV30_SWIZZLED_SURFACE; - break; - case 0x40: - case 0x60: - class = NV40_SWIZZLED_SURFACE; - break; - default: - /* Famous last words: this really can't happen.. */ - assert(0); - break; - } - - ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvSwzSurf); - if (ret) { - NOUVEAU_ERR("Error creating swizzled surface: %d\n", ret); - return 1; - } - - BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); - - if (chipset < 0x10) { - class = NV04_SCALED_IMAGE_FROM_MEMORY; - } else - if (chipset < 0x40) { - class = NV10_SCALED_IMAGE_FROM_MEMORY; - } else { - class = NV40_SCALED_IMAGE_FROM_MEMORY; - } - - ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvSIFM); - if (ret) { - NOUVEAU_ERR("Error creating scaled image object: %d\n", ret); - return 1; - } - - BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); - - return 0; -} - -int -nouveau_surface_init_nv04(struct nouveau_context *nv) -{ - nv->surface_copy_prep = nv04_surface_copy_prep; - nv->surface_copy = nv04_surface_copy_blit; - nv->surface_copy_done = nv04_surface_copy_done; - nv->surface_fill = nv04_surface_fill; - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/nv50_surface.c b/src/gallium/winsys/drm/nouveau/nv50_surface.c deleted file mode 100644 index c8ab7f690f..0000000000 --- a/src/gallium/winsys/drm/nouveau/nv50_surface.c +++ /dev/null @@ -1,194 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_format.h" - -#include "nouveau_context.h" - -static INLINE int -nv50_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return NV50_2D_DST_FORMAT_32BPP; - case PIPE_FORMAT_X8R8G8B8_UNORM: - return NV50_2D_DST_FORMAT_24BPP; - case PIPE_FORMAT_R5G6B5_UNORM: - return NV50_2D_DST_FORMAT_16BPP; - case PIPE_FORMAT_A8_UNORM: - return NV50_2D_DST_FORMAT_8BPP; - default: - return -1; - } -} - -static int -nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->bo; - int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; - int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); - - surf_format = nv50_format(surf->format); - if (surf_format < 0) - return 1; - - if (!nouveau_bo(bo)->tiled) { - BEGIN_RING(chan, eng2d, mthd, 2); - OUT_RING (chan, surf_format); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, mthd + 0x14, 5); - OUT_RING (chan, surf->stride); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - OUT_RELOCh(chan, bo, surf->offset, flags); - OUT_RELOCl(chan, bo, surf->offset, flags); - } else { - BEGIN_RING(chan, eng2d, mthd, 5); - OUT_RING (chan, surf_format); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, mthd + 0x18, 4); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - OUT_RELOCh(chan, bo, surf->offset, flags); - OUT_RELOCl(chan, bo, surf->offset, flags); - } - -#if 0 - if (dst) { - BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - } -#endif - - return 0; -} - -static int -nv50_surface_copy_prep(struct nouveau_context *nv, - struct pipe_surface *dst, struct pipe_surface *src) -{ - int ret; - - assert(src->format == dst->format); - - ret = nv50_surface_set(nv, dst, 1); - if (ret) - return ret; - - ret = nv50_surface_set(nv, src, 0); - if (ret) - return ret; - - return 0; -} - -static void -nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - - BEGIN_RING(chan, eng2d, 0x088c, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4); - OUT_RING (chan, dx); - OUT_RING (chan, dy); - OUT_RING (chan, w); - OUT_RING (chan, h); - BEGIN_RING(chan, eng2d, 0x08c0, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, 0x08d0, 4); - OUT_RING (chan, 0); - OUT_RING (chan, sx); - OUT_RING (chan, 0); - OUT_RING (chan, sy); -} - -static void -nv50_surface_copy_done(struct nouveau_context *nv) -{ - FIRE_RING(nv->nvc->channel); -} - -static int -nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, - unsigned dx, unsigned dy, unsigned w, unsigned h, - unsigned value) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - int rect_format, ret; - - rect_format = nv50_format(dst->format); - if (rect_format < 0) - return 1; - - ret = nv50_surface_set(nv, dst, 1); - if (ret) - return ret; - - BEGIN_RING(chan, eng2d, 0x0580, 3); - OUT_RING (chan, 4); - OUT_RING (chan, rect_format); - OUT_RING (chan, value); - - BEGIN_RING(chan, eng2d, NV50_2D_RECT_X1, 4); - OUT_RING (chan, dx); - OUT_RING (chan, dy); - OUT_RING (chan, dx + w); - OUT_RING (chan, dy + h); - - FIRE_RING(chan); - return 0; -} - -int -nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) -{ - struct nouveau_channel *chan = nvc->channel; - struct nouveau_grobj *eng2d = NULL; - int ret; - - ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d); - if (ret) - return ret; - nvc->Nv2D = eng2d; - - BIND_RING (chan, eng2d, nvc->next_subchannel++); - BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4); - OUT_RING (chan, nvc->sync_notifier->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1); - OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); - BEGIN_RING(chan, eng2d, 0x0290, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, 0x0888, 1); - OUT_RING (chan, 1); - - return 0; -} - -int -nouveau_surface_init_nv50(struct nouveau_context *nv) -{ - nv->surface_copy_prep = nv50_surface_copy_prep; - nv->surface_copy = nv50_surface_copy; - nv->surface_copy_done = nv50_surface_copy_done; - nv->surface_fill = nv50_surface_fill; - return 0; -} - diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index ff43327778..22d925b643 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -3,35 +3,33 @@ GALLIUMDIR = ../../.. DRMDIR ?= /usr DRIDIR = ../../../../driclient -OBJECTS = nouveau_bo.o nouveau_fence.o nouveau_swapbuffers.o nouveau_channel.o \ - nouveau_grobj.o nouveau_context.o nouveau_winsys.o nouveau_lock.o \ - nouveau_winsys_pipe.o nouveau_device.o nouveau_notifier.o nouveau_dma.o \ - nouveau_pushbuf.o nouveau_resource.o nouveau_screen.o nv04_surface.o \ - nv50_surface.o #nouveau_winsys_softpipe.o - -CFLAGS += -g -Wall -fPIC \ - -I${GALLIUMDIR}/include \ - -I${GALLIUMDIR}/winsys/g3dvl \ - -I${DRMDIR}/include \ - -I${DRMDIR}/include/drm \ - -I${GALLIUMDIR}/drivers \ - -I${GALLIUMDIR}/auxiliary \ +OBJECTS = nouveau_screen_vl.o nouveau_context_vl.o nouveau_swapbuffers.o + +CFLAGS += -g -Wall -Werror=implicit-function-declaration -fPIC \ + -I${GALLIUMDIR}/include \ + -I${GALLIUMDIR}/winsys/g3dvl \ + -I${GALLIUMDIR}/winsys/drm/nouveau \ + -I${DRMDIR}/include \ + -I${DRMDIR}/include/drm \ + -I${GALLIUMDIR}/drivers \ + -I${GALLIUMDIR}/auxiliary \ -I${DRIDIR}/include -LDFLAGS += -L${DRMDIR}/lib \ - -L${DRIDIR}/lib \ - -L${GALLIUMDIR}/auxiliary/draw \ - -L${GALLIUMDIR}/auxiliary/tgsi \ - -L${GALLIUMDIR}/auxiliary/translate \ - -L${GALLIUMDIR}/auxiliary/rtasm \ - -L${GALLIUMDIR}/auxiliary/cso_cache \ - -L${GALLIUMDIR}/drivers/nv10 \ - -L${GALLIUMDIR}/drivers/nv20 \ - -L${GALLIUMDIR}/drivers/nv30 \ - -L${GALLIUMDIR}/drivers/nv40 \ +LDFLAGS += -L${DRMDIR}/lib \ + -L${DRIDIR}/lib \ + -L${GALLIUMDIR}/winsys/drm/nouveau/common \ + -L${GALLIUMDIR}/auxiliary/draw \ + -L${GALLIUMDIR}/auxiliary/tgsi \ + -L${GALLIUMDIR}/auxiliary/translate \ + -L${GALLIUMDIR}/auxiliary/rtasm \ + -L${GALLIUMDIR}/auxiliary/cso_cache \ + -L${GALLIUMDIR}/drivers/nv10 \ + -L${GALLIUMDIR}/drivers/nv20 \ + -L${GALLIUMDIR}/drivers/nv30 \ + -L${GALLIUMDIR}/drivers/nv40 \ -L${GALLIUMDIR}/drivers/nv50 -LIBS += -ldriclient -ldrm -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm +LIBS += -lnouveaudrm -ldriclient -ldrm -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm ############################################# diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c deleted file mode 100644 index 06a61fcda3..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c +++ /dev/null @@ -1,370 +0,0 @@ -#include "pipe/p_defines.h" -#include "pipe/p_context.h" -#include "pipe/p_screen.h" -#include "util/u_memory.h" - -#include "nouveau_context.h" -#include "nouveau_dri.h" -#include "nouveau_local.h" -#include "nouveau_screen.h" -#include "nouveau_winsys_pipe.h" - -/* -#ifdef DEBUG -static const struct dri_debug_control debug_control[] = { - { "bo", DEBUG_BO }, - { NULL, 0 } -}; -int __nouveau_debug = 0; -#endif -*/ - -/* - * TODO: Re-examine dri_screen, dri_context, nouveau_screen, nouveau_context - * relationships, seems like there is a lot of room for simplification there. - */ - -static void -nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) -{ - nouveau_grobj_free(&nvc->NvCtxSurf2D); - nouveau_grobj_free(&nvc->NvImageBlit); - nouveau_grobj_free(&nvc->NvGdiRect); - nouveau_grobj_free(&nvc->NvM2MF); - nouveau_grobj_free(&nvc->Nv2D); - nouveau_grobj_free(&nvc->NvSwzSurf); - nouveau_grobj_free(&nvc->NvSIFM); - - nouveau_notifier_free(&nvc->sync_notifier); - - nouveau_channel_free(&nvc->channel); - - FREE(nvc); -} - -static struct nouveau_channel_context * -nouveau_channel_context_create(struct nouveau_device *dev) -{ - struct nouveau_channel_context *nvc; - int ret; - - nvc = CALLOC_STRUCT(nouveau_channel_context); - if (!nvc) - return NULL; - - if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002, - &nvc->channel))) { - NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); - nouveau_channel_context_destroy(nvc); - return NULL; - } - - nvc->next_handle = 0x80000000; - - if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, - &nvc->sync_notifier))) { - NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); - nouveau_channel_context_destroy(nvc); - return NULL; - } - - switch (dev->chipset & 0xf0) { - case 0x50: - case 0x80: - case 0x90: - ret = nouveau_surface_channel_create_nv50(nvc); - break; - default: - ret = nouveau_surface_channel_create_nv04(nvc); - break; - } - - if (ret) { - NOUVEAU_ERR("Error initialising surface objects: %d\n", ret); - nouveau_channel_context_destroy(nvc); - return NULL; - } - - return nvc; -} - -int -nouveau_context_create(dri_context_t *dri_context) -{ - dri_screen_t *dri_screen = dri_context->dri_screen; - struct nouveau_screen *nv_screen = dri_screen->private; - struct nouveau_context *nv = CALLOC_STRUCT(nouveau_context); - struct pipe_context *pipe = NULL; - struct nouveau_channel_context *nvc = NULL; - struct nouveau_device *dev = nv_screen->device; - int i; - - switch (dev->chipset & 0xf0) { - case 0x10: - case 0x20: - /* NV10 */ - case 0x30: - /* NV30 */ - case 0x40: - case 0x60: - /* NV40 */ - case 0x50: - case 0x80: - case 0x90: - /* G80 */ - break; - default: - NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset); - return 1; - } - - dri_context->private = (void*)nv; - nv->dri_context = dri_context; - nv->nv_screen = nv_screen; - - { - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - nvdev->ctx = dri_context->drm_context; - nvdev->lock = (drmLock*)&dri_screen->sarea->lock; - } - - /* - driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, - nv->dri_screen->myNum, "nouveau"); -#ifdef DEBUG - __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"), - debug_control); -#endif - */ - - /*XXX: Hack up a fake region and buffer object for front buffer. - * This will go away with TTM, replaced with a simple reference - * of the front buffer handle passed to us by the DDX. - */ - { - struct pipe_surface *fb_surf; - struct nouveau_pipe_buffer *fb_buf; - struct nouveau_bo_priv *fb_bo; - - fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); - fb_bo->drm.offset = nv_screen->front_offset; - fb_bo->drm.flags = NOUVEAU_MEM_FB; - fb_bo->drm.size = nv_screen->front_pitch * - nv_screen->front_height; - fb_bo->refcount = 1; - fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; - fb_bo->base.offset = fb_bo->drm.offset; - fb_bo->base.handle = (unsigned long)fb_bo; - fb_bo->base.size = fb_bo->drm.size; - fb_bo->base.device = nv_screen->device; - - fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); - fb_buf->bo = &fb_bo->base; - - fb_surf = calloc(1, sizeof(struct pipe_surface)); - if (nv_screen->front_cpp == 2) - fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; - else - fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; - pf_get_block(fb_surf->format, &fb_surf->block); - fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; - fb_surf->height = nv_screen->front_height; - fb_surf->stride = fb_surf->width * fb_surf->block.size; - fb_surf->refcount = 1; - fb_surf->buffer = &fb_buf->base; - - nv->frontbuffer = fb_surf; - } - - nvc = nv_screen->nvc; - - if (!nvc) { - nvc = nouveau_channel_context_create(dev); - if (!nvc) { - NOUVEAU_ERR("Failed initialising GPU context\n"); - return 1; - } - nv_screen->nvc = nvc; - } - - nvc->refcount++; - nv->nvc = nvc; - - /* Find a free slot for a pipe context, allocate a new one if needed */ - nv->pctx_id = -1; - for (i = 0; i < nvc->nr_pctx; i++) { - if (nvc->pctx[i] == NULL) { - nv->pctx_id = i; - break; - } - } - - if (nv->pctx_id < 0) { - nv->pctx_id = nvc->nr_pctx++; - nvc->pctx = - realloc(nvc->pctx, - sizeof(struct pipe_context *) * nvc->nr_pctx); - } - - /* Create pipe */ - switch (dev->chipset & 0xf0) { - case 0x50: - case 0x80: - case 0x90: - if (nouveau_surface_init_nv50(nv)) - return 1; - break; - default: - if (nouveau_surface_init_nv04(nv)) - return 1; - break; - } - - if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { - struct pipe_screen *pscreen; - - pipe = nouveau_pipe_create(nv); - if (!pipe) - NOUVEAU_ERR("Couldn't create hw pipe\n"); - pscreen = nvc->pscreen; - - nv->cap.hw_vertex_buffer = - pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF); - nv->cap.hw_index_buffer = - pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF); - } - - /* XXX: nouveau_winsys_softpipe needs a mesa header removed before we can compile it. */ - /* - if (!pipe) { - NOUVEAU_MSG("Using softpipe\n"); - pipe = nouveau_create_softpipe(nv); - if (!pipe) { - NOUVEAU_ERR("Error creating pipe, bailing\n"); - return 1; - } - } - */ - if (!pipe) { - NOUVEAU_ERR("Error creating pipe, bailing\n"); - return 1; - } - - pipe->priv = nv; - - return 0; -} - -void -nouveau_context_destroy(dri_context_t *dri_context) -{ - struct nouveau_context *nv = dri_context->private; - struct nouveau_channel_context *nvc = nv->nvc; - - assert(nv); - - if (nv->pctx_id >= 0) { - nvc->pctx[nv->pctx_id] = NULL; - if (--nvc->refcount <= 0) { - nouveau_channel_context_destroy(nvc); - nv->nv_screen->nvc = NULL; - } - } - - free(nv); -} - -int -nouveau_context_bind(struct nouveau_context *nv, dri_drawable_t *dri_drawable) -{ - assert(nv); - assert(dri_drawable); - - if (nv->dri_drawable != dri_drawable) - { - nv->dri_drawable = dri_drawable; - dri_drawable->private = nv; - } - - return 0; -} - -int -nouveau_context_unbind(struct nouveau_context *nv) -{ - assert(nv); - - nv->dri_drawable = NULL; - - return 0; -} - -/* Show starts here */ - -int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) -{ - struct nouveau_context *nv; - dri_drawable_t *dri_drawable; - - nv = pipe->priv; - - driCreateDrawable(nv->nv_screen->dri_screen, drawable, &dri_drawable); - - nouveau_context_bind(nv, dri_drawable); - - return 0; -} - -int unbind_pipe_drawable(struct pipe_context *pipe) -{ - nouveau_context_unbind(pipe->priv); - - return 0; -} - -struct pipe_context* create_pipe_context(Display *display, int screen) -{ - dri_screen_t *dri_screen; - dri_framebuffer_t dri_framebuf; - dri_context_t *dri_context; - struct nouveau_context *nv; - - driCreateScreen(display, screen, &dri_screen, &dri_framebuf); - driCreateContext(dri_screen, XDefaultVisual(display, screen), &dri_context); - - nouveau_screen_create(dri_screen, &dri_framebuf); - nouveau_context_create(dri_context); - - nv = dri_context->private; - - return nv->nvc->pctx[nv->pctx_id]; -} - -int destroy_pipe_context(struct pipe_context *pipe) -{ - struct pipe_screen *screen; - struct pipe_winsys *winsys; - struct nouveau_context *nv; - dri_screen_t *dri_screen; - dri_context_t *dri_context; - - assert(pipe); - - screen = pipe->screen; - winsys = pipe->winsys; - nv = pipe->priv; - dri_context = nv->dri_context; - dri_screen = dri_context->dri_screen; - - pipe->destroy(pipe); - screen->destroy(screen); - free(winsys); - - nouveau_context_destroy(dri_context); - nouveau_screen_destroy(dri_screen); - driDestroyContext(dri_context); - driDestroyScreen(dri_screen); - - return 0; -} diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h deleted file mode 100644 index 395a3ab790..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef __NOUVEAU_CONTEXT_H__ -#define __NOUVEAU_CONTEXT_H__ - -/*#include "xmlconfig.h"*/ - -#include -#include "nouveau/nouveau_winsys.h" -#include "nouveau_drmif.h" -#include "nouveau_dma.h" - -struct nouveau_channel_context { - struct pipe_screen *pscreen; - int refcount; - - unsigned cur_pctx; - unsigned nr_pctx; - struct pipe_context **pctx; - - struct nouveau_channel *channel; - - struct nouveau_notifier *sync_notifier; - - /* Common */ - struct nouveau_grobj *NvM2MF; - /* NV04-NV40 */ - struct nouveau_grobj *NvCtxSurf2D; - struct nouveau_grobj *NvSwzSurf; - struct nouveau_grobj *NvImageBlit; - struct nouveau_grobj *NvGdiRect; - struct nouveau_grobj *NvSIFM; - /* G80 */ - struct nouveau_grobj *Nv2D; - - uint32_t next_handle; - uint32_t next_subchannel; - uint32_t next_sequence; -}; - -struct nouveau_context { - /* DRI stuff */ - dri_context_t *dri_context; - dri_drawable_t *dri_drawable; - unsigned int last_stamp; - /*driOptionCache dri_option_cache;*/ - drm_context_t drm_context; - drmLock drm_lock; - int locked; - struct nouveau_screen *nv_screen; - struct pipe_surface *frontbuffer; - - struct { - int hw_vertex_buffer; - int hw_index_buffer; - } cap; - - /* Hardware context */ - struct nouveau_channel_context *nvc; - int pctx_id; - - /* pipe_surface accel */ - struct pipe_surface *surf_src, *surf_dst; - unsigned surf_src_offset, surf_dst_offset; - - int (*surface_copy_prep)(struct nouveau_context *, - struct pipe_surface *dst, - struct pipe_surface *src); - void (*surface_copy)(struct nouveau_context *, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h); - void (*surface_copy_done)(struct nouveau_context *); - int (*surface_fill)(struct nouveau_context *, struct pipe_surface *, - unsigned, unsigned, unsigned, unsigned, unsigned); -}; - -extern int nouveau_context_create(dri_context_t *); -extern void nouveau_context_destroy(dri_context_t *); -extern int nouveau_context_bind(struct nouveau_context *, dri_drawable_t *); -extern int nouveau_context_unbind(struct nouveau_context *); - -#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 - -extern void LOCK_HARDWARE(struct nouveau_context *); -extern void UNLOCK_HARDWARE(struct nouveau_context *); - -extern int -nouveau_surface_channel_create_nv04(struct nouveau_channel_context *); -extern int -nouveau_surface_channel_create_nv50(struct nouveau_channel_context *); -extern int nouveau_surface_init_nv04(struct nouveau_context *); -extern int nouveau_surface_init_nv50(struct nouveau_context *); - -extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int); -extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *); - -#endif diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.c new file mode 100644 index 0000000000..dfc4905bc0 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.c @@ -0,0 +1,172 @@ +#include "nouveau_context_vl.h" +#include +#include +#include +#include +#include +#include +#include +#include "nouveau_screen_vl.h" + +/* +#ifdef DEBUG +static const struct dri_debug_control debug_control[] = { + { "bo", DEBUG_BO }, + { NULL, 0 } +}; +int __nouveau_debug = 0; +#endif +*/ + +int +nouveau_context_create(dri_context_t *dri_context) +{ + dri_screen_t *dri_screen; + struct nouveau_screen_vl *nv_screen; + struct nouveau_context_vl *nv; + + assert (dri_context); + + dri_screen = dri_context->dri_screen; + nv_screen = dri_screen->private; + nv = CALLOC_STRUCT(nouveau_context_vl); + + if (!nv) + return 1; + + if (nouveau_context_init(&nv_screen->base, dri_context->drm_context, + (drmLock*)&dri_screen->sarea->lock, NULL, &nv->base)) + { + FREE(nv); + return 1; + } + + dri_context->private = (void*)nv; + nv->dri_context = dri_context; + nv->nv_screen = nv_screen; + + /* + driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, + nv->dri_screen->myNum, "nouveau"); +#ifdef DEBUG + __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"), + debug_control); +#endif + */ + + nv->base.nvc->pctx[nv->base.pctx_id]->priv = nv; + + return 0; +} + +void +nouveau_context_destroy(dri_context_t *dri_context) +{ + struct nouveau_context_vl *nv = dri_context->private; + + assert(dri_context); + + nouveau_context_cleanup(&nv->base); + + FREE(nv); +} + +int +nouveau_context_bind(struct nouveau_context_vl *nv, dri_drawable_t *dri_drawable) +{ + assert(nv); + assert(dri_drawable); + + if (nv->dri_drawable != dri_drawable) + { + nv->dri_drawable = dri_drawable; + dri_drawable->private = nv; + } + + return 0; +} + +int +nouveau_context_unbind(struct nouveau_context_vl *nv) +{ + assert(nv); + + nv->dri_drawable = NULL; + + return 0; +} + +/* Show starts here */ + +int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) +{ + struct nouveau_context_vl *nv; + dri_drawable_t *dri_drawable; + + assert(pipe); + + nv = pipe->priv; + + driCreateDrawable(nv->nv_screen->dri_screen, drawable, &dri_drawable); + + nouveau_context_bind(nv, dri_drawable); + + return 0; +} + +int unbind_pipe_drawable(struct pipe_context *pipe) +{ + assert (pipe); + + nouveau_context_unbind(pipe->priv); + + return 0; +} + +struct pipe_context* create_pipe_context(Display *display, int screen) +{ + dri_screen_t *dri_screen; + dri_framebuffer_t dri_framebuf; + dri_context_t *dri_context; + struct nouveau_context_vl *nv; + + assert(display); + + driCreateScreen(display, screen, &dri_screen, &dri_framebuf); + driCreateContext(dri_screen, XDefaultVisual(display, screen), &dri_context); + + nouveau_screen_create(dri_screen, &dri_framebuf); + nouveau_context_create(dri_context); + + nv = dri_context->private; + + return nv->base.nvc->pctx[nv->base.pctx_id]; +} + +int destroy_pipe_context(struct pipe_context *pipe) +{ + struct pipe_screen *screen; + struct pipe_winsys *winsys; + struct nouveau_context_vl *nv; + dri_screen_t *dri_screen; + dri_context_t *dri_context; + + assert(pipe); + + screen = pipe->screen; + winsys = pipe->winsys; + nv = pipe->priv; + dri_context = nv->dri_context; + dri_screen = dri_context->dri_screen; + + pipe->destroy(pipe); + screen->destroy(screen); + FREE(winsys); + + nouveau_context_destroy(dri_context); + nouveau_screen_destroy(dri_screen); + driDestroyContext(dri_context); + driDestroyScreen(dri_screen); + + return 0; +} diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.h new file mode 100644 index 0000000000..1115c3130c --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.h @@ -0,0 +1,39 @@ +#ifndef __NOUVEAU_CONTEXT_VL_H__ +#define __NOUVEAU_CONTEXT_VL_H__ + +#include +#include +#include + +/*#include "xmlconfig.h"*/ + +struct nouveau_context_vl { + struct nouveau_context base; + struct nouveau_screen_vl *nv_screen; + dri_context_t *dri_context; + dri_drawable_t *dri_drawable; + unsigned int last_stamp; + /*driOptionCache dri_option_cache;*/ + drm_context_t drm_context; + drmLock drm_lock; +}; + +extern int nouveau_context_create(dri_context_t *); +extern void nouveau_context_destroy(dri_context_t *); +extern int nouveau_context_bind(struct nouveau_context_vl *, dri_drawable_t *); +extern int nouveau_context_unbind(struct nouveau_context_vl *); + +#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/g3dvl/nouveau/nouveau_screen.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c deleted file mode 100644 index f80d00050c..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "pipe/p_context.h" -#include "util/u_memory.h" -#include "nouveau_context.h" -#include -#include "nouveau_dri.h" -#include "nouveau_local.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" - -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 -#error nouveau_drm.h version does not match expected version -#endif - -/* -PUBLIC const char __driConfigOptions[] = -DRI_CONF_BEGIN -DRI_CONF_END; -static const GLuint __driNConfigOptions = 0; -*/ - -int nouveau_check_dri_drm_ddx(dri_version_t *dri, dri_version_t *drm, dri_version_t *ddx) -{ - static const dri_version_t ddx_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; - static const dri_version_t dri_expected = {4, 0, 0}; - static const dri_version_t drm_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; - - assert(dri); - assert(drm); - assert(ddx); - - if (dri->major != dri_expected.major || dri->minor < dri_expected.minor) - { - NOUVEAU_ERR("Unexpected DRI version.\n"); - return 1; - } - if (drm->major != drm_expected.major || drm->minor < drm_expected.minor) - { - NOUVEAU_ERR("Unexpected DRM version.\n"); - return 1; - } - if (ddx->major != ddx_expected.major || ddx->minor < ddx_expected.minor) - { - NOUVEAU_ERR("Unexpected DDX version.\n"); - return 1; - } - - return 0; -} - -int -nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf) -{ - struct nouveau_dri *nv_dri = dri_framebuf->private; - struct nouveau_screen *nv_screen; - int ret; - - if (nouveau_check_dri_drm_ddx(&dri_screen->dri, &dri_screen->drm, &dri_screen->ddx)) - return 1; - - nv_screen = CALLOC_STRUCT(nouveau_screen); - if (!nv_screen) - return 1; - nv_screen->dri_screen = dri_screen; - dri_screen->private = (void*)nv_screen; - - /* - driParseOptionInfo(&nv_screen->option_cache, - __driConfigOptions, __driNConfigOptions); - */ - - if ((ret = nouveau_device_open_existing(&nv_screen->device, 0, - dri_screen->fd, 0))) { - NOUVEAU_ERR("Failed opening nouveau device: %d.\n", ret); - return 1; - } - - nv_screen->front_offset = nv_dri->front_offset; - nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8); - nv_screen->front_cpp = nv_dri->bpp / 8; - nv_screen->front_height = nv_dri->height; - - return 0; -} - -void -nouveau_screen_destroy(dri_screen_t *dri_screen) -{ - struct nouveau_screen *nv_screen = dri_screen->private; - - FREE(nv_screen); -} diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h deleted file mode 100644 index 8a58bb7556..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __NOUVEAU_SCREEN_H__ -#define __NOUVEAU_SCREEN_H__ - -/* TODO: Investigate using DRI options for interesting things */ -/*#include "xmlconfig.h"*/ - -struct nouveau_screen { - dri_screen_t *dri_screen; - struct nouveau_device *device; - struct nouveau_channel_context *nvc; - - uint32_t front_offset; - uint32_t front_pitch; - uint32_t front_cpp; - uint32_t front_height; - - /*driOptionCache option_cache;*/ -}; - -int nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf); -void nouveau_screen_destroy(dri_screen_t *dri_screen); - -#endif - diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c new file mode 100644 index 0000000000..658dafd910 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c @@ -0,0 +1,88 @@ +#include "nouveau_screen_vl.h" +#include +#include +#include +#include + +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 +#error nouveau_drm.h version does not match expected version +#endif + +/* +PUBLIC const char __driConfigOptions[] = +DRI_CONF_BEGIN +DRI_CONF_END; +static const GLuint __driNConfigOptions = 0; +*/ + +int nouveau_check_dri_drm_ddx(dri_version_t *dri, dri_version_t *drm, dri_version_t *ddx) +{ + static const dri_version_t ddx_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; + static const dri_version_t dri_expected = {4, 0, 0}; + static const dri_version_t drm_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; + + assert(dri); + assert(drm); + assert(ddx); + + if (dri->major != dri_expected.major || dri->minor < dri_expected.minor) + { + NOUVEAU_ERR("Unexpected DRI version.\n"); + return 1; + } + if (drm->major != drm_expected.major || drm->minor < drm_expected.minor) + { + NOUVEAU_ERR("Unexpected DRM version.\n"); + return 1; + } + if (ddx->major != ddx_expected.major || ddx->minor < ddx_expected.minor) + { + NOUVEAU_ERR("Unexpected DDX version.\n"); + return 1; + } + + return 0; +} + +int +nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf) +{ + struct nouveau_dri *nv_dri = dri_framebuf->private; + struct nouveau_screen_vl *nv_screen; + + assert(dri_screen); + assert(dri_framebuf); + + if (nouveau_check_dri_drm_ddx(&dri_screen->dri, &dri_screen->drm, &dri_screen->ddx)) + return 1; + + nv_screen = CALLOC_STRUCT(nouveau_screen_vl); + + if (!nv_screen) + return 1; + + if (nouveau_screen_init(nv_dri, dri_screen->fd, &nv_screen->base)) + { + FREE(nv_screen); + return 1; + } + + /* + driParseOptionInfo(&nv_screen->option_cache, + __driConfigOptions, __driNConfigOptions); + */ + + nv_screen->dri_screen = dri_screen; + dri_screen->private = (void*)nv_screen; + + return 0; +} + +void +nouveau_screen_destroy(dri_screen_t *dri_screen) +{ + struct nouveau_screen_vl *nv_screen = dri_screen->private; + + nouveau_screen_cleanup(&nv_screen->base); + FREE(nv_screen); +} diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.h new file mode 100644 index 0000000000..0c1ceca6de --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.h @@ -0,0 +1,20 @@ +#ifndef __NOUVEAU_SCREEN_VL_H__ +#define __NOUVEAU_SCREEN_VL_H__ + +#include +#include + +/* TODO: Investigate using DRI options for interesting things */ +/*#include "xmlconfig.h"*/ + +struct nouveau_screen_vl +{ + struct nouveau_screen base; + dri_screen_t *dri_screen; + /*driOptionCache option_cache;*/ +}; + +int nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf); +void nouveau_screen_destroy(dri_screen_t *dri_screen); + +#endif diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c index 7916c80615..16e6d5543c 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c @@ -1,26 +1,26 @@ -#include "pipe/p_context.h" -#include "nouveau_context.h" -#include "nouveau_local.h" -#include "nouveau_screen.h" +#include +#include +#include +#include "nouveau_context_vl.h" #include "nouveau_swapbuffers.h" void nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, const drm_clip_rect_t *rect) { - struct nouveau_context *nv = dri_drawable->private; - drm_clip_rect_t *pbox; - int nbox, i; + struct nouveau_context_vl *nv = dri_drawable->private; + drm_clip_rect_t *pbox; + int nbox, i; - LOCK_HARDWARE(nv); + LOCK_HARDWARE(&nv->base); if (!dri_drawable->num_cliprects) { - UNLOCK_HARDWARE(nv); + UNLOCK_HARDWARE(&nv->base); return; } pbox = dri_drawable->cliprects; nbox = dri_drawable->num_cliprects; - nv->surface_copy_prep(nv, nv->frontbuffer, surf); + nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf); for (i = 0; i < nbox; i++, pbox++) { int sx, sy, dx, dy, w, h; @@ -31,14 +31,11 @@ nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, w = pbox->x2 - pbox->x1; h = pbox->y2 - pbox->y1; - nv->surface_copy(nv, dx, dy, sx, sy, w, h); + nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h); } - FIRE_RING(nv->nvc->channel); - UNLOCK_HARDWARE(nv); - - //if (nv->last_stamp != dri_drawable->last_sarea_stamp) - //nv->last_stamp = dri_drawable->last_sarea_stamp; + FIRE_RING(nv->base.nvc->channel); + UNLOCK_HARDWARE(&nv->base); } void @@ -62,3 +59,35 @@ nouveau_swap_buffers(dri_drawable_t *dri_drawable, struct pipe_surface *surf) nouveau_copy_buffer(dri_drawable, surf, NULL); } +void +nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, + void *context_private) +{ + struct nouveau_context_vl *nv; + dri_drawable_t *dri_drawable; + + assert(pws); + assert(surf); + assert(context_private); + + nv = context_private; + dri_drawable = nv->dri_drawable; + + nouveau_copy_buffer(dri_drawable, surf, NULL); +} + +void +nouveau_contended_lock(struct nouveau_context *nv) +{ + struct nouveau_context_vl *nv_vl = (struct nouveau_context_vl*)nv; + dri_drawable_t *dri_drawable = nv_vl->dri_drawable; + dri_screen_t *dri_screen = nv_vl->dri_context->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 (dri_drawable) + DRI_VALIDATE_DRAWABLE_INFO(dri_screen, dri_drawable); +} -- cgit v1.2.3 From 7b6fb34e9d1da73cc92fc63fa1d52082df5904ee Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 12 Jan 2009 13:25:28 +1000 Subject: nouveau: use usage, not uninitialised flags value... --- src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c index 6895137506..c8f26d5fad 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c @@ -69,7 +69,7 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, nvbuf->base.usage = usage; nvbuf->base.size = size; - flags = nouveau_flags_from_usage(nv, flags); + flags = nouveau_flags_from_usage(nv, usage); if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) { FREE(nvbuf); -- cgit v1.2.3 From df266471b1f0eae54cf23fd59a741fa3be9b93df Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 12 Jan 2009 13:27:13 +1000 Subject: nouveau: return buffer map to something sane. Sorry, but no, we're not doing this.. Correctness always takes precedence over speed. Implement this higher up where you know it's safe to do so, and doesn't break other things in the process. --- .../winsys/drm/nouveau/common/nouveau_winsys_pipe.c | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c index c8f26d5fad..683710ee3c 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c @@ -121,26 +121,6 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) map_flags |= NOUVEAU_BO_WR; - /* XXX: Technically incorrect. If the client maps a buffer for write-only - * and leaves part of the buffer untouched it probably expects those parts - * to remain intact. This is violated because we allocate a whole new buffer - * and don't copy the previous buffer's contents, so this optimization is - * only valid if the client intends to overwrite the whole buffer. - */ - if ((map_flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_WR && - !nouveau_bo_busy(nvbuf->bo, map_flags)) { - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; - struct nouveau_context *nv = nvpws->nv; - struct nouveau_device *dev = nv->nv_screen->device; - struct nouveau_bo *rename; - uint32_t flags = nouveau_flags_from_usage(nv, buf->usage); - - if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) { - nouveau_bo_del(&nvbuf->bo); - nvbuf->bo = rename; - } - } - if (nouveau_bo_map(nvbuf->bo, map_flags)) return NULL; return nvbuf->bo->map; -- cgit v1.2.3 From ecb2eb4c991be40cf4235fadd286c942179f4036 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 12 Jan 2009 16:15:58 +1000 Subject: nouveau: fix warning --- src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c index 006978b182..aacfe984d1 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c @@ -42,7 +42,7 @@ nouveau_context_create(const __GLcontextModes *glVis, if (nouveau_context_init(&nv_screen->base, driContextPriv->hHWContext, (drmLock *)&driScrnPriv->pSAREA->lock, - nv_share, &nv->base)) { + &nv_share->base, &nv->base)) { return GL_FALSE; } -- cgit v1.2.3 From 2f19fecd583a4406385708de6362b3bdef23811e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 13 Jan 2009 18:08:24 +0000 Subject: xlib: allow winsys's to register themselves with glx/xlib state tracker --- src/gallium/winsys/xlib/xlib.c | 77 ++++--------------------------- src/gallium/winsys/xlib/xlib.h | 13 ++++++ src/gallium/winsys/xlib/xlib_brw.h | 18 ++------ src/gallium/winsys/xlib/xlib_brw_screen.c | 20 +++++--- src/gallium/winsys/xlib/xlib_softpipe.c | 55 ++++++++++++++++------ src/gallium/winsys/xlib/xlib_softpipe.h | 50 -------------------- src/gallium/winsys/xlib/xlib_trace.c | 28 +++++++---- src/gallium/winsys/xlib/xlib_trace.h | 26 ----------- 8 files changed, 96 insertions(+), 191 deletions(-) create mode 100644 src/gallium/winsys/xlib/xlib.h delete mode 100644 src/gallium/winsys/xlib/xlib_softpipe.h delete mode 100644 src/gallium/winsys/xlib/xlib_trace.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xlib.c b/src/gallium/winsys/xlib/xlib.c index 8d4d734b03..e5f8048b6a 100644 --- a/src/gallium/winsys/xlib/xlib.c +++ b/src/gallium/winsys/xlib/xlib.c @@ -31,9 +31,7 @@ * Keith Whitwell */ -#include "xlib_trace.h" -#include "xlib_softpipe.h" -#include "xlib_brw.h" +#include "xlib.h" #include "xm_winsys.h" #include @@ -50,7 +48,6 @@ enum mode { MODE_SOFTPIPE }; -static enum mode xlib_mode; static enum mode get_mode() { @@ -68,80 +65,24 @@ static enum mode get_mode() return MODE_SOFTPIPE; } +static void _init( void ) __attribute__((constructor)); -struct pipe_winsys * -xmesa_create_pipe_winsys( void ) +static void _init( void ) { - xlib_mode = get_mode(); + enum mode xlib_mode = get_mode(); switch (xlib_mode) { case MODE_TRACE: - return xlib_create_trace_winsys(); - case MODE_BRW: - return xlib_create_brw_winsys(); - case MODE_CELL: - return xlib_create_cell_winsys(); - case MODE_SOFTPIPE: - return xlib_create_softpipe_winsys(); - default: - assert(0); - return NULL; - } -} - -struct pipe_screen * -xmesa_create_pipe_screen( struct pipe_winsys *winsys ) -{ - switch (xlib_mode) { - case MODE_TRACE: - return xlib_create_trace_screen( winsys ); - case MODE_BRW: - return xlib_create_brw_screen( winsys ); - case MODE_CELL: - return xlib_create_cell_screen( winsys ); - case MODE_SOFTPIPE: - return xlib_create_softpipe_screen( winsys ); - default: - assert(0); - return NULL; - } -} - -struct pipe_context * -xmesa_create_pipe_context( struct pipe_screen *screen, - void *priv ) -{ - switch (xlib_mode) { - case MODE_TRACE: - return xlib_create_trace_context( screen, priv ); - case MODE_BRW: - return xlib_create_brw_context( screen, priv ); - case MODE_CELL: - return xlib_create_cell_context( screen, priv ); - case MODE_SOFTPIPE: - return xlib_create_softpipe_context( screen, priv ); - default: - assert(0); - return NULL; - } -} - -void -xmesa_display_surface( struct xmesa_buffer *buffer, - struct pipe_surface *surf ) -{ - switch (xlib_mode) { - case MODE_TRACE: - xlib_trace_display_surface( buffer, surf ); + xmesa_set_driver( &xlib_trace_driver ); break; case MODE_BRW: - xlib_brw_display_surface( buffer, surf ); + xmesa_set_driver( &xlib_brw_driver ); break; case MODE_CELL: - xlib_cell_display_surface( buffer, surf ); + xmesa_set_driver( &xlib_cell_driver ); break; case MODE_SOFTPIPE: - xlib_softpipe_display_surface( buffer, surf ); + xmesa_set_driver( &xlib_softpipe_driver ); break; default: assert(0); @@ -149,8 +90,6 @@ xmesa_display_surface( struct xmesa_buffer *buffer, } } - - /*********************************************************************** * * Butt-ugly hack to convince the linker not to throw away public GL diff --git a/src/gallium/winsys/xlib/xlib.h b/src/gallium/winsys/xlib/xlib.h new file mode 100644 index 0000000000..9e47f23be5 --- /dev/null +++ b/src/gallium/winsys/xlib/xlib.h @@ -0,0 +1,13 @@ + +#ifndef XLIB_H +#define XLIB_H + +#include "xm_winsys.h" + +extern struct xm_driver xlib_trace_driver; +extern struct xm_driver xlib_softpipe_driver; +extern struct xm_driver xlib_cell_driver; +extern struct xm_driver xlib_brw_driver; + + +#endif diff --git a/src/gallium/winsys/xlib/xlib_brw.h b/src/gallium/winsys/xlib/xlib_brw.h index aad3f229bf..be2dd147db 100644 --- a/src/gallium/winsys/xlib/xlib_brw.h +++ b/src/gallium/winsys/xlib/xlib_brw.h @@ -6,20 +6,6 @@ struct pipe_buffer; struct pipe_surface; struct xmesa_buffer; -struct pipe_winsys *xlib_create_brw_winsys( void ); - -struct pipe_screen *xlib_create_brw_screen( struct pipe_winsys * ); - -struct pipe_context *xlib_create_brw_context( struct pipe_screen *, - void *priv ); - -void xlib_brw_display_surface(struct xmesa_buffer *b, - struct pipe_surface *surf); - -/*********************************************************************** - * Internal functions - */ - unsigned xlib_brw_get_buffer_offset( struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned access_flags ); @@ -37,4 +23,8 @@ void xlib_brw_commands_aub(struct pipe_winsys *winsys, unsigned *cmds, unsigned nr_dwords); +struct pipe_context * +xlib_create_brw_context( struct pipe_screen *screen, + void *unused ); + #endif diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c index 9325bdc7a6..1e4c2f6c41 100644 --- a/src/gallium/winsys/xlib/xlib_brw_screen.c +++ b/src/gallium/winsys/xlib/xlib_brw_screen.c @@ -45,6 +45,7 @@ #include "xlib_brw_aub.h" #include "xlib_brw.h" +#include "xlib.h" @@ -311,7 +312,7 @@ xlib_brw_destroy_pipe_winsys_aub( struct pipe_winsys *winsys ) -struct pipe_winsys * +static struct pipe_winsys * xlib_create_brw_winsys( void ) { struct aub_pipe_winsys *iws = CALLOC_STRUCT( aub_pipe_winsys ); @@ -349,14 +350,10 @@ xlib_create_brw_winsys( void ) } -struct pipe_screen * +static struct pipe_screen * xlib_create_brw_screen( struct pipe_winsys *winsys ) { -#ifdef GALLIUM_CELL - return NULL; -#else return brw_create_screen(winsys, 0/* XXX pci_id */); -#endif } @@ -464,7 +461,7 @@ void xlib_brw_buffer_subdata_typed( struct pipe_winsys *pws, } -void +static void xlib_brw_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf) { @@ -472,3 +469,12 @@ xlib_brw_display_surface(struct xmesa_buffer *b, surf, aub_bo(surf->buffer)->offset ); } + + +struct xm_driver xlib_brw_driver = +{ + .create_pipe_winsys = xlib_create_brw_winsys, + .create_pipe_screen = xlib_create_brw_screen, + .create_pipe_context = xlib_create_brw_context, + .display_surface = xlib_brw_display_surface, +}; diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index 2a8bd4681e..7ad73be260 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -54,7 +54,7 @@ #define TILE_SIZE 32 /* avoid compilation errors */ #endif -#include "xlib_softpipe.h" +#include "xlib.h" /** * Subclass of pipe_buffer for Xlib winsys. @@ -303,7 +303,7 @@ twiddle_tile(const uint *tileIn, uint *tileOut) * Display a surface that's in a tiled configuration. That is, all the * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory. */ -void +static void xlib_cell_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf) { XImage *ximage; @@ -374,7 +374,7 @@ xlib_cell_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf) * Display/copy the image in the surface into the X window specified * by the XMesaBuffer. */ -void +static void xlib_softpipe_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf) { @@ -620,7 +620,7 @@ xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, -struct pipe_winsys * +static struct pipe_winsys * xlib_create_softpipe_winsys( void ) { static struct xmesa_pipe_winsys *ws = NULL; @@ -655,7 +655,7 @@ xlib_create_softpipe_winsys( void ) } -struct pipe_screen * +static struct pipe_screen * xlib_create_softpipe_screen( struct pipe_winsys *pws ) { struct pipe_screen *screen; @@ -671,7 +671,7 @@ fail: } -struct pipe_context * +static struct pipe_context * xlib_create_softpipe_context( struct pipe_screen *screen, void *context_private ) { @@ -689,6 +689,14 @@ fail: return NULL; } +struct xm_driver xlib_softpipe_driver = +{ + .create_pipe_winsys = xlib_create_softpipe_winsys, + .create_pipe_screen = xlib_create_softpipe_screen, + .create_pipe_context = xlib_create_softpipe_context, + .display_surface = xlib_softpipe_display_surface +}; + /*********************************************************************** * Cell piggybacks on softpipe code still. @@ -698,28 +706,25 @@ fail: * and creating cell-specific versions of either those functions or * the entire file. */ -struct pipe_winsys * +#ifdef GALLIUM_CELL + +static struct pipe_winsys * xlib_create_cell_winsys( void ) { return xlib_create_softpipe_winsys(); } -struct pipe_screen * +static struct pipe_screen * xlib_create_cell_screen( struct pipe_winsys *pws ) { -#ifdef GALLIUM_CELL return cell_create_screen( pws ); -#else - return NULL; -#endif } -struct pipe_context * +static struct pipe_context * xlib_create_cell_context( struct pipe_screen *screen, void *priv ) { -#ifdef GALLIUM_CELL struct cell_winsys *cws; struct pipe_context *pipe; @@ -742,6 +747,26 @@ xlib_create_cell_context( struct pipe_screen *screen, return pipe; fail: -#endif return NULL; } +#endif + +#if defined(GALLIUM_CELL) +struct xm_driver xlib_cell_driver = +{ + .create_pipe_winsys = xlib_create_cell_winsys, + .create_pipe_screen = xlib_create_cell_screen, + .create_pipe_context = xlib_create_cell_context, + .display_surface = xlib_cell_display_surface, +}; +#else +struct xm_driver xlib_cell_driver = +{ + .create_pipe_winsys = xlib_create_softpipe_winsys, + .create_pipe_screen = xlib_create_softpipe_screen, + .create_pipe_context = xlib_create_softpipe_context, + .display_surface = xlib_softpipe_display_surface, +}; +#endif + + diff --git a/src/gallium/winsys/xlib/xlib_softpipe.h b/src/gallium/winsys/xlib/xlib_softpipe.h deleted file mode 100644 index 0de96cc4c6..0000000000 --- a/src/gallium/winsys/xlib/xlib_softpipe.h +++ /dev/null @@ -1,50 +0,0 @@ - -#ifndef XLIB_SOFTPIPE_H -#define XLIB_SOFTPIPE_H - -struct pipe_winsys; -struct pipe_screen; -struct pipe_context; -struct pipe_surface; -struct xmesa_buffer; - - -struct pipe_winsys * -xlib_create_softpipe_winsys( void ); - -struct pipe_screen * -xlib_create_softpipe_screen( struct pipe_winsys *pws ); - -struct pipe_context * -xlib_create_softpipe_context( struct pipe_screen *screen, - void *context_priv ); - -void -xlib_softpipe_display_surface( struct xmesa_buffer *, - struct pipe_surface * ); - -/*********************************************************************** - * Cell piggybacks on softpipe code still. - * - * Should be untangled sufficiently to live in a separate file, at - * least. That would mean removing #ifdef GALLIUM_CELL's from above - * and creating cell-specific versions of either those functions or - * the entire file. - */ -struct pipe_winsys * -xlib_create_cell_winsys( void ); - -struct pipe_screen * -xlib_create_cell_screen( struct pipe_winsys *pws ); - - -struct pipe_context * -xlib_create_cell_context( struct pipe_screen *screen, - void *priv ); - -void -xlib_cell_display_surface( struct xmesa_buffer *, - struct pipe_surface * ); - - -#endif diff --git a/src/gallium/winsys/xlib/xlib_trace.c b/src/gallium/winsys/xlib/xlib_trace.c index 45afba7a47..1b8d3f8a11 100644 --- a/src/gallium/winsys/xlib/xlib_trace.c +++ b/src/gallium/winsys/xlib/xlib_trace.c @@ -33,25 +33,24 @@ */ -#include "xlib_softpipe.h" -#include "xlib_trace.h" +#include "xlib.h" #include "trace/tr_screen.h" #include "trace/tr_context.h" -struct pipe_winsys * +static struct pipe_winsys * xlib_create_trace_winsys( void ) { - return xlib_create_softpipe_winsys(); + return xlib_softpipe_driver.create_pipe_winsys(); } -struct pipe_screen * +static struct pipe_screen * xlib_create_trace_screen( struct pipe_winsys *winsys ) { struct pipe_screen *screen, *trace_screen; - screen = xlib_create_softpipe_screen( winsys ); + screen = xlib_softpipe_driver.create_pipe_screen( winsys ); if (screen == NULL) goto fail; @@ -68,13 +67,13 @@ fail: return NULL; } -struct pipe_context * +static struct pipe_context * xlib_create_trace_context( struct pipe_screen *screen, void *priv ) { struct pipe_context *pipe, *trace_pipe; - pipe = xlib_create_softpipe_context( screen, priv ); + pipe = xlib_softpipe_driver.create_pipe_context( screen, priv ); if (pipe == NULL) goto fail; @@ -92,11 +91,20 @@ fail: return NULL; } -void +static void xlib_trace_display_surface( struct xmesa_buffer *buffer, struct pipe_surface *surf ) { /* ?? */ - xlib_softpipe_display_surface( buffer, surf ); + xlib_softpipe_driver.display_surface( buffer, surf ); } + + +struct xm_driver xlib_trace_driver = +{ + .create_pipe_winsys = xlib_create_trace_winsys, + .create_pipe_screen = xlib_create_trace_screen, + .create_pipe_context = xlib_create_trace_context, + .display_surface = xlib_trace_display_surface, +}; diff --git a/src/gallium/winsys/xlib/xlib_trace.h b/src/gallium/winsys/xlib/xlib_trace.h deleted file mode 100644 index c79c0fe34d..0000000000 --- a/src/gallium/winsys/xlib/xlib_trace.h +++ /dev/null @@ -1,26 +0,0 @@ - -#ifndef XLIB_TRACE_H -#define XLIB_TRACE_H - -struct pipe_winsys; -struct pipe_screen; -struct pipe_context; -struct pipe_surface; -struct xmesa_buffer; - -struct pipe_winsys * -xlib_create_trace_winsys( void ); - -struct pipe_screen * -xlib_create_trace_screen( struct pipe_winsys *winsys ); - -struct pipe_context * -xlib_create_trace_context( struct pipe_screen *screen, - void *priv ); - -void -xlib_trace_display_surface( struct xmesa_buffer *buffer, - struct pipe_surface *surf ); - - -#endif -- cgit v1.2.3 From a8e0df08ef75db9d80ddc55098e436829af49d7c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 13 Jan 2009 19:53:40 +0000 Subject: xlib: split off cell to its own backend Also remove compile-time USE_XSHM flag. Still check for XSHM at runtime though. --- src/gallium/winsys/xlib/Makefile | 1 + src/gallium/winsys/xlib/xlib.c | 1 + src/gallium/winsys/xlib/xlib.h | 1 + src/gallium/winsys/xlib/xlib_cell.c | 464 ++++++++++++++++++++++++++++++++ src/gallium/winsys/xlib/xlib_softpipe.c | 245 ----------------- 5 files changed, 467 insertions(+), 245 deletions(-) create mode 100644 src/gallium/winsys/xlib/xlib_cell.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index fbc947f363..bca59ac883 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -24,6 +24,7 @@ INCLUDE_DIRS = \ XLIB_WINSYS_SOURCES = \ xlib.c \ + xlib_cell.c \ xlib_brw_aub.c \ xlib_brw_context.c \ xlib_brw_screen.c \ diff --git a/src/gallium/winsys/xlib/xlib.c b/src/gallium/winsys/xlib/xlib.c index e5f8048b6a..4982230000 100644 --- a/src/gallium/winsys/xlib/xlib.c +++ b/src/gallium/winsys/xlib/xlib.c @@ -90,6 +90,7 @@ static void _init( void ) } } + /*********************************************************************** * * Butt-ugly hack to convince the linker not to throw away public GL diff --git a/src/gallium/winsys/xlib/xlib.h b/src/gallium/winsys/xlib/xlib.h index 9e47f23be5..d602ab0b13 100644 --- a/src/gallium/winsys/xlib/xlib.h +++ b/src/gallium/winsys/xlib/xlib.h @@ -2,6 +2,7 @@ #ifndef XLIB_H #define XLIB_H +#include "pipe/p_compiler.h" #include "xm_winsys.h" extern struct xm_driver xlib_trace_driver; diff --git a/src/gallium/winsys/xlib/xlib_cell.c b/src/gallium/winsys/xlib/xlib_cell.c new file mode 100644 index 0000000000..5fe406d5ab --- /dev/null +++ b/src/gallium/winsys/xlib/xlib_cell.c @@ -0,0 +1,464 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * Brian Paul + */ + +#include "xlib.h" + +#ifdef GALLIUM_CELL + +#include "xm_api.h" + +#undef ASSERT +#undef Elements + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "cell/ppu/cell_context.h" +#include "cell/ppu/cell_screen.h" +#include "cell/ppu/cell_winsys.h" + + +/** + * Subclass of pipe_buffer for Xlib winsys. + * Low-level OS/window system memory buffer + */ +struct xm_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; + + XImage *tempImage; + int shm; +}; + + +/** + * Subclass of pipe_winsys for Xlib winsys + */ +struct xmesa_pipe_winsys +{ + struct pipe_winsys base; +}; + + + +/** Cast wrapper */ +static INLINE struct xm_buffer * +xm_buffer( struct pipe_buffer *buf ) +{ + return (struct xm_buffer *)buf; +} + + +/* Most callbacks map direcly onto dri_bufmgr operations: + */ +static void * +xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, + unsigned flags) +{ + struct xm_buffer *xm_buf = xm_buffer(buf); + xm_buf->mapped = xm_buf->data; + return xm_buf->mapped; +} + +static void +xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct xm_buffer *xm_buf = xm_buffer(buf); + xm_buf->mapped = NULL; +} + +static void +xm_buffer_destroy(struct pipe_winsys *pws, + struct pipe_buffer *buf) +{ + struct xm_buffer *oldBuf = xm_buffer(buf); + + if (oldBuf->data) { + { + if (!oldBuf->userBuffer) { + align_free(oldBuf->data); + } + } + + oldBuf->data = NULL; + } + + free(oldBuf); +} + + +/** + * For Cell. Basically, rearrange the pixels/quads from this layout: + * +--+--+--+--+ + * |p0|p1|p2|p3|.... + * +--+--+--+--+ + * + * to this layout: + * +--+--+ + * |p0|p1|.... + * +--+--+ + * |p2|p3| + * +--+--+ + */ +static void +twiddle_tile(const uint *tileIn, uint *tileOut) +{ + int y, x; + + for (y = 0; y < TILE_SIZE; y+=2) { + for (x = 0; x < TILE_SIZE; x+=2) { + int k = 4 * (y/2 * TILE_SIZE/2 + x/2); + tileOut[y * TILE_SIZE + (x + 0)] = tileIn[k]; + tileOut[y * TILE_SIZE + (x + 1)] = tileIn[k+1]; + tileOut[(y + 1) * TILE_SIZE + (x + 0)] = tileIn[k+2]; + tileOut[(y + 1) * TILE_SIZE + (x + 1)] = tileIn[k+3]; + } + } +} + + + +/** + * Display a surface that's in a tiled configuration. That is, all the + * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory. + */ +static void +xlib_cell_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf) +{ + XImage *ximage; + struct xm_buffer *xm_buf = xm_buffer(surf->buffer); + const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE; + uint x, y; + + ximage = b->tempImage; + + /* check that the XImage has been previously initialized */ + assert(ximage->format); + assert(ximage->bitmap_unit); + + /* update XImage's fields */ + ximage->width = TILE_SIZE; + ximage->height = TILE_SIZE; + ximage->bytes_per_line = TILE_SIZE * 4; + + for (y = 0; y < surf->height; y += TILE_SIZE) { + for (x = 0; x < surf->width; x += TILE_SIZE) { + uint tmpTile[TILE_SIZE * TILE_SIZE]; + int tx = x / TILE_SIZE; + int ty = y / TILE_SIZE; + int offset = ty * tilesPerRow + tx; + int w = TILE_SIZE; + int h = TILE_SIZE; + + if (y + h > surf->height) + h = surf->height - y; + if (x + w > surf->width) + w = surf->width - x; + + /* offset in pixels */ + offset *= TILE_SIZE * TILE_SIZE; + + /* twiddle from ximage buffer to temp tile */ + twiddle_tile((uint *) xm_buf->data + offset, tmpTile); + /* display temp tile data */ + ximage->data = (char *) tmpTile; + XPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, x, y, w, h); + } + } +} + + + + + +static void +xm_flush_frontbuffer(struct pipe_winsys *pws, + struct pipe_surface *surf, + void *context_private) +{ + /* + * The front color buffer is actually just another XImage buffer. + * This function copies that XImage to the actual X Window. + */ + XMesaContext xmctx = (XMesaContext) context_private; + xlib_cell_display_surface(xmctx->xm_buffer, surf); +} + + + +static const char * +xm_get_name(struct pipe_winsys *pws) +{ + return "Xlib/Cell"; +} + + +static struct pipe_buffer * +xm_buffer_create(struct pipe_winsys *pws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + + if (buffer->data == NULL) { + buffer->shm = 0; + + /* align to 16-byte multiple for Cell */ + buffer->data = align_malloc(size, max(alignment, 16)); + } + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) +{ + struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); + buffer->base.refcount = 1; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + buffer->shm = 0; + + return &buffer->base; +} + + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +xm_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + /* XXX a bit of a hack */ + surf->stride * round_up(surf->nblocksy, TILE_SIZE)); + + if(!surf->buffer) + return -1; + + return 0; +} + + +/** + * Called via winsys->surface_alloc() to create new surfaces. + */ +static struct pipe_surface * +xm_surface_alloc(struct pipe_winsys *ws) +{ + struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); + + assert(ws); + + surface->refcount = 1; + surface->winsys = ws; + + return surface; +} + + + +static void +xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + assert(!surf->texture); + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + winsys_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + +/* + * Fence functions - basically nothing to do, as we don't create any actual + * fence objects. + */ + +static void +xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + + +static struct pipe_winsys * +xlib_create_cell_winsys( void ) +{ + static struct xmesa_pipe_winsys *ws = NULL; + + if (!ws) { + ws = CALLOC_STRUCT(xmesa_pipe_winsys); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + */ + ws->base.buffer_create = xm_buffer_create; + ws->base.user_buffer_create = xm_user_buffer_create; + ws->base.buffer_map = xm_buffer_map; + ws->base.buffer_unmap = xm_buffer_unmap; + ws->base.buffer_destroy = xm_buffer_destroy; + + ws->base.surface_alloc = xm_surface_alloc; + ws->base.surface_alloc_storage = xm_surface_alloc_storage; + ws->base.surface_release = xm_surface_release; + + ws->base.fence_reference = xm_fence_reference; + ws->base.fence_signalled = xm_fence_signalled; + ws->base.fence_finish = xm_fence_finish; + + ws->base.flush_frontbuffer = xm_flush_frontbuffer; + ws->base.get_name = xm_get_name; + } + + return &ws->base; +} + + +static struct pipe_screen * +xlib_create_cell_screen( struct pipe_winsys *pws ) +{ + return cell_create_screen( pws ); +} + + +static struct pipe_context * +xlib_create_cell_context( struct pipe_screen *screen, + void *priv ) +{ + struct pipe_context *pipe; + + + /* This takes a cell_winsys pointer, but probably that should be + * created and stored at screen creation, not context creation. + * + * The actual cell_winsys value isn't used for anything, so just + * passing NULL for now. + */ + pipe = cell_create_context( screen, NULL); + if (pipe == NULL) + goto fail; + + pipe->priv = priv; + + return pipe; + +fail: + return NULL; +} + +struct xm_driver xlib_cell_driver = +{ + .create_pipe_winsys = xlib_create_cell_winsys, + .create_pipe_screen = xlib_create_cell_screen, + .create_pipe_context = xlib_create_cell_context, + .display_surface = xlib_cell_display_surface, +}; + +#else + +struct xm_driver xlib_cell_driver = +{ + .create_pipe_winsys = NULL, + .create_pipe_screen = NULL, + .create_pipe_context = NULL, + .display_surface = NULL, +}; + +#endif diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index 7ad73be260..775e345c2b 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -46,14 +46,6 @@ #include "util/u_memory.h" #include "softpipe/sp_winsys.h" -#ifdef GALLIUM_CELL -#include "cell/ppu/cell_context.h" -#include "cell/ppu/cell_screen.h" -#include "cell/ppu/cell_winsys.h" -#else -#define TILE_SIZE 32 /* avoid compilation errors */ -#endif - #include "xlib.h" /** @@ -69,9 +61,7 @@ struct xm_buffer XImage *tempImage; int shm; -#if defined(USE_XSHM) XShmSegmentInfo shminfo; -#endif }; @@ -98,8 +88,6 @@ xm_buffer( struct pipe_buffer *buf ) /** * X Shared Memory Image extension code */ -#if defined(USE_XSHM) - #define XSHM_ENABLED(b) ((b)->shm) static volatile int mesaXErrorFlag = 0; @@ -150,9 +138,6 @@ alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, * errors at different points if the extension won't work. Therefore * we have to be very careful... */ -#if 0 - GC gc; -#endif int (*old_handler)(Display *, XErrorEvent *); b->tempImage = XShmCreateImage(xmb->xm_visual->display, @@ -184,40 +169,8 @@ alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, (void) XSetErrorHandler(old_handler); return; } - - - /* Finally, try an XShmPutImage to be really sure the extension works */ -#if 0 - gc = XCreateGC(xmb->xm_visual->display, xmb->drawable, 0, NULL); - XShmPutImage(xmb->xm_visual->display, xmb->drawable, gc, - b->tempImage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False); - XSync(xmb->xm_visual->display, False); - XFreeGC(xmb->xm_visual->display, gc); - (void) XSetErrorHandler(old_handler); - if (mesaXErrorFlag) { - XFlush(xmb->xm_visual->display); - mesaXErrorFlag = 0; - XDestroyImage(b->tempImage); - b->tempImage = NULL; - b->shm = 0; - return; - } -#endif } -#else - -#define XSHM_ENABLED(b) 0 - -static void -alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, - unsigned width, unsigned height) -{ - b->shm = 0; -} -#endif /* USE_XSHM */ - - /* Most callbacks map direcly onto dri_bufmgr operations: @@ -245,7 +198,6 @@ xm_buffer_destroy(struct pipe_winsys *pws, struct xm_buffer *oldBuf = xm_buffer(buf); if (oldBuf->data) { -#if defined(USE_XSHM) if (oldBuf->shminfo.shmid >= 0) { shmdt(oldBuf->shminfo.shmaddr); shmctl(oldBuf->shminfo.shmid, IPC_RMID, 0); @@ -254,7 +206,6 @@ xm_buffer_destroy(struct pipe_winsys *pws, oldBuf->shminfo.shmaddr = (char *) -1; } else -#endif { if (!oldBuf->userBuffer) { align_free(oldBuf->data); @@ -268,107 +219,6 @@ xm_buffer_destroy(struct pipe_winsys *pws, } -/** - * For Cell. Basically, rearrange the pixels/quads from this layout: - * +--+--+--+--+ - * |p0|p1|p2|p3|.... - * +--+--+--+--+ - * - * to this layout: - * +--+--+ - * |p0|p1|.... - * +--+--+ - * |p2|p3| - * +--+--+ - */ -static void -twiddle_tile(const uint *tileIn, uint *tileOut) -{ - int y, x; - - for (y = 0; y < TILE_SIZE; y+=2) { - for (x = 0; x < TILE_SIZE; x+=2) { - int k = 4 * (y/2 * TILE_SIZE/2 + x/2); - tileOut[y * TILE_SIZE + (x + 0)] = tileIn[k]; - tileOut[y * TILE_SIZE + (x + 1)] = tileIn[k+1]; - tileOut[(y + 1) * TILE_SIZE + (x + 0)] = tileIn[k+2]; - tileOut[(y + 1) * TILE_SIZE + (x + 1)] = tileIn[k+3]; - } - } -} - - - -/** - * Display a surface that's in a tiled configuration. That is, all the - * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory. - */ -static void -xlib_cell_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf) -{ - XImage *ximage; - struct xm_buffer *xm_buf = xm_buffer(surf->buffer); - const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE; - uint x, y; - - if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { - alloc_shm_ximage(xm_buf, b, TILE_SIZE, TILE_SIZE); - } - - ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; - - /* check that the XImage has been previously initialized */ - assert(ximage->format); - assert(ximage->bitmap_unit); - - if (!XSHM_ENABLED(xm_buf)) { - /* update XImage's fields */ - ximage->width = TILE_SIZE; - ximage->height = TILE_SIZE; - ximage->bytes_per_line = TILE_SIZE * 4; - } - - for (y = 0; y < surf->height; y += TILE_SIZE) { - for (x = 0; x < surf->width; x += TILE_SIZE) { - uint tmpTile[TILE_SIZE * TILE_SIZE]; - int tx = x / TILE_SIZE; - int ty = y / TILE_SIZE; - int offset = ty * tilesPerRow + tx; - int w = TILE_SIZE; - int h = TILE_SIZE; - - if (y + h > surf->height) - h = surf->height - y; - if (x + w > surf->width) - w = surf->width - x; - - /* offset in pixels */ - offset *= TILE_SIZE * TILE_SIZE; - - if (0 && XSHM_ENABLED(xm_buf)) { - ximage->data = (char *) xm_buf->data + 4 * offset; - /* make copy of tile data */ - memcpy(tmpTile, (uint *) ximage->data, sizeof(tmpTile)); - /* twiddle from temp to ximage in shared memory */ - twiddle_tile(tmpTile, (uint *) ximage->data); - /* display image in shared memory */ -#if defined(USE_XSHM) - XShmPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, x, y, w, h, False); -#endif - } - else { - /* twiddle from ximage buffer to temp tile */ - twiddle_tile((uint *) xm_buf->data + offset, tmpTile); - /* display temp tile data */ - ximage->data = (char *) tmpTile; - XPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, x, y, w, h); - } - } - } -} - /** * Display/copy the image in the surface into the X window specified @@ -386,22 +236,12 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b, if (firsttime) { no_swap = getenv("SP_NO_RAST") != NULL; -#ifdef GALLIUM_CELL - if (!getenv("GALLIUM_NOCELL")) { - tileSize = 32; /** probably temporary */ - } -#endif firsttime = 0; } if (no_swap) return; - if (tileSize) { - xlib_cell_display_surface(b, surf); - return; - } - if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { assert(surf->block.width == 1); assert(surf->block.height == 1); @@ -413,10 +253,8 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b, /* display image in Window */ if (XSHM_ENABLED(xm_buf)) { -#if defined(USE_XSHM) XShmPutImage(b->xm_visual->display, b->drawable, b->gc, ximage, 0, 0, 0, 0, surf->width, surf->height, False); -#endif } else { /* check that the XImage has been previously initialized */ assert(ximage->format); @@ -462,17 +300,12 @@ xm_buffer_create(struct pipe_winsys *pws, unsigned size) { struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); -#if defined(USE_XSHM) struct xmesa_pipe_winsys *xpws = (struct xmesa_pipe_winsys *) pws; -#endif buffer->base.refcount = 1; buffer->base.alignment = alignment; buffer->base.usage = usage; buffer->base.size = size; - - -#if defined(USE_XSHM) buffer->shminfo.shmid = -1; buffer->shminfo.shmaddr = (char *) -1; @@ -483,7 +316,6 @@ xm_buffer_create(struct pipe_winsys *pws, buffer->data = buffer->shminfo.shmaddr; } } -#endif if (buffer->data == NULL) { buffer->shm = 0; @@ -545,11 +377,7 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, -#ifdef GALLIUM_CELL /* XXX a bit of a hack */ - surf->stride * round_up(surf->nblocksy, TILE_SIZE)); -#else surf->stride * surf->nblocksy); -#endif if(!surf->buffer) return -1; @@ -628,8 +456,6 @@ xlib_create_softpipe_winsys( void ) if (!ws) { ws = CALLOC_STRUCT(xmesa_pipe_winsys); - //ws->shm = xmesa_check_for_xshm( display ); - /* Fill in this struct with callbacks that pipe will need to * communicate with the window system, buffer manager, etc. */ @@ -698,75 +524,4 @@ struct xm_driver xlib_softpipe_driver = }; -/*********************************************************************** - * Cell piggybacks on softpipe code still. - * - * Should be untangled sufficiently to live in a separate file, at - * least. That would mean removing #ifdef GALLIUM_CELL's from above - * and creating cell-specific versions of either those functions or - * the entire file. - */ -#ifdef GALLIUM_CELL - -static struct pipe_winsys * -xlib_create_cell_winsys( void ) -{ - return xlib_create_softpipe_winsys(); -} - -static struct pipe_screen * -xlib_create_cell_screen( struct pipe_winsys *pws ) -{ - return cell_create_screen( pws ); -} - - -static struct pipe_context * -xlib_create_cell_context( struct pipe_screen *screen, - void *priv ) -{ - struct cell_winsys *cws; - struct pipe_context *pipe; - - if (getenv("GALLIUM_NOCELL")) - return xlib_create_softpipe_context( screen, priv ); - - - /* This takes a cell_winsys pointer, but probably that should be - * created and stored at screen creation, not context creation. - * - * The actual cell_winsys value isn't used for anything, so just - * passing NULL for now. - */ - pipe = cell_create_context( screen, NULL); - if (pipe == NULL) - goto fail; - - pipe->priv = priv; - - return pipe; - -fail: - return NULL; -} -#endif - -#if defined(GALLIUM_CELL) -struct xm_driver xlib_cell_driver = -{ - .create_pipe_winsys = xlib_create_cell_winsys, - .create_pipe_screen = xlib_create_cell_screen, - .create_pipe_context = xlib_create_cell_context, - .display_surface = xlib_cell_display_surface, -}; -#else -struct xm_driver xlib_cell_driver = -{ - .create_pipe_winsys = xlib_create_softpipe_winsys, - .create_pipe_screen = xlib_create_softpipe_screen, - .create_pipe_context = xlib_create_softpipe_context, - .display_surface = xlib_softpipe_display_surface, -}; -#endif - -- cgit v1.2.3 From 529f86fb113529d1ecf113dc45efade7fe185f94 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 5 Jan 2009 11:44:56 +0100 Subject: intel: Add a none working GEM backend for intel --- src/gallium/winsys/drm/intel/gem/Makefile | 18 ++ src/gallium/winsys/drm/intel/gem/Makefile.template | 64 +++++ .../winsys/drm/intel/gem/intel_be_batchbuffer.c | 120 ++++++++++ .../winsys/drm/intel/gem/intel_be_batchbuffer.h | 55 +++++ .../winsys/drm/intel/gem/intel_be_context.c | 79 +++++++ .../winsys/drm/intel/gem/intel_be_context.h | 48 ++++ src/gallium/winsys/drm/intel/gem/intel_be_device.c | 260 +++++++++++++++++++++ src/gallium/winsys/drm/intel/gem/intel_be_device.h | 70 ++++++ src/gallium/winsys/drm/intel/gem/intel_be_fence.h | 38 +++ 9 files changed, 752 insertions(+) create mode 100644 src/gallium/winsys/drm/intel/gem/Makefile create mode 100644 src/gallium/winsys/drm/intel/gem/Makefile.template create mode 100644 src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c create mode 100644 src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h create mode 100644 src/gallium/winsys/drm/intel/gem/intel_be_context.c create mode 100644 src/gallium/winsys/drm/intel/gem/intel_be_context.h create mode 100644 src/gallium/winsys/drm/intel/gem/intel_be_device.c create mode 100644 src/gallium/winsys/drm/intel/gem/intel_be_device.h create mode 100644 src/gallium/winsys/drm/intel/gem/intel_be_fence.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/Makefile b/src/gallium/winsys/drm/intel/gem/Makefile new file mode 100644 index 0000000000..b25fc258f4 --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/Makefile @@ -0,0 +1,18 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +LIBNAME = inteldrm + +C_SOURCES = \ + intel_be_batchbuffer.c \ + intel_be_context.c \ + intel_be_device.c + + +include ./Makefile.template + +DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \ + && pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") +symlinks: + diff --git a/src/gallium/winsys/drm/intel/gem/Makefile.template b/src/gallium/winsys/drm/intel/gem/Makefile.template new file mode 100644 index 0000000000..557070ae02 --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/Makefile.template @@ -0,0 +1,64 @@ +# -*-makefile-*- + + +# We still have a dependency on the "dri" buffer manager. Most likely +# the interface can be reused in non-dri environments, and also as a +# frontend to simpler memory managers. +# +COMMON_SOURCES = + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(CPP_SOURCES:.cpp=.o) \ + $(ASM_SOURCES:.S=.o) + + +### Include directories +INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/include \ + $(DRIVER_INCLUDES) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) + + +$(LIBNAME): $(OBJECTS) Makefile Makefile.template + $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) + + +depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean:: + -rm -f *.o */*.o *~ *.so *.a *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +include depend diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c new file mode 100644 index 0000000000..2399910613 --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c @@ -0,0 +1,120 @@ + +#include "intel_be_batchbuffer.h" +#include "intel_be_context.h" +#include "intel_be_device.h" +#include "intel_be_fence.h" +#include + +#include "util/u_memory.h" + +struct intel_be_batchbuffer * +intel_be_batchbuffer_alloc(struct intel_be_context *intel) +{ + struct intel_be_batchbuffer *batch = CALLOC_STRUCT(intel_be_batchbuffer); + + batch->base.buffer = NULL; + batch->base.winsys = &intel->base; + batch->base.map = NULL; + batch->base.ptr = NULL; + batch->base.size = 0; + batch->base.actual_size = intel->device->max_batch_size; + batch->base.relocs = 0; + batch->base.max_relocs = INTEL_DEFAULT_RELOCS; + + batch->base.map = malloc(batch->base.actual_size); + memset(batch->base.map, 0, batch->base.actual_size); + + batch->base.ptr = batch->base.map; + + intel_be_batchbuffer_reset(batch); + + return NULL; +} + +void +intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch) +{ + struct intel_be_context *intel = intel_be_context(batch->base.winsys); + struct intel_be_device *dev = intel->device; + + if (batch->bo) + drm_intel_bo_unreference(batch->bo); + + memset(batch->base.map, 0, batch->base.actual_size); + batch->base.ptr = batch->base.map; + batch->base.size = batch->base.actual_size - BATCH_RESERVED; + + batch->base.relocs = 0; + batch->base.max_relocs = INTEL_DEFAULT_RELOCS; + + batch->bo = drm_intel_bo_alloc(dev->pools.gem, + "gallium3d_batch_buffer", + batch->base.actual_size, 0); +} + +int +intel_be_offset_relocation(struct intel_be_batchbuffer *batch, + unsigned pre_add, + drm_intel_bo *bo, + uint32_t read_domains, + uint32_t write_domain) +{ + unsigned offset; + int ret = 0; + + assert(batch->base.relocs < batch->base.max_relocs); + + offset = (unsigned)(batch->base.ptr - batch->base.map); + batch->base.ptr += 4; + +/* + TODO: Enable this when we submit batch buffers to HW + ret = drm_intel_bo_emit_reloc(bo, pre_add, + batch->bo, offset, + read_domains, + write_domain); +*/ + + if (!ret) + batch->base.relocs++; + + return ret; +} + +void +intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch, + struct intel_be_fence **fence) +{ + struct i915_batchbuffer *i915 = &batch->base; + + assert(i915_batchbuffer_space(i915) >= 0); + + /* TODO: submit stuff to HW */ + + intel_be_batchbuffer_reset(batch); + + if (fence) { + if (*fence) + intel_be_fence_unreference(*fence); + + (*fence) = CALLOC_STRUCT(intel_be_fence); + (*fence)->refcount = 1; + (*fence)->bo = NULL; + } +} + +void +intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch) +{ + +} + +void +intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch) +{ + if (batch->bo) + drm_intel_bo_unreference(batch->bo); + + free(batch->base.map); + free(batch); +} diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h new file mode 100644 index 0000000000..195bf8dee7 --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h @@ -0,0 +1,55 @@ + +#ifndef INTEL_BE_BATCHBUFFER_H +#define INTEL_BE_BATCHBUFFER_H + +#include "i915simple/i915_batch.h" + +#include "drm.h" +#include "intel_bufmgr.h" + +#define BATCH_RESERVED 16 + +#define INTEL_DEFAULT_RELOCS 100 +#define INTEL_MAX_RELOCS 400 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct intel_be_context; +struct intel_be_device; +struct intel_be_fence; + +struct intel_be_batchbuffer +{ + struct i915_batchbuffer base; + + struct intel_be_context *intel; + struct intel_be_device *device; + + drm_intel_bo *bo; +}; + +struct intel_be_batchbuffer * +intel_be_batchbuffer_alloc(struct intel_be_context *intel); + +void +intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch); + +void +intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch); + +void +intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch, + struct intel_be_fence **fence); + +void +intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch); + +int +intel_be_offset_relocation(struct intel_be_batchbuffer *batch, + unsigned pre_add, + drm_intel_bo *bo, + uint32_t read_domains, + uint32_t write_doman); + +#endif diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c new file mode 100644 index 0000000000..92fc2dd767 --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c @@ -0,0 +1,79 @@ + +#include "intel_be_device.h" +#include "intel_be_context.h" +#include "intel_be_batchbuffer.h" + +#include "i915_drm.h" + +static struct i915_batchbuffer * +intel_be_batch_get(struct i915_winsys *sws) +{ + struct intel_be_context *intel = intel_be_context(sws); + return &intel->batch->base; +} + +static void +intel_be_batch_reloc(struct i915_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta) +{ + struct intel_be_context *intel = intel_be_context(sws); + drm_intel_bo *bo = intel_bo(buf); + int ret; + uint32_t read = 0; + uint32_t write = 0; + + if (access_flags & I915_BUFFER_ACCESS_WRITE) { + write = I915_GEM_DOMAIN_RENDER; + } + + if (access_flags & I915_BUFFER_ACCESS_READ) { + read = I915_GEM_DOMAIN_SAMPLER | + I915_GEM_DOMAIN_INSTRUCTION | + I915_GEM_DOMAIN_VERTEX; + } + + ret = intel_be_offset_relocation(intel->batch, + delta, + bo, + read, + write); + /* TODO change return type */ + /* return ret; */ +} + +static void +intel_be_batch_flush(struct i915_winsys *sws, + struct pipe_fence_handle **fence) +{ + struct intel_be_context *intel = intel_be_context(sws); + struct intel_be_fence **f = (struct intel_be_fence **)fence; + + if (fence && *fence) + assert(0); + + intel_be_batchbuffer_flush(intel->batch, f); +} + +boolean +intel_be_init_context(struct intel_be_context *intel, struct intel_be_device *device) +{ + assert(intel); + assert(device); + intel->device = device; + + intel->base.batch_get = intel_be_batch_get; + intel->base.batch_reloc = intel_be_batch_reloc; + intel->base.batch_flush = intel_be_batch_flush; + + intel->batch = intel_be_batchbuffer_alloc(intel); + + return true; +} + +void +intel_be_destroy_context(struct intel_be_context *intel) +{ + intel_be_batchbuffer_free(intel->batch); +} diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.h b/src/gallium/winsys/drm/intel/gem/intel_be_context.h new file mode 100644 index 0000000000..9cee1a4e52 --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.h @@ -0,0 +1,48 @@ + +#ifndef INTEL_BE_CONTEXT_H +#define INTEL_BE_CONTEXT_H + +#include "i915simple/i915_winsys.h" + +struct intel_be_context +{ + /** Interface to i915simple driver */ + struct i915_winsys base; + + struct intel_be_device *device; + struct intel_be_batchbuffer *batch; + + /* + * Hardware lock functions. + * + * Needs to be filled in by the winsys. + */ + void (*hardware_lock)(struct intel_be_context *context); + void (*hardware_unlock)(struct intel_be_context *context); + boolean (*hardware_locked)(struct intel_be_context *context); +}; + +static INLINE struct intel_be_context * +intel_be_context(struct i915_winsys *sws) +{ + return (struct intel_be_context *)sws; +} + +/** + * Intialize a allocated intel_be_context struct. + * + * Remember to set the hardware_* functions. + */ +boolean +intel_be_init_context(struct intel_be_context *intel, + struct intel_be_device *device); + +/** + * Destroy a intel_be_context. + * + * Does not free the struct that is up to the winsys. + */ +void +intel_be_destroy_context(struct intel_be_context *intel); + +#endif diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c new file mode 100644 index 0000000000..cf0c1408dc --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c @@ -0,0 +1,260 @@ + +#include "intel_be_device.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" +#include "util/u_memory.h" + +#include "intel_be_fence.h" + +#include "i915simple/i915_screen.h" + + +/** + * Turn a pipe winsys into an intel/pipe winsys: + */ +static INLINE struct intel_be_device * +intel_be_device(struct pipe_winsys *winsys) +{ + return (struct intel_be_device *)winsys; +} + +/* + * Buffer + */ + +static void * +intel_be_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags) +{ + drm_intel_bo *bo = intel_bo(buf); + int write = 0; + int ret; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + write = 1; + + ret = drm_intel_bo_map(bo, write); + + if (ret) + return NULL; + + return bo->virtual; +} + +static void +intel_be_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + drm_intel_bo_unmap(intel_bo(buf)); +} + +static void +intel_be_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + drm_intel_bo_unreference(intel_bo(buf)); + free(buf); +} + +static struct pipe_buffer * +intel_be_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer); + struct intel_be_device *dev = intel_be_device(winsys); + drm_intel_bufmgr *pool; + char *name; + + if (!buffer) + return NULL; + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { + /* Local buffer */ + name = "gallium3d_local"; + pool = dev->pools.gem; + } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { + /* For vertex buffers */ + name = "gallium3d_internal_vertex"; + pool = dev->pools.gem; + } else { + /* Regular buffers */ + name = "gallium3d_regular"; + pool = dev->pools.gem; + } + + buffer->bo = drm_intel_bo_alloc(pool, name, size, alignment); + + if (!buffer->bo) + goto err; + + return &buffer->base; + +err: + free(buffer); + return NULL; +} + +static struct pipe_buffer * +intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) +{ + struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer); + struct intel_be_device *dev = intel_be_device(winsys); + int ret; + + if (!buffer) + return NULL; + + buffer->base.refcount = 1; + buffer->base.alignment = 0; + buffer->base.usage = 0; + buffer->base.size = bytes; + + buffer->bo = drm_intel_bo_alloc(dev->pools.gem, + "gallium3d_user_buffer", + bytes, 0); + + if (!buffer->bo) + goto err; + + ret = drm_intel_bo_subdata(buffer->bo, + 0, bytes, ptr); + + if (ret) + goto err; + + return &buffer->base; + +err: + free(buffer); + return NULL; +} + +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *dev, + const char* name, unsigned handle) +{ + struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer); + + if (!buffer) + return NULL; + + buffer->bo = drm_intel_bo_gem_create_from_name(dev->pools.gem, name, handle); + + if (!buffer->bo) + goto err; + + buffer->base.refcount = 1; + buffer->base.alignment = buffer->bo->align; + buffer->base.usage = PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE | + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE; + buffer->base.size = buffer->bo->size; + + return &buffer->base; + +err: + free(buffer); + return NULL; +} + +/* + * Fence + */ + +static void +intel_be_fence_refunref(struct pipe_winsys *sws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ + struct intel_be_fence **p = (struct intel_be_fence **)ptr; + struct intel_be_fence *f = (struct intel_be_fence *)fence; + + assert(p); + + if (f) + intel_be_fence_reference(f); + + if (*p) + intel_be_fence_unreference(*p); + + *p = f; +} + +static int +intel_be_fence_signalled(struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag) +{ + assert(0); + + return 0; +} + +static int +intel_be_fence_finish(struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag) +{ + struct intel_be_fence *f = (struct intel_be_fence *)fence; + + /* fence already expired */ + if (!f->bo) + return 0; + + drm_intel_bo_wait_rendering(f->bo); + drm_intel_bo_unreference(f->bo); + f->bo = NULL; + + return 0; +} + +/* + * Misc functions + */ + +boolean +intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id) +{ + dev->fd = fd; + dev->max_batch_size = 16 * 4096; + dev->max_vertex_size = 128 * 4096; + + dev->base.buffer_create = intel_be_buffer_create; + dev->base.user_buffer_create = intel_be_user_buffer_create; + dev->base.buffer_map = intel_be_buffer_map; + dev->base.buffer_unmap = intel_be_buffer_unmap; + dev->base.buffer_destroy = intel_be_buffer_destroy; + + /* Not used anymore */ + dev->base.surface_alloc = NULL; + dev->base.surface_alloc_storage = NULL; + dev->base.surface_release = NULL; + + dev->base.fence_reference = intel_be_fence_refunref; + dev->base.fence_signalled = intel_be_fence_signalled; + dev->base.fence_finish = intel_be_fence_finish; + + dev->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size); + + dev->screen = i915_create_screen(&dev->base, id); + + return true; +} + +void +intel_be_destroy_device(struct intel_be_device *dev) +{ + drm_intel_bufmgr_destroy(dev->pools.gem); +} diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.h b/src/gallium/winsys/drm/intel/gem/intel_be_device.h new file mode 100644 index 0000000000..53d63536c9 --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h @@ -0,0 +1,70 @@ + +#ifndef INTEL_DRM_DEVICE_H +#define INTEL_DRM_DEVICE_H + +#include "pipe/p_winsys.h" +#include "pipe/p_context.h" + +#include "drm.h" +#include "intel_bufmgr.h" + +/* + * Device + */ + +struct intel_be_device +{ + struct pipe_winsys base; + + /** + * Hw level screen + */ + struct pipe_screen *screen; + + int fd; /**< Drm file discriptor */ + + size_t max_batch_size; + size_t max_vertex_size; + + struct { + drm_intel_bufmgr *gem; + } pools; +}; + +boolean +intel_be_init_device(struct intel_be_device *device, int fd, unsigned id); + +void +intel_be_destroy_device(struct intel_be_device *dev); + +/* + * Buffer + */ + +struct intel_be_buffer { + struct pipe_buffer base; + drm_intel_bo *bo; +}; + +/** + * Create a be buffer from a drm bo handle + * + * Takes a reference + */ +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle); + +static INLINE struct intel_be_buffer * +intel_be_buffer(struct pipe_buffer *buf) +{ + return (struct intel_be_buffer *)buf; +} + +static INLINE drm_intel_bo * +intel_bo(struct pipe_buffer *buf) +{ + return intel_be_buffer(buf)->bo; +} + +#endif diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_fence.h b/src/gallium/winsys/drm/intel/gem/intel_be_fence.h new file mode 100644 index 0000000000..0fe18f66f8 --- /dev/null +++ b/src/gallium/winsys/drm/intel/gem/intel_be_fence.h @@ -0,0 +1,38 @@ + +#ifndef INTEL_BE_FENCE_H +#define INTEL_BE_FENCE_H + +#include "pipe/p_defines.h" + +#include "drm.h" +#include "intel_bufmgr.h" + +/** + * Because gem does not have fence's we have to create our own fences. + * + * They work by keeping the batchbuffer around and checking if that has + * been idled. If bo is NULL fence has expired. + */ +struct intel_be_fence +{ + uint32_t refcount; + drm_intel_bo *bo; +}; + +static INLINE void +intel_be_fence_reference(struct intel_be_fence *f) +{ + f->refcount++; +} + +static INLINE void +intel_be_fence_unreference(struct intel_be_fence *f) +{ + if (!--f->refcount) { + if (f->bo) + drm_intel_bo_unreference(f->bo); + free(f); + } +} + +#endif -- cgit v1.2.3 From bcc45a202496fba9686f953011039c09e36bf3ae Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 17 Jan 2009 17:12:30 +0000 Subject: xlib: don't explicitly create the pipe_winsys struct --- src/gallium/winsys/xlib/xlib_brw_screen.c | 22 +++++++++++++++++++--- src/gallium/winsys/xlib/xlib_cell.c | 21 ++++++++++++++++++--- src/gallium/winsys/xlib/xlib_softpipe.c | 14 ++++++++++---- src/gallium/winsys/xlib/xlib_trace.c | 15 ++++++--------- 4 files changed, 53 insertions(+), 19 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c index 1e4c2f6c41..030cd66bd9 100644 --- a/src/gallium/winsys/xlib/xlib_brw_screen.c +++ b/src/gallium/winsys/xlib/xlib_brw_screen.c @@ -351,9 +351,26 @@ xlib_create_brw_winsys( void ) static struct pipe_screen * -xlib_create_brw_screen( struct pipe_winsys *winsys ) +xlib_create_brw_screen( void ) { - return brw_create_screen(winsys, 0/* XXX pci_id */); + struct pipe_winsys *winsys; + struct pipe_screen *screen; + + winsys = xlib_create_brw_winsys(); + if (winsys == NULL) + return NULL; + + screen = brw_create_screen(winsys, 0/* XXX pci_id */); + if (screen == NULL) + goto fail; + + return screen; + +fail: + if (winsys) + winsys->destroy( winsys ); + + return NULL; } @@ -473,7 +490,6 @@ xlib_brw_display_surface(struct xmesa_buffer *b, struct xm_driver xlib_brw_driver = { - .create_pipe_winsys = xlib_create_brw_winsys, .create_pipe_screen = xlib_create_brw_screen, .create_pipe_context = xlib_create_brw_context, .display_surface = xlib_brw_display_surface, diff --git a/src/gallium/winsys/xlib/xlib_cell.c b/src/gallium/winsys/xlib/xlib_cell.c index 5fe406d5ab..93bc8ecd81 100644 --- a/src/gallium/winsys/xlib/xlib_cell.c +++ b/src/gallium/winsys/xlib/xlib_cell.c @@ -414,7 +414,24 @@ xlib_create_cell_winsys( void ) static struct pipe_screen * xlib_create_cell_screen( struct pipe_winsys *pws ) { - return cell_create_screen( pws ); + struct pipe_winsys *winsys; + struct pipe_screen *screen; + + winsys = xlib_create_cell_winsys(); + if (winsys == NULL) + return NULL; + + screen = cell_create_screen(winsys); + if (screen == NULL) + goto fail; + + return screen; + +fail: + if (winsys) + winsys->destroy( winsys ); + + return NULL; } @@ -445,7 +462,6 @@ fail: struct xm_driver xlib_cell_driver = { - .create_pipe_winsys = xlib_create_cell_winsys, .create_pipe_screen = xlib_create_cell_screen, .create_pipe_context = xlib_create_cell_context, .display_surface = xlib_cell_display_surface, @@ -455,7 +471,6 @@ struct xm_driver xlib_cell_driver = struct xm_driver xlib_cell_driver = { - .create_pipe_winsys = NULL, .create_pipe_screen = NULL, .create_pipe_context = NULL, .display_surface = NULL, diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index 775e345c2b..e8513069fe 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -232,7 +232,6 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b, struct xm_buffer *xm_buf = xm_buffer(surf->buffer); static boolean no_swap = 0; static boolean firsttime = 1; - static int tileSize = 0; if (firsttime) { no_swap = getenv("SP_NO_RAST") != NULL; @@ -482,17 +481,25 @@ xlib_create_softpipe_winsys( void ) static struct pipe_screen * -xlib_create_softpipe_screen( struct pipe_winsys *pws ) +xlib_create_softpipe_screen( void ) { + struct pipe_winsys *winsys; struct pipe_screen *screen; - screen = softpipe_create_screen(pws); + winsys = xlib_create_softpipe_winsys(); + if (winsys == NULL) + return NULL; + + screen = softpipe_create_screen(winsys); if (screen == NULL) goto fail; return screen; fail: + if (winsys) + winsys->destroy( winsys ); + return NULL; } @@ -517,7 +524,6 @@ fail: struct xm_driver xlib_softpipe_driver = { - .create_pipe_winsys = xlib_create_softpipe_winsys, .create_pipe_screen = xlib_create_softpipe_screen, .create_pipe_context = xlib_create_softpipe_context, .display_surface = xlib_softpipe_display_surface diff --git a/src/gallium/winsys/xlib/xlib_trace.c b/src/gallium/winsys/xlib/xlib_trace.c index 1b8d3f8a11..37095c5d8e 100644 --- a/src/gallium/winsys/xlib/xlib_trace.c +++ b/src/gallium/winsys/xlib/xlib_trace.c @@ -38,19 +38,16 @@ #include "trace/tr_screen.h" #include "trace/tr_context.h" +#include "pipe/p_screen.h" + -static struct pipe_winsys * -xlib_create_trace_winsys( void ) -{ - return xlib_softpipe_driver.create_pipe_winsys(); -} static struct pipe_screen * -xlib_create_trace_screen( struct pipe_winsys *winsys ) +xlib_create_trace_screen( void ) { struct pipe_screen *screen, *trace_screen; - screen = xlib_softpipe_driver.create_pipe_screen( winsys ); + screen = xlib_softpipe_driver.create_pipe_screen(); if (screen == NULL) goto fail; @@ -63,7 +60,8 @@ xlib_create_trace_screen( struct pipe_winsys *winsys ) return trace_screen; fail: - /* free stuff */ + if (screen) + screen->destroy( screen ); return NULL; } @@ -103,7 +101,6 @@ xlib_trace_display_surface( struct xmesa_buffer *buffer, struct xm_driver xlib_trace_driver = { - .create_pipe_winsys = xlib_create_trace_winsys, .create_pipe_screen = xlib_create_trace_screen, .create_pipe_context = xlib_create_trace_context, .display_surface = xlib_trace_display_surface, -- cgit v1.2.3 From a874cf37ee2a792991819cad2cb73e3d2ddc87a3 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sun, 18 Jan 2009 15:35:50 +0100 Subject: i915: Update gem backend a bit --- .../winsys/drm/intel/gem/intel_be_batchbuffer.c | 3 ++- src/gallium/winsys/drm/intel/gem/intel_be_device.c | 15 +++++++++++---- src/gallium/winsys/drm/intel/gem/intel_be_device.h | 20 ++++++++++++-------- 3 files changed, 25 insertions(+), 13 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c index 2399910613..af5c027748 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c @@ -12,6 +12,7 @@ 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; @@ -28,7 +29,7 @@ intel_be_batchbuffer_alloc(struct intel_be_context *intel) intel_be_batchbuffer_reset(batch); - return NULL; + return batch; } void diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c index cf0c1408dc..201a485049 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c @@ -141,9 +141,10 @@ err: } struct pipe_buffer * -intel_be_buffer_from_handle(struct intel_be_device *dev, - const char* name, unsigned handle) +intel_be_buffer_from_handle(struct pipe_winsys *winsys, + const char* name, unsigned handle) { + struct intel_be_device *dev = intel_be_device(winsys); struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer); if (!buffer) @@ -169,6 +170,14 @@ err: return NULL; } +unsigned +intel_be_handle_from_buffer(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + drm_intel_bo *bo = intel_bo(buf); + return bo->handle; +} + /* * Fence */ @@ -248,8 +257,6 @@ intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id) dev->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size); - dev->screen = i915_create_screen(&dev->base, id); - return true; } diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.h b/src/gallium/winsys/drm/intel/gem/intel_be_device.h index 53d63536c9..96e94c47e7 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h +++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h @@ -16,11 +16,6 @@ struct intel_be_device { struct pipe_winsys base; - /** - * Hw level screen - */ - struct pipe_screen *screen; - int fd; /**< Drm file discriptor */ size_t max_batch_size; @@ -47,14 +42,23 @@ struct intel_be_buffer { }; /** - * Create a be buffer from a drm bo handle + * Create a be buffer from a drm bo handle. * - * Takes a reference + * Takes a reference. */ struct pipe_buffer * -intel_be_buffer_from_handle(struct intel_be_device *device, +intel_be_buffer_from_handle(struct pipe_winsys *winsys, const char* name, unsigned handle); +/** + * Gets a handle from a buffer. + * + * If buffer is destroyed handle may become invalid. + */ +unsigned +intel_be_handle_from_buffer(struct pipe_winsys *winsys, + struct pipe_buffer *buffer); + static INLINE struct intel_be_buffer * intel_be_buffer(struct pipe_buffer *buf) { -- cgit v1.2.3 From df3ef7a8d6473238da57ab47b6de027bb427f395 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sun, 18 Jan 2009 15:49:06 +0100 Subject: i915: Use new egl state_tracker --- src/gallium/winsys/drm/Makefile.template | 4 +- src/gallium/winsys/drm/intel/egl/Makefile | 10 +- src/gallium/winsys/drm/intel/egl/SConscript | 39 - src/gallium/winsys/drm/intel/egl/intel_api.c | 10 + src/gallium/winsys/drm/intel/egl/intel_api.h | 14 + .../winsys/drm/intel/egl/intel_batchbuffer.h | 24 - src/gallium/winsys/drm/intel/egl/intel_context.c | 211 +----- src/gallium/winsys/drm/intel/egl/intel_context.h | 118 --- src/gallium/winsys/drm/intel/egl/intel_device.c | 145 +--- src/gallium/winsys/drm/intel/egl/intel_device.h | 50 -- src/gallium/winsys/drm/intel/egl/intel_egl.c | 796 --------------------- src/gallium/winsys/drm/intel/egl/intel_egl.h | 53 -- src/gallium/winsys/drm/intel/egl/intel_reg.h | 53 -- .../winsys/drm/intel/egl/intel_swapbuffers.c | 111 --- 14 files changed, 86 insertions(+), 1552 deletions(-) delete mode 100644 src/gallium/winsys/drm/intel/egl/SConscript create mode 100644 src/gallium/winsys/drm/intel/egl/intel_api.c create mode 100644 src/gallium/winsys/drm/intel/egl/intel_api.h delete mode 100644 src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h delete mode 100644 src/gallium/winsys/drm/intel/egl/intel_context.h delete mode 100644 src/gallium/winsys/drm/intel/egl/intel_device.h delete mode 100644 src/gallium/winsys/drm/intel/egl/intel_egl.c delete mode 100644 src/gallium/winsys/drm/intel/egl/intel_egl.h delete mode 100644 src/gallium/winsys/drm/intel/egl/intel_reg.h delete mode 100644 src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template index 80e817b808..211f4d875e 100644 --- a/src/gallium/winsys/drm/Makefile.template +++ b/src/gallium/winsys/drm/Makefile.template @@ -84,14 +84,14 @@ default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(LIBNAME_EGL) $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template $(TOP)/bin/mklib -noprefix -o $@ \ - $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) + $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS) $(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS) $(TOP)/bin/mklib -o $(LIBNAME_EGL) \ -linker "$(CC)" \ -noprefix \ $(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \ - --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive + --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive $(DRIVER_EXTRAS) $(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile index f0b5a44389..4b22d17ccf 100644 --- a/src/gallium/winsys/drm/intel/egl/Makefile +++ b/src/gallium/winsys/drm/intel/egl/Makefile @@ -6,21 +6,23 @@ LIBNAME = EGL_i915.so PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ - ../common/libinteldrm.a + $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ + ../gem/libinteldrm.a DRIVER_SOURCES = \ - intel_swapbuffers.c \ intel_context.c \ intel_device.c \ - intel_egl.c + intel_api.c C_SOURCES = \ $(COMMON_GALLIUM_SOURCES) \ $(DRIVER_SOURCES) +DRIVER_EXTRAS = -ldrm_intel + ASM_SOURCES = -DRIVER_DEFINES = -I../common $(shell pkg-config libdrm --atleast-version=2.3.1 \ +DRIVER_DEFINES = -I../gem $(shell pkg-config libdrm --atleast-version=2.3.1 \ && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") include ../../Makefile.template diff --git a/src/gallium/winsys/drm/intel/egl/SConscript b/src/gallium/winsys/drm/intel/egl/SConscript deleted file mode 100644 index 0ad19d42a8..0000000000 --- a/src/gallium/winsys/drm/intel/egl/SConscript +++ /dev/null @@ -1,39 +0,0 @@ -Import('*') - -env = drienv.Clone() - -env.Append(CPPPATH = [ - '../intel', - 'server' -]) - -#MINIGLX_SOURCES = server/intel_dri.c - -DRIVER_SOURCES = [ - 'intel_winsys_pipe.c', - 'intel_winsys_softpipe.c', - 'intel_winsys_i915.c', - 'intel_batchbuffer.c', - 'intel_swapbuffers.c', - 'intel_context.c', - 'intel_lock.c', - 'intel_screen.c', - 'intel_batchpool.c', -] - -sources = \ - COMMON_GALLIUM_SOURCES + \ - COMMON_BM_SOURCES + \ - DRIVER_SOURCES - -drivers = [ - softpipe, - i915simple -] - -# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -env.SharedLibrary( - target ='i915tex_dri.so', - source = sources, - LIBS = drivers + mesa + auxiliaries + env['LIBS'], -) \ No newline at end of file diff --git a/src/gallium/winsys/drm/intel/egl/intel_api.c b/src/gallium/winsys/drm/intel/egl/intel_api.c new file mode 100644 index 0000000000..5dc4a7b052 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_api.c @@ -0,0 +1,10 @@ + +#include "intel_api.h" + +struct drm_api drm_api_hocks = +{ + .create_screen = intel_create_screen, + .create_context = intel_create_context, + .buffer_from_handle = intel_be_buffer_from_handle, + .handle_from_buffer = intel_be_handle_from_buffer, +}; diff --git a/src/gallium/winsys/drm/intel/egl/intel_api.h b/src/gallium/winsys/drm/intel/egl/intel_api.h new file mode 100644 index 0000000000..8ec165ab01 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_api.h @@ -0,0 +1,14 @@ + +#ifndef _INTEL_API_H_ +#define _INTEL_API_H_ + +#include "pipe/p_compiler.h" + +#include "state_tracker/drm_api.h" + +#include "intel_be_device.h" + +struct pipe_screen *intel_create_screen(int drmFD, int pciID); +struct pipe_context *intel_create_context(struct pipe_screen *screen); + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h b/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h deleted file mode 100644 index 3e95326168..0000000000 --- a/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef INTEL_BATCHBUFFER_H -#define INTEL_BATCHBUFFER_H - -#include "intel_be_batchbuffer.h" - -/* - * Need to redefine the BATCH defines - */ - -#undef BEGIN_BATCH -#define BEGIN_BATCH(dwords, relocs) \ - (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) - -#undef OUT_BATCH -#define OUT_BATCH(d) \ - i915_batchbuffer_dword(&intel->base.batch->base, d) - -#undef OUT_RELOC -#define OUT_RELOC(buf,flags,mask,delta) do { \ - assert((delta) >= 0); \ - intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ -} while (0) - -#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_context.c b/src/gallium/winsys/drm/intel/egl/intel_context.c index 927addb834..57e5ff7bc1 100644 --- a/src/gallium/winsys/drm/intel/egl/intel_context.c +++ b/src/gallium/winsys/drm/intel/egl/intel_context.c @@ -1,119 +1,21 @@ -/************************************************************************** - * - * 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 "i915simple/i915_screen.h" -#include "intel_device.h" -#include "intel_context.h" -#include "intel_batchbuffer.h" +#include "intel_be_device.h" +#include "intel_be_context.h" -#include "state_tracker/st_public.h" #include "pipe/p_defines.h" #include "pipe/p_context.h" -#include "intel_egl.h" -#include "utils.h" -#ifdef DEBUG -int __intel_debug = 0; -#endif +#include "intel_api.h" +struct intel_context +{ + struct intel_be_context base; -#define need_GL_ARB_multisample -#define need_GL_ARB_point_parameters -#define need_GL_ARB_texture_compression -#define need_GL_ARB_vertex_buffer_object -#define need_GL_ARB_vertex_program -#define need_GL_ARB_window_pos -#define need_GL_EXT_blend_color -#define need_GL_EXT_blend_equation_separate -#define need_GL_EXT_blend_func_separate -#define need_GL_EXT_blend_minmax -#define need_GL_EXT_cull_vertex -#define need_GL_EXT_fog_coord -#define need_GL_EXT_framebuffer_object -#define need_GL_EXT_multi_draw_arrays -#define need_GL_EXT_secondary_color -#define need_GL_NV_vertex_program -#include "extension_helper.h" - - -/** - * Extension strings exported by the intel driver. - * - * \note - * It appears that ARB_texture_env_crossbar has "disappeared" compared to the - * old i830-specific driver. - */ -const struct dri_extension card_extensions[] = { - {"GL_ARB_multisample", GL_ARB_multisample_functions}, - {"GL_ARB_multitexture", NULL}, - {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, - {"GL_ARB_texture_border_clamp", NULL}, - {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, - {"GL_ARB_texture_cube_map", NULL}, - {"GL_ARB_texture_env_add", NULL}, - {"GL_ARB_texture_env_combine", NULL}, - {"GL_ARB_texture_env_dot3", NULL}, - {"GL_ARB_texture_mirrored_repeat", NULL}, - {"GL_ARB_texture_rectangle", NULL}, - {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, - {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, - {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, - {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, - {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, - {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, - {"GL_EXT_blend_subtract", NULL}, - {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, - {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, - {"GL_EXT_packed_depth_stencil", NULL}, - {"GL_EXT_pixel_buffer_object", NULL}, - {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, - {"GL_EXT_stencil_wrap", NULL}, - {"GL_EXT_texture_edge_clamp", NULL}, - {"GL_EXT_texture_env_combine", NULL}, - {"GL_EXT_texture_env_dot3", NULL}, - {"GL_EXT_texture_filter_anisotropic", NULL}, - {"GL_EXT_texture_lod_bias", NULL}, - {"GL_3DFX_texture_compression_FXT1", NULL}, - {"GL_APPLE_client_storage", NULL}, - {"GL_MESA_pack_invert", NULL}, - {"GL_MESA_ycbcr_texture", NULL}, - {"GL_NV_blend_square", NULL}, - {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, - {"GL_NV_vertex_program1_1", NULL}, - {"GL_SGIS_generate_mipmap", NULL }, - {NULL, NULL} + /* stuff */ }; - /* * Hardware lock functions. * Doesn't do anything in EGL @@ -142,101 +44,40 @@ intel_locked_hardware(struct intel_be_context *context) /* * Misc functions. */ +static void +intel_destroy_be_context(struct i915_winsys *winsys) +{ + struct intel_context *intel = (struct intel_context *)winsys; + + intel_be_destroy_context(&intel->base); + free(intel); +} -int -intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) +struct pipe_context * +intel_create_context(struct pipe_screen *screen) { - struct intel_context *intel = CALLOC_STRUCT(intel_context); - struct intel_device *device = (struct intel_device *)egl_context->device->priv; + struct intel_context *intel; struct pipe_context *pipe; - struct st_context *st_share = NULL; + struct intel_be_device *device = (struct intel_be_device *)screen->winsys; - egl_context->priv = intel; - - intel->intel_device = device; - intel->egl_context = egl_context; - intel->egl_device = egl_context->device; + intel = (struct intel_context *)malloc(sizeof(*intel)); + memset(intel, 0, sizeof(*intel)); intel->base.hardware_lock = intel_lock_hardware; intel->base.hardware_unlock = intel_unlock_hardware; intel->base.hardware_locked = intel_locked_hardware; - intel_be_init_context(&intel->base, &device->base); + intel_be_init_context(&intel->base, device); + + intel->base.base.destroy = intel_destroy_be_context; #if 0 pipe = intel_create_softpipe(intel, screen->winsys); #else - pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base); + pipe = i915_create_context(screen, &device->base, &intel->base.base); #endif pipe->priv = intel; - intel->st = st_create_context(pipe, visual, st_share); - - device->dummy = intel; - - return TRUE; -} - -int -intel_destroy_context(struct egl_drm_context *egl_context) -{ - struct intel_context *intel = egl_context->priv; - - if (intel->intel_device->dummy == intel) - intel->intel_device->dummy = NULL; - - st_destroy_context(intel->st); - intel_be_destroy_context(&intel->base); - free(intel); - return TRUE; -} - -void -intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read) -{ - if (context) { - struct intel_context *intel = (struct intel_context *)context->priv; - struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; - struct intel_framebuffer *read_fb = (struct intel_framebuffer *)read->priv; - - assert(draw_fb->stfb); - assert(read_fb->stfb); - - st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); - - intel->egl_drawable = draw; - - st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); - - if (draw != read) - st_resize_framebuffer(read_fb->stfb, read->w, read->h); - - } else { - st_make_current(NULL, NULL, NULL); - } -} - -void -intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) -{ - struct intel_device *device = (struct intel_device *)draw->device->priv; - struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; - - if (draw_fb->front_buffer) - driBOUnReference(draw_fb->front_buffer); - - draw_fb->front_buffer = NULL; - draw_fb->front = NULL; - - /* to unbind just call this function with front == NULL */ - if (!front) - return; - - draw_fb->front = front; - - driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); - driBOSetReferenced(draw_fb->front_buffer, front->handle); - - st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); + return pipe; } diff --git a/src/gallium/winsys/drm/intel/egl/intel_context.h b/src/gallium/winsys/drm/intel/egl/intel_context.h deleted file mode 100644 index 477fdec7f7..0000000000 --- a/src/gallium/winsys/drm/intel/egl/intel_context.h +++ /dev/null @@ -1,118 +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. - * - **************************************************************************/ - -#ifndef INTEL_CONTEXT_H -#define INTEL_CONTEXT_H - -#include "pipe/p_debug.h" -#include "intel_be_context.h" - - -struct st_context; -struct egl_drm_device; -struct egl_drm_context; -struct egl_drm_frontbuffer; - - -/** - * Intel rendering context, contains a state tracker and intel-specific info. - */ -struct intel_context -{ - struct intel_be_context base; - - struct st_context *st; - - struct intel_device *intel_device; - - /* new egl stuff */ - struct egl_drm_device *egl_device; - struct egl_drm_context *egl_context; - struct egl_drm_drawable *egl_drawable; -}; - - - -/** - * Intel framebuffer. - */ -struct intel_framebuffer -{ - struct st_framebuffer *stfb; - - struct intel_device *device; - struct _DriBufferObject *front_buffer; - struct egl_drm_frontbuffer *front; -}; - - - - -/* These are functions now: - */ -void LOCK_HARDWARE( struct intel_context *intel ); -void UNLOCK_HARDWARE( struct intel_context *intel ); - -extern char *__progname; - - - -/* ================================================================ - * Debugging: - */ -#ifdef DEBUG -extern int __intel_debug; - -#define DEBUG_SWAP 0x1 -#define DEBUG_LOCK 0x2 -#define DEBUG_IOCTL 0x4 -#define DEBUG_BATCH 0x8 - -#define DBG(flag, ...) do { \ - if (__intel_debug & (DEBUG_##flag)) \ - printf(__VA_ARGS__); \ -} while(0) - -#else -#define DBG(flag, ...) -#endif - - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GME 0x27AE -#define PCI_CHIP_G33_G 0x29C2 -#define PCI_CHIP_Q35_G 0x29B2 -#define PCI_CHIP_Q33_G 0x29D2 - -#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_device.c b/src/gallium/winsys/drm/intel/egl/intel_device.c index 1964745c99..6b281402d5 100644 --- a/src/gallium/winsys/drm/intel/egl/intel_device.c +++ b/src/gallium/winsys/drm/intel/egl/intel_device.c @@ -1,137 +1,48 @@ -/************************************************************************** - * - * 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 "utils.h" - -#include "state_tracker/st_public.h" +#include +#include "pipe/p_defines.h" +#include "intel_be_device.h" #include "i915simple/i915_screen.h" -#include "intel_context.h" -#include "intel_device.h" -#include "intel_batchbuffer.h" -#include "intel_egl.h" - - -extern const struct dri_extension card_extensions[]; - +#include "intel_api.h" -int -intel_create_device(struct egl_drm_device *device) +struct intel_device { - struct intel_device *intel_device; - - /* Allocate the private area */ - intel_device = CALLOC_STRUCT(intel_device); - if (!intel_device) - return FALSE; - - device->priv = (void *)intel_device; - intel_device->device = device; - - intel_device->deviceID = device->deviceID; - - intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID); + struct intel_be_device base; - intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID); + int deviceID; +}; - /* hack */ - driInitExtensions(NULL, card_extensions, GL_FALSE); - - return TRUE; -} - -int -intel_destroy_device(struct egl_drm_device *device) +static void +intel_destroy_winsys(struct pipe_winsys *winsys) { - struct intel_device *intel_device = (struct intel_device *)device->priv; - - intel_be_destroy_device(&intel_device->base); + struct intel_device *dev = (struct intel_device *)winsys; - free(intel_device); - device->priv = NULL; + intel_be_destroy_device(&dev->base); - return TRUE; + free(dev); } -int -intel_create_drawable(struct egl_drm_drawable *drawable, - const __GLcontextModes * visual) +struct pipe_screen * +intel_create_screen(int drmFD, int deviceID) { - enum pipe_format colorFormat, depthFormat, stencilFormat; - struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); - - if (!intelfb) - return GL_FALSE; - - intelfb->device = drawable->device->priv; + struct intel_device *dev; + struct pipe_screen *screen; - if (visual->redBits == 5) - colorFormat = PIPE_FORMAT_R5G6B5_UNORM; - else - colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; - - if (visual->depthBits == 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (visual->depthBits == 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_NONE; + /* Allocate the private area */ + dev = malloc(sizeof(*dev)); + if (!dev) + return NULL; + memset(dev, 0, sizeof(*dev)); - if (visual->stencilBits == 8) - stencilFormat = PIPE_FORMAT_S8Z24_UNORM; - else - stencilFormat = PIPE_FORMAT_NONE; + dev->deviceID = deviceID; - intelfb->stfb = st_create_framebuffer(visual, - colorFormat, - depthFormat, - stencilFormat, - drawable->w, - drawable->h, - (void*) intelfb); + intel_be_init_device(&dev->base, drmFD, deviceID); - if (!intelfb->stfb) { - free(intelfb); - return GL_FALSE; - } + /* we need to hock our own destroy function in here */ + dev->base.base.destroy = intel_destroy_winsys; - drawable->priv = (void *) intelfb; - return GL_TRUE; -} - -int -intel_destroy_drawable(struct egl_drm_drawable *drawable) -{ - struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; - drawable->priv = NULL; + screen = i915_create_screen(&dev->base.base, deviceID); - assert(intelfb->stfb); - st_unreference_framebuffer(intelfb->stfb); - free(intelfb); - return TRUE; + return screen; } diff --git a/src/gallium/winsys/drm/intel/egl/intel_device.h b/src/gallium/winsys/drm/intel/egl/intel_device.h deleted file mode 100644 index 323a7c2aef..0000000000 --- a/src/gallium/winsys/drm/intel/egl/intel_device.h +++ /dev/null @@ -1,50 +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. - * - **************************************************************************/ - -#ifndef _INTEL_SCREEN_H_ -#define _INTEL_SCREEN_H_ - -#include "intel_be_device.h" - -#include "pipe/p_compiler.h" - -struct pipe_screen; -struct egl_drm_device; -struct intel_context; - -struct intel_device -{ - struct intel_be_device base; - struct pipe_screen *pipe; - - int deviceID; - struct egl_drm_device *device; - - struct intel_context *dummy; -}; - -#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_egl.c b/src/gallium/winsys/drm/intel/egl/intel_egl.c deleted file mode 100644 index ed464076ee..0000000000 --- a/src/gallium/winsys/drm/intel/egl/intel_egl.c +++ /dev/null @@ -1,796 +0,0 @@ - -#include -#include -#include -#include -#include - -#include "eglconfig.h" -#include "eglcontext.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "eglmode.h" -#include "eglscreen.h" -#include "eglsurface.h" -#include "egllog.h" - -#include "intel_egl.h" - -#include "xf86drm.h" -#include "xf86drmMode.h" - -#include "intel_context.h" - -#include "state_tracker/st_public.h" - -#define MAX_SCREENS 16 - -static void -drm_get_device_id(struct egl_drm_device *device) -{ - char path[512]; - FILE *file; - - /* TODO get the real minor */ - int minor = 0; - - snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor); - file = fopen(path, "r"); - if (!file) { - _eglLog(_EGL_WARNING, "Could not retrive device ID\n"); - return; - } - - fgets(path, sizeof( path ), file); - sscanf(path, "%x", &device->deviceID); - fclose(file); -} - -static struct egl_drm_device* -egl_drm_create_device(int drmFD) -{ - struct egl_drm_device *device = malloc(sizeof(*device)); - memset(device, 0, sizeof(*device)); - device->drmFD = drmFD; - - device->version = drmGetVersion(device->drmFD); - - drm_get_device_id(device); - - if (!intel_create_device(device)) { - free(device); - return NULL; - } - - return device; -} - -static void -_egl_context_modes_destroy(__GLcontextModes *modes) -{ - _eglLog(_EGL_DEBUG, "%s", __FUNCTION__); - - while (modes) { - __GLcontextModes * const next = modes->next; - free(modes); - modes = next; - } -} -/** - * Create a linked list of 'count' GLcontextModes. - * These are used during the client/server visual negotiation phase, - * then discarded. - */ -static __GLcontextModes * -_egl_context_modes_create(unsigned count, size_t minimum_size) -{ - /* This code copied from libGLX, and modified */ - const size_t size = (minimum_size > sizeof(__GLcontextModes)) - ? minimum_size : sizeof(__GLcontextModes); - __GLcontextModes * head = NULL; - __GLcontextModes ** next; - unsigned i; - - _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size); - - next = & head; - for (i = 0 ; i < count ; i++) { - *next = (__GLcontextModes *) calloc(1, size); - if (*next == NULL) { - _egl_context_modes_destroy(head); - head = NULL; - break; - } - - (*next)->doubleBufferMode = 1; - (*next)->visualID = GLX_DONT_CARE; - (*next)->visualType = GLX_DONT_CARE; - (*next)->visualRating = GLX_NONE; - (*next)->transparentPixel = GLX_NONE; - (*next)->transparentRed = GLX_DONT_CARE; - (*next)->transparentGreen = GLX_DONT_CARE; - (*next)->transparentBlue = GLX_DONT_CARE; - (*next)->transparentAlpha = GLX_DONT_CARE; - (*next)->transparentIndex = GLX_DONT_CARE; - (*next)->xRenderable = GLX_DONT_CARE; - (*next)->fbconfigID = GLX_DONT_CARE; - (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; - (*next)->bindToTextureRgb = GLX_DONT_CARE; - (*next)->bindToTextureRgba = GLX_DONT_CARE; - (*next)->bindToMipmapTexture = GLX_DONT_CARE; - (*next)->bindToTextureTargets = 0; - (*next)->yInverted = GLX_DONT_CARE; - - next = & ((*next)->next); - } - - return head; -} - -struct drm_screen; - -struct drm_driver -{ - _EGLDriver base; /* base class/object */ - - drmModeResPtr res; - - struct drm_screen *screens[MAX_SCREENS]; - size_t count_screens; - - struct egl_drm_device *device; -}; - -struct drm_surface -{ - _EGLSurface base; /* base class/object */ - - struct egl_drm_drawable *drawable; -}; - -struct drm_context -{ - _EGLContext base; /* base class/object */ - - struct egl_drm_context *context; -}; - -struct drm_screen -{ - _EGLScreen base; - - /* currently only support one connector */ - drmModeConnectorPtr connector; - - /* Has this screen been shown */ - int shown; - - /* Surface that is currently attached to this screen */ - struct drm_surface *surf; - - /* backing buffer */ - drmBO buffer; - - /* framebuffer */ - drmModeFBPtr fb; - uint32_t fbID; - - /* crtc and mode used */ - drmModeCrtcPtr crtc; - uint32_t crtcID; - - struct drm_mode_modeinfo *mode; - - /* geometry of the screen */ - struct egl_drm_frontbuffer front; -}; - -static void -drm_update_res(struct drm_driver *drm_drv) -{ - drmModeFreeResources(drm_drv->res); - drm_drv->res = drmModeGetResources(drm_drv->device->drmFD); -} - -static void -drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) -{ - struct drm_mode_modeinfo *m; - int i; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name); - } -} - - -static EGLBoolean -drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) -{ - _EGLDisplay *disp = _eglLookupDisplay(dpy); - struct drm_driver *drm_drv = (struct drm_driver *)drv; - struct drm_screen *screen = NULL; - drmModeConnectorPtr connector = NULL; - drmModeResPtr res = NULL; - unsigned count_connectors = 0; - int num_screens = 0; - - EGLint i; - int fd; - - fd = drmOpen("i915", NULL); - if (fd < 0) { - return EGL_FALSE; - } - - drm_drv->device = egl_drm_create_device(fd); - if (!drm_drv->device) { - drmClose(fd); - return EGL_FALSE; - } - - drm_update_res(drm_drv); - res = drm_drv->res; - if (res) - count_connectors = res->count_connectors; - - for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { - connector = drmModeGetConnector(fd, res->connectors[i]); - - if (!connector) - continue; - - if (connector->connection != DRM_MODE_CONNECTED) { - drmModeFreeConnector(connector); - continue; - } - - screen = malloc(sizeof(struct drm_screen)); - memset(screen, 0, sizeof(*screen)); - screen->connector = connector; - _eglInitScreen(&screen->base); - _eglAddScreen(disp, &screen->base); - drm_add_modes_from_connector(&screen->base, connector); - drm_drv->screens[num_screens++] = screen; - } - drm_drv->count_screens = num_screens; - - /* for now we only have one config */ - _EGLConfig *config = calloc(1, sizeof(*config)); - memset(config, 1, sizeof(*config)); - _eglInitConfig(config, 1); - _eglSetConfigAttrib(config, EGL_RED_SIZE, 8); - _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); - _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); - _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24); - _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); - _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); - _eglAddConfig(disp, config); - - drv->Initialized = EGL_TRUE; - - *major = 1; - *minor = 4; - - return EGL_TRUE; -} - -static void -drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - unsigned int i; - - intel_bind_frontbuffer(screen->surf->drawable, NULL); - screen->surf = NULL; - - for (i = 0; i < drm_drv->res->count_crtcs; i++) { - drmModeSetCrtc( - drm_drv->device->drmFD, - drm_drv->res->crtcs[i], - 0, // FD - 0, 0, - NULL, 0, // List of output ids - NULL); - } - - drmModeRmFB(drm_drv->device->drmFD, screen->fbID); - drmModeFreeFB(screen->fb); - screen->fb = NULL; - - drmBOUnreference(drm_drv->device->drmFD, &screen->buffer); - - screen->shown = 0; -} - -static EGLBoolean -drm_terminate(_EGLDriver *drv, EGLDisplay dpy) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - struct drm_screen *screen; - int i = 0; - - intel_destroy_device(drm_drv->device); - drmFreeVersion(drm_drv->device->version); - - for (i = 0; i < drm_drv->count_screens; i++) { - screen = drm_drv->screens[i]; - - if (screen->shown) - drm_takedown_shown_screen(drv, screen); - - drmModeFreeConnector(screen->connector); - _eglDestroyScreen(&screen->base); - drm_drv->screens[i] = NULL; - } - - drmClose(drm_drv->device->drmFD); - - free(drm_drv->device); - - _eglCleanupDisplay(_eglLookupDisplay(dpy)); - free(drm_drv); - - return EGL_TRUE; -} - - -static struct drm_context * -lookup_drm_context(EGLContext context) -{ - _EGLContext *c = _eglLookupContext(context); - return (struct drm_context *) c; -} - - -static struct drm_surface * -lookup_drm_surface(EGLSurface surface) -{ - _EGLSurface *s = _eglLookupSurface(surface); - return (struct drm_surface *) s; -} - -static struct drm_screen * -lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen) -{ - _EGLScreen *s = _eglLookupScreen(dpy, screen); - return (struct drm_screen *) s; -} - -static __GLcontextModes* -visual_from_config(_EGLConfig *conf) -{ - __GLcontextModes *visual; - (void)conf; - - visual = _egl_context_modes_create(1, sizeof(*visual)); - visual->redBits = 8; - visual->greenBits = 8; - visual->blueBits = 8; - visual->alphaBits = 8; - - visual->rgbBits = 32; - visual->doubleBufferMode = 1; - - visual->depthBits = 24; - visual->haveDepthBuffer = visual->depthBits > 0; - visual->stencilBits = 8; - visual->haveStencilBuffer = visual->stencilBits > 0; - - return visual; -} - - - -static EGLContext -drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - struct drm_context *c; - struct drm_egl_context *share = NULL; - _EGLConfig *conf; - int i; - int ret; - __GLcontextModes *visual; - struct egl_drm_context *context; - - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs defined for now */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - } - - c = (struct drm_context *) calloc(1, sizeof(struct drm_context)); - if (!c) - return EGL_NO_CONTEXT; - - _eglInitContext(drv, dpy, &c->base, config, attrib_list); - - context = malloc(sizeof(*context)); - memset(context, 0, sizeof(*context)); - - if (!context) - goto err_c; - - context->device = drm_drv->device; - visual = visual_from_config(conf); - - ret = intel_create_context(context, visual, share); - free(visual); - - if (!ret) - goto err_gl; - - c->context = context; - - /* generate handle and insert into hash table */ - _eglSaveContext(&c->base); - assert(_eglGetContextHandle(&c->base)); - - return _eglGetContextHandle(&c->base); -err_gl: - free(context); -err_c: - free(c); - return EGL_NO_CONTEXT; -} - -static EGLBoolean -drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) -{ - struct drm_context *fc = lookup_drm_context(context); - _eglRemoveContext(&fc->base); - if (fc->base.IsBound) { - fc->base.DeletePending = EGL_TRUE; - } else { - intel_destroy_context(fc->context); - free(fc->context); - free(fc); - } - return EGL_TRUE; -} - - -static EGLSurface -drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) -{ - return EGL_NO_SURFACE; -} - - -static EGLSurface -drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) -{ - return EGL_NO_SURFACE; -} - - -static EGLSurface -drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, - const EGLint *attrib_list) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - int i; - int ret; - int width = -1; - int height = -1; - struct drm_surface *surf = NULL; - struct egl_drm_drawable *drawable = NULL; - __GLcontextModes *visual; - _EGLConfig *conf; - - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface"); - return EGL_NO_CONTEXT; - } - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - case EGL_WIDTH: - width = attrib_list[++i]; - break; - case EGL_HEIGHT: - height = attrib_list[++i]; - break; - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); - return EGL_NO_SURFACE; - } - } - - if (width < 1 || height < 1) { - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); - return EGL_NO_SURFACE; - } - - surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface)); - if (!surf) - goto err; - - if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list)) - goto err_surf; - - drawable = malloc(sizeof(*drawable)); - memset(drawable, 0, sizeof(*drawable)); - - drawable->w = width; - drawable->h = height; - - visual = visual_from_config(conf); - - drawable->device = drm_drv->device; - ret = intel_create_drawable(drawable, visual); - free(visual); - - if (!ret) - goto err_draw; - - surf->drawable = drawable; - - _eglSaveSurface(&surf->base); - return surf->base.Handle; - -err_draw: - free(drawable); -err_surf: - free(surf); -err: - return EGL_NO_SURFACE; -} - -static EGLSurface -drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, - const EGLint *attrib_list) -{ - EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list); - - return surf; -} - -static struct drm_mode_modeinfo * -drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) -{ - int i; - struct drm_mode_modeinfo *m = NULL; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) - break; - m = &connector->modes[0]; /* if we can't find one, return first */ - } - - return m; -} -static void -draw(size_t x, size_t y, size_t w, size_t h, size_t pitch, size_t v, unsigned int *ptr) -{ - int i, j; - - for (i = x; i < x + w; i++) - for(j = y; j < y + h; j++) - ptr[(i * pitch / 4) + j] = v; - -} - -static void -prettyColors(int fd, unsigned int handle, size_t pitch) -{ - drmBO bo; - unsigned int *ptr; - void *p; - int i; - - drmBOReference(fd, handle, &bo); - drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &p); - ptr = (unsigned int*)p; - - for (i = 0; i < (bo.size / 4); i++) - ptr[i] = 0xFFFFFFFF; - - for (i = 0; i < 4; i++) - draw(i * 40, i * 40, 40, 40, pitch, 0, ptr); - - - draw(200, 100, 40, 40, pitch, 0xff00ff, ptr); - draw(100, 200, 40, 40, pitch, 0xff00ff, ptr); - - drmBOUnmap(fd, &bo); -} - -static EGLBoolean -drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, - EGLScreenMESA screen, - EGLSurface surface, EGLModeMESA m) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - struct drm_surface *surf = lookup_drm_surface(surface); - struct drm_screen *scrn = lookup_drm_screen(dpy, screen); - _EGLMode *mode = _eglLookupMode(dpy, m); - size_t pitch = mode->Width * 4; - size_t size = mode->Height * pitch; - int ret; - unsigned int i,j,k; - - if (scrn->shown) - drm_takedown_shown_screen(drv, scrn); - - ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_NO_EVICT, - DRM_BO_HINT_DONT_FENCE, &scrn->buffer); - - if (ret) - return EGL_FALSE; - - prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); - - ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height, - 32, 32, pitch, - scrn->buffer.handle, - &scrn->fbID); - - if (ret) - goto err_bo; - - scrn->fb = drmModeGetFB(drm_drv->device->drmFD, scrn->fbID); - if (!scrn->fb) - goto err_bo; - - for (j = 0; j < drm_drv->res->count_connectors; j++) { - drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]); - scrn->mode = drm_find_mode(con, mode); - if (!scrn->mode) - goto err_fb; - - for (k = 0; k < con->count_encoders; k++) { - drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]); - for (i = 0; i < drm_drv->res->count_crtcs; i++) { - if (enc->possible_crtcs & (1<device->drmFD, - drm_drv->res->crtcs[i], - scrn->fbID, - 0, 0, - &drm_drv->res->connectors[j], 1, - scrn->mode); - /* skip the other crtcs now */ - i = drm_drv->res->count_crtcs; - } - } - } - } - - scrn->front.handle = scrn->buffer.handle; - scrn->front.pitch = pitch; - scrn->front.width = mode->Width; - scrn->front.height = mode->Height; - - scrn->surf = surf; - intel_bind_frontbuffer(surf->drawable, &scrn->front); - - scrn->shown = 1; - - return EGL_TRUE; - -err_fb: - /* TODO remove fb */ - -err_bo: - drmBOUnreference(drm_drv->device->drmFD, &scrn->buffer); - return EGL_FALSE; -} - -static EGLBoolean -drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) -{ - struct drm_surface *fs = lookup_drm_surface(surface); - _eglRemoveSurface(&fs->base); - if (fs->base.IsBound) { - fs->base.DeletePending = EGL_TRUE; - } else { - intel_bind_frontbuffer(fs->drawable, NULL); - intel_destroy_drawable(fs->drawable); - free(fs->drawable); - free(fs); - } - return EGL_TRUE; -} - - -static EGLBoolean -drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) -{ - struct drm_surface *readSurf = lookup_drm_surface(read); - struct drm_surface *drawSurf = lookup_drm_surface(draw); - struct drm_context *ctx = lookup_drm_context(context); - EGLBoolean b; - - b = _eglMakeCurrent(drv, dpy, draw, read, context); - if (!b) - return EGL_FALSE; - - if (ctx) { - if (!drawSurf || !readSurf) - return EGL_FALSE; - - intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); - } else { - intel_make_current(NULL, NULL, NULL); - } - - return EGL_TRUE; -} - -static EGLBoolean -drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) -{ - struct drm_surface *surf = lookup_drm_surface(draw); - if (!surf) - return EGL_FALSE; - - /* error checking */ - if (!_eglSwapBuffers(drv, dpy, draw)) - return EGL_FALSE; - - intel_swap_buffers(surf->drawable); - return EGL_TRUE; -} - - -/** - * The bootstrap function. Return a new drm_driver object and - * plug in API functions. - */ -_EGLDriver * -_eglMain(_EGLDisplay *dpy, const char *args) -{ - struct drm_driver *drm; - - drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); - if (!drm) { - return NULL; - } - - /* First fill in the dispatch table with defaults */ - _eglInitDriverFallbacks(&drm->base); - /* then plug in our Drm-specific functions */ - drm->base.API.Initialize = drm_initialize; - drm->base.API.Terminate = drm_terminate; - drm->base.API.CreateContext = drm_create_context; - drm->base.API.MakeCurrent = drm_make_current; - drm->base.API.CreateWindowSurface = drm_create_window_surface; - drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface; - drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface; - drm->base.API.DestroySurface = drm_destroy_surface; - drm->base.API.DestroyContext = drm_destroy_context; - drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa; - drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; - drm->base.API.SwapBuffers = drm_swap_buffers; - - drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; - drm->base.Name = "DRM/Gallium"; - - /* enable supported extensions */ - drm->base.Extensions.MESA_screen_surface = EGL_TRUE; - drm->base.Extensions.MESA_copy_context = EGL_TRUE; - - return &drm->base; -} diff --git a/src/gallium/winsys/drm/intel/egl/intel_egl.h b/src/gallium/winsys/drm/intel/egl/intel_egl.h deleted file mode 100644 index 1ee27e0847..0000000000 --- a/src/gallium/winsys/drm/intel/egl/intel_egl.h +++ /dev/null @@ -1,53 +0,0 @@ - -#ifndef _INTEL_EGL_H_ -#define _INTEL_EGL_H_ - -#include - -struct egl_drm_device -{ - void *priv; - int drmFD; - - drmVersionPtr version; - int deviceID; -}; - -struct egl_drm_context -{ - void *priv; - struct egl_drm_device *device; -}; - -struct egl_drm_drawable -{ - void *priv; - struct egl_drm_device *device; - size_t h; - size_t w; -}; - -struct egl_drm_frontbuffer -{ - uint32_t handle; - uint32_t pitch; - uint32_t width; - uint32_t height; -}; - -#include "GL/internal/glcore.h" - -int intel_create_device(struct egl_drm_device *device); -int intel_destroy_device(struct egl_drm_device *device); - -int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate); -int intel_destroy_context(struct egl_drm_context *context); - -int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual); -int intel_destroy_drawable(struct egl_drm_drawable *drawable); - -void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read); -void intel_swap_buffers(struct egl_drm_drawable *draw); -void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front); - -#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_reg.h b/src/gallium/winsys/drm/intel/egl/intel_reg.h deleted file mode 100644 index 4f33bee438..0000000000 --- a/src/gallium/winsys/drm/intel/egl/intel_reg.h +++ /dev/null @@ -1,53 +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. - * - **************************************************************************/ - - -#ifndef _INTEL_REG_H_ -#define _INTEL_REG_H_ - - -#define BR00_BITBLT_CLIENT 0x40000000 -#define BR00_OP_COLOR_BLT 0x10000000 -#define BR00_OP_SRC_COPY_BLT 0x10C00000 -#define BR13_SOLID_PATTERN 0x80000000 - -#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) -#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) -#define XY_COLOR_BLT_WRITE_RGB (1<<20) - -#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) -#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) -#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) - -#define MI_WAIT_FOR_EVENT ((0x3<<23)) -#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) -#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) - -#define MI_BATCH_BUFFER_END (0xA<<23) - - -#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c b/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c deleted file mode 100644 index 2edcbc79ff..0000000000 --- a/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c +++ /dev/null @@ -1,111 +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 "intel_device.h" -#include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_reg.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 "intel_egl.h" - - -static void -intel_display_surface(struct egl_drm_drawable *draw, - struct pipe_surface *surf); - -void intel_swap_buffers(struct egl_drm_drawable *draw) -{ - struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; - struct pipe_surface *back_surf; - - assert(intel_fb); - assert(intel_fb->stfb); - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, ST_SURFACE_BACK_LEFT); - if (back_surf) { - st_notify_swapbuffers(intel_fb->stfb); - if (intel_fb->front) - intel_display_surface(draw, back_surf); - st_notify_swapbuffers_complete(intel_fb->stfb); - } -} - -static void -intel_display_surface(struct egl_drm_drawable *draw, - struct pipe_surface *surf) -{ - struct intel_context *intel = NULL; - struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; - struct _DriFenceObject *fence; - - //const int srcWidth = surf->width; - //const int srcHeight = surf->height; - - intel = intel_fb->device->dummy; - if (!intel) { - printf("No dummy context\n"); - return; - } - - const int dstWidth = intel_fb->front->width; - const int dstHeight = intel_fb->front->height; - const int dstPitch = intel_fb->front->pitch / 4;//draw->front.cpp; - - const int cpp = 4;//intel_fb->front->cpp; - const int srcPitch = surf->stride / cpp; - - int BR13, CMD; - //int i; - - BR13 = (dstPitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - - BEGIN_BATCH(8, 2); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((0 << 16) | 0); - OUT_BATCH((dstHeight << 16) | dstWidth); - - OUT_RELOC(intel_fb->front_buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); - - OUT_BATCH((0 << 16) | 0); - OUT_BATCH((srcPitch * cpp) & 0xffff); - OUT_RELOC(dri_bo(surf->buffer), - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - - fence = intel_be_batchbuffer_flush(intel->base.batch); - driFenceUnReference(&fence); - intel_be_batchbuffer_finish(intel->base.batch); -} -- cgit v1.2.3 From 353f824379259f899142b106d6f642fbe46207f4 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 19 Jan 2009 02:22:34 +0100 Subject: i915: Make gem submit commands --- .../winsys/drm/intel/gem/intel_be_batchbuffer.c | 26 ++++++++++++++++++---- .../winsys/drm/intel/gem/intel_be_context.c | 1 - 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c index af5c027748..e83a4c42cd 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c @@ -68,13 +68,10 @@ intel_be_offset_relocation(struct intel_be_batchbuffer *batch, offset = (unsigned)(batch->base.ptr - batch->base.map); batch->base.ptr += 4; -/* - TODO: Enable this when we submit batch buffers to HW ret = drm_intel_bo_emit_reloc(bo, pre_add, batch->bo, offset, read_domains, write_domain); -*/ if (!ret) batch->base.relocs++; @@ -87,10 +84,31 @@ 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); - /* TODO: submit stuff to HW */ + used = batch->base.ptr - batch->base.map; + assert((used & 3) == 0); + + if (used & 4) { + ((uint32_t *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((uint32_t *) batch->base.ptr)[1] = 0; + ((uint32_t *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; + batch->base.ptr += 12; + } else { + ((uint32_t *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((uint32_t *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; + batch->base.ptr += 8; + } + + 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); diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c index 92fc2dd767..3e472e1e43 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_context.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c @@ -30,7 +30,6 @@ intel_be_batch_reloc(struct i915_winsys *sws, if (access_flags & I915_BUFFER_ACCESS_READ) { read = I915_GEM_DOMAIN_SAMPLER | - I915_GEM_DOMAIN_INSTRUCTION | I915_GEM_DOMAIN_VERTEX; } -- cgit v1.2.3 From a835eb930df5b596060a88863933a1bc7d76b6a9 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 19 Jan 2009 02:24:29 +0100 Subject: i915: Build gem and egl winsys by default --- src/gallium/winsys/drm/intel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/Makefile b/src/gallium/winsys/drm/intel/Makefile index a670ac044d..eede9fc866 100644 --- a/src/gallium/winsys/drm/intel/Makefile +++ b/src/gallium/winsys/drm/intel/Makefile @@ -2,7 +2,7 @@ TOP = ../../../../.. include $(TOP)/configs/current -SUBDIRS = common dri egl +SUBDIRS = gem egl default: subdirs -- cgit v1.2.3 From 7309e8057844bc67a81ce01a99a9cb62d36eda0b Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Wed, 14 Jan 2009 00:27:42 -0500 Subject: nouveau: Rename buffer on map if discardable, busy, and write-only. --- .../winsys/drm/nouveau/common/nouveau_winsys_pipe.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c index 683710ee3c..5b3101fbba 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c @@ -121,6 +121,21 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) map_flags |= NOUVEAU_BO_WR; + if (flags & PIPE_BUFFER_USAGE_DISCARD && + !(flags & PIPE_BUFFER_USAGE_CPU_READ) && + nouveau_bo_busy(nvbuf->bo, map_flags)) { + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_context *nv = nvpws->nv; + struct nouveau_device *dev = nv->nv_screen->device; + struct nouveau_bo *rename; + uint32_t flags = nouveau_flags_from_usage(nv, buf->usage); + + if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) { + nouveau_bo_del(&nvbuf->bo); + nvbuf->bo = rename; + } + } + if (nouveau_bo_map(nvbuf->bo, map_flags)) return NULL; return nvbuf->bo->map; -- cgit v1.2.3 From ea55b62f373a5fb63a684ce0d7f89240d3b888e7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 19 Jan 2009 10:29:27 +0000 Subject: xlib: fix compilation after xmesa header moves --- src/gallium/winsys/xlib/fakeglx.c | 2 +- src/gallium/winsys/xlib/xm_api.c | 2 +- src/gallium/winsys/xlib/xmesa.h | 424 ++++++++++++++++++++++++++++++++++++++ src/gallium/winsys/xlib/xmesaP.h | 2 +- src/gallium/winsys/xlib/xmesa_x.h | 86 ++++++++ 5 files changed, 513 insertions(+), 3 deletions(-) create mode 100644 src/gallium/winsys/xlib/xmesa.h create mode 100644 src/gallium/winsys/xlib/xmesa_x.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c index fd2d222c85..52bc1dbb44 100644 --- a/src/gallium/winsys/xlib/fakeglx.c +++ b/src/gallium/winsys/xlib/fakeglx.c @@ -42,7 +42,7 @@ #include "glxheader.h" #include "glxapi.h" -#include "GL/xmesa.h" +#include "xmesa.h" #include "context.h" #include "config.h" #include "macros.h" diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index d28a6423b9..613aa99fa1 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -58,7 +58,7 @@ #endif #include "glxheader.h" -#include "GL/xmesa.h" +#include "xmesa.h" #include "xmesaP.h" #include "main/context.h" #include "main/framebuffer.h" diff --git a/src/gallium/winsys/xlib/xmesa.h b/src/gallium/winsys/xlib/xmesa.h new file mode 100644 index 0000000000..98139af833 --- /dev/null +++ b/src/gallium/winsys/xlib/xmesa.h @@ -0,0 +1,424 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + + +/* + * Mesa/X11 interface. This header file serves as the documentation for + * the Mesa/X11 interface functions. + * + * Note: this interface isn't intended for user programs. It's primarily + * just for implementing the pseudo-GLX interface. + */ + + +/* Sample Usage: + +In addition to the usual X calls to select a visual, create a colormap +and create a window, you must do the following to use the X/Mesa interface: + +1. Call XMesaCreateVisual() to make an XMesaVisual from an XVisualInfo. + +2. Call XMesaCreateContext() to create an X/Mesa rendering context, given + the XMesaVisual. + +3. Call XMesaCreateWindowBuffer() to create an XMesaBuffer from an X window + and XMesaVisual. + +4. Call XMesaMakeCurrent() to bind the XMesaBuffer to an XMesaContext and + to make the context the current one. + +5. Make gl* calls to render your graphics. + +6. Use XMesaSwapBuffers() when double buffering to swap front/back buffers. + +7. Before the X window is destroyed, call XMesaDestroyBuffer(). + +8. Before exiting, call XMesaDestroyVisual and XMesaDestroyContext. + +*/ + + + + +#ifndef XMESA_H +#define XMESA_H + +#ifdef __VMS +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XFree86Server +#include "xmesa_xf86.h" +#else +#include +#include +#include "xmesa_x.h" +#endif +#include "GL/gl.h" + +#ifdef AMIWIN +#include +extern struct Library *XLibBase; +#endif + + +#define XMESA_MAJOR_VERSION 6 +#define XMESA_MINOR_VERSION 3 + + + +/* + * Values passed to XMesaGetString: + */ +#define XMESA_VERSION 1 +#define XMESA_EXTENSIONS 2 + + +/* + * Values passed to XMesaSetFXmode: + */ +#define XMESA_FX_WINDOW 1 +#define XMESA_FX_FULLSCREEN 2 + + + +typedef struct xmesa_context *XMesaContext; + +typedef struct xmesa_visual *XMesaVisual; + +typedef struct xmesa_buffer *XMesaBuffer; + + + +/* + * Create a new X/Mesa visual. + * Input: display - X11 display + * visinfo - an XVisualInfo pointer + * rgb_flag - GL_TRUE = RGB mode, + * GL_FALSE = color index mode + * alpha_flag - alpha buffer requested? + * db_flag - GL_TRUE = double-buffered, + * GL_FALSE = single buffered + * stereo_flag - stereo visual? + * ximage_flag - GL_TRUE = use an XImage for back buffer, + * GL_FALSE = use an off-screen pixmap for back buffer + * depth_size - requested bits/depth values, or zero + * stencil_size - requested bits/stencil values, or zero + * accum_red_size - requested bits/red accum values, or zero + * accum_green_size - requested bits/green accum values, or zero + * accum_blue_size - requested bits/blue accum values, or zero + * accum_alpha_size - requested bits/alpha accum values, or zero + * num_samples - number of samples/pixel if multisampling, or zero + * level - visual level, usually 0 + * visualCaveat - ala the GLX extension, usually GLX_NONE_EXT + * Return; a new XMesaVisual or 0 if error. + */ +extern XMesaVisual XMesaCreateVisual( XMesaDisplay *display, + XMesaVisualInfo visinfo, + GLboolean rgb_flag, + GLboolean alpha_flag, + GLboolean db_flag, + GLboolean stereo_flag, + GLboolean ximage_flag, + GLint depth_size, + GLint stencil_size, + GLint accum_red_size, + GLint accum_green_size, + GLint accum_blue_size, + GLint accum_alpha_size, + GLint num_samples, + GLint level, + GLint visualCaveat ); + +/* + * Destroy an XMesaVisual, but not the associated XVisualInfo. + */ +extern void XMesaDestroyVisual( XMesaVisual v ); + + + +/* + * Create a new XMesaContext for rendering into an X11 window. + * + * Input: visual - an XMesaVisual + * share_list - another XMesaContext with which to share display + * lists or NULL if no sharing is wanted. + * Return: an XMesaContext or NULL if error. + */ +extern XMesaContext XMesaCreateContext( XMesaVisual v, + XMesaContext share_list ); + + +/* + * Destroy a rendering context as returned by XMesaCreateContext() + */ +extern void XMesaDestroyContext( XMesaContext c ); + + +#ifdef XFree86Server +/* + * These are the extra routines required for integration with XFree86. + * None of these routines should be user visible. -KEM + */ +extern GLboolean XMesaForceCurrent( XMesaContext c ); + +extern GLboolean XMesaLoseCurrent( XMesaContext c ); + +extern GLboolean XMesaCopyContext( XMesaContext src, + XMesaContext dst, + GLuint mask ); +#endif /* XFree86Server */ + + +/* + * Create an XMesaBuffer from an X window. + */ +extern XMesaBuffer XMesaCreateWindowBuffer( XMesaVisual v, XMesaWindow w ); + + +/* + * Create an XMesaBuffer from an X pixmap. + */ +extern XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v, + XMesaPixmap p, + XMesaColormap cmap ); + + +/* + * Destroy an XMesaBuffer, but not the corresponding window or pixmap. + */ +extern void XMesaDestroyBuffer( XMesaBuffer b ); + + +/* + * Return the XMesaBuffer handle which corresponds to an X drawable, if any. + * + * New in Mesa 2.3. + */ +extern XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, + XMesaDrawable d ); + + + +/* + * Bind a buffer to a context and make the context the current one. + */ +extern GLboolean XMesaMakeCurrent( XMesaContext c, + XMesaBuffer b ); + + +/* + * Bind two buffers (read and draw) to a context and make the + * context the current one. + * New in Mesa 3.3 + */ +extern GLboolean XMesaMakeCurrent2( XMesaContext c, + XMesaBuffer drawBuffer, + XMesaBuffer readBuffer ); + + +/* + * Unbind the current context from its buffer. + */ +extern GLboolean XMesaUnbindContext( XMesaContext c ); + + +/* + * Return a handle to the current context. + */ +extern XMesaContext XMesaGetCurrentContext( void ); + + +/* + * Return handle to the current (draw) buffer. + */ +extern XMesaBuffer XMesaGetCurrentBuffer( void ); + + +/* + * Return handle to the current read buffer. + * New in Mesa 3.3 + */ +extern XMesaBuffer XMesaGetCurrentReadBuffer( void ); + + +/* + * Swap the front and back buffers for the given buffer. No action is + * taken if the buffer is not double buffered. + */ +extern void XMesaSwapBuffers( XMesaBuffer b ); + + +/* + * Copy a sub-region of the back buffer to the front buffer. + * + * New in Mesa 2.6 + */ +extern void XMesaCopySubBuffer( XMesaBuffer b, + int x, + int y, + int width, + int height ); + + +/* + * Return a pointer to the the Pixmap or XImage being used as the back + * color buffer of an XMesaBuffer. This function is a way to get "under + * the hood" of X/Mesa so one can manipulate the back buffer directly. + * Input: b - the XMesaBuffer + * Output: pixmap - pointer to back buffer's Pixmap, or 0 + * ximage - pointer to back buffer's XImage, or NULL + * Return: GL_TRUE = context is double buffered + * GL_FALSE = context is single buffered + */ +extern GLboolean XMesaGetBackBuffer( XMesaBuffer b, + XMesaPixmap *pixmap, + XMesaImage **ximage ); + + + +/* + * Return the depth buffer associated with an XMesaBuffer. + * Input: b - the XMesa buffer handle + * Output: width, height - size of buffer in pixels + * bytesPerValue - bytes per depth value (2 or 4) + * buffer - pointer to depth buffer values + * Return: GL_TRUE or GL_FALSE to indicate success or failure. + * + * New in Mesa 2.4. + */ +extern GLboolean XMesaGetDepthBuffer( XMesaBuffer b, + GLint *width, + GLint *height, + GLint *bytesPerValue, + void **buffer ); + + + +/* + * Flush/sync a context + */ +extern void XMesaFlush( XMesaContext c ); + + + +/* + * Get an X/Mesa-specific string. + * Input: name - either XMESA_VERSION or XMESA_EXTENSIONS + */ +extern const char *XMesaGetString( XMesaContext c, int name ); + + + +/* + * Scan for XMesaBuffers whose window/pixmap has been destroyed, then free + * any memory used by that buffer. + * + * New in Mesa 2.3. + */ +extern void XMesaGarbageCollect( void ); + + + +/* + * Return a dithered pixel value. + * Input: c - XMesaContext + * x, y - window coordinate + * red, green, blue, alpha - color components in [0,1] + * Return: pixel value + * + * New in Mesa 2.3. + */ +extern unsigned long XMesaDitherColor( XMesaContext xmesa, + GLint x, + GLint y, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha ); + + + +/* + * 3Dfx Glide driver only! + * Set 3Dfx/Glide full-screen or window rendering mode. + * Input: mode - either XMESA_FX_WINDOW (window rendering mode) or + * XMESA_FX_FULLSCREEN (full-screen rendering mode) + * Return: GL_TRUE if success + * GL_FALSE if invalid mode or if not using 3Dfx driver + * + * New in Mesa 2.6. + */ +extern GLboolean XMesaSetFXmode( GLint mode ); + + + +/* + * Reallocate the back/depth/stencil/accum/etc/ buffers associated with + * buffer if its size has changed. + * + * New in Mesa 4.0.2 + */ +extern void XMesaResizeBuffers( XMesaBuffer b ); + + + +/* + * Create a pbuffer. + * New in Mesa 4.1 + */ +extern XMesaBuffer XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, + unsigned int width, unsigned int height); + + + +/* + * Texture from Pixmap + * New in Mesa 7.1 + */ +extern void +XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer, + const int *attrib_list); + +extern void +XMesaReleaseTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer); + + +extern XMesaBuffer +XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p, + XMesaColormap cmap, + int format, int target, int mipmap); + + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/src/gallium/winsys/xlib/xmesaP.h b/src/gallium/winsys/xlib/xmesaP.h index fcaeee52bc..9a0b1469cc 100644 --- a/src/gallium/winsys/xlib/xmesaP.h +++ b/src/gallium/winsys/xlib/xmesaP.h @@ -27,7 +27,7 @@ #define XMESAP_H -#include "GL/xmesa.h" +#include "xmesa.h" #include "mtypes.h" #ifdef XFree86Server #include "xm_image.h" diff --git a/src/gallium/winsys/xlib/xmesa_x.h b/src/gallium/winsys/xlib/xmesa_x.h new file mode 100644 index 0000000000..865bab4313 --- /dev/null +++ b/src/gallium/winsys/xlib/xmesa_x.h @@ -0,0 +1,86 @@ + +/************************************************************************** + +Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * + * When we're building the XMesa driver for stand-alone Mesa we + * include this file when building the xm_*.c files. + * We need to define some types and macros differently when building + * in the Xserver vs. stand-alone Mesa. + */ + +#ifndef _XMESA_X_H_ +#define _XMESA_X_H_ + +typedef Display XMesaDisplay; +typedef Pixmap XMesaPixmap; +typedef Colormap XMesaColormap; +typedef Drawable XMesaDrawable; +typedef Window XMesaWindow; +typedef GC XMesaGC; +typedef XVisualInfo *XMesaVisualInfo; +typedef XImage XMesaImage; +typedef XPoint XMesaPoint; +typedef XColor XMesaColor; + +#define XMesaDestroyImage XDestroyImage + +#define XMesaPutPixel XPutPixel +#define XMesaGetPixel XGetPixel + +#define XMesaSetForeground XSetForeground +#define XMesaSetBackground XSetBackground +#define XMesaSetPlaneMask XSetPlaneMask +#define XMesaSetFunction XSetFunction +#define XMesaSetFillStyle XSetFillStyle +#define XMesaSetTile XSetTile + +#define XMesaDrawPoint XDrawPoint +#define XMesaDrawPoints XDrawPoints +#define XMesaDrawLine XDrawLine +#define XMesaFillRectangle XFillRectangle +#define XMesaGetImage XGetImage +#define XMesaPutImage XPutImage +#define XMesaCopyArea XCopyArea + +#define XMesaCreatePixmap XCreatePixmap +#define XMesaFreePixmap XFreePixmap +#define XMesaFreeGC XFreeGC + +#define GET_COLORMAP_SIZE(__v) __v->visinfo->colormap_size +#define GET_REDMASK(__v) __v->mesa_visual.redMask +#define GET_GREENMASK(__v) __v->mesa_visual.greenMask +#define GET_BLUEMASK(__v) __v->mesa_visual.blueMask +#define GET_VISUAL_DEPTH(__v) __v->visinfo->depth +#define GET_BLACK_PIXEL(__v) BlackPixel(__v->display, __v->mesa_visual.screen) +#define CHECK_BYTE_ORDER(__v) host_byte_order()==ImageByteOrder(__v->display) +#define CHECK_FOR_HPCR(__v) XInternAtom(__v->display, "_HP_RGB_SMOOTH_MAP_LIST", True) + +#endif -- cgit v1.2.3 From ba3a879b1cade2cb189b1d6d3b244f1fa3f8f5d7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 19 Jan 2009 11:51:23 -0700 Subject: gallium: use align() intead of round_up() --- src/gallium/winsys/xlib/xlib_softpipe.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index e8513069fe..0c3097c42e 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -344,16 +344,6 @@ xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) } - -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - static int xm_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, @@ -362,7 +352,7 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, unsigned flags, unsigned tex_usage) { - const unsigned alignment = 64; + const int alignment = 64; surf->width = width; surf->height = height; @@ -370,7 +360,7 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, pf_get_block(format, &surf->block); surf->nblocksx = pf_get_nblocksx(&surf->block, width); surf->nblocksy = pf_get_nblocksy(&surf->block, height); - surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); + surf->stride = align(surf->nblocksx * surf->block.size, alignment); surf->usage = flags; assert(!surf->buffer); -- cgit v1.2.3 From ecc563b17f810399ddf74a68fca1e903ba49a0d6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 19 Jan 2009 20:01:45 +0000 Subject: xlib: fix dependencies --- src/gallium/winsys/xlib/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index bca59ac883..14d3849f75 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -69,11 +69,11 @@ $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) Makefile --start-group $(LIBS) --end-group $(GL_LIB_DEPS) -depend: $(ALL_SOURCES) +depend: $(XLIB_WINSYS_SOURCES) @ echo "running $(MKDEP)" @ rm -f depend # workaround oops on gutsy?!? @ touch depend - @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \ + $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(XLIB_WINSYS_SOURCES) \ > /dev/null 2>/dev/null -- cgit v1.2.3 From 5897383344da3320d158c26adae05de35480471f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 20 Jan 2009 12:22:49 +0000 Subject: gallium: Remove the standalone surfaces. This commit is mostly just a cosmetic change that cleans-up the interfaces, replacing pipe_winsys::surface_* calls by /** * Allocate storage for a display target surface. * * Often surfaces which are meant to be blitted to the front screen (i.e., * display targets) must be allocated with special characteristics, memory * pools, or obtained directly from the windowing system. * * This callback is invoked by the pipe_screenwhen creating a texture marked * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying * buffer storage. */ struct pipe_buffer *(*surface_buffer_create)(struct pipe_winsys *ws, unsigned width, unsigned height, enum pipe_format format, unsigned usage, unsigned *stride); Most drivers were updated but not all were tested. Use the softpipe pipe driver and the xlib winsys changes as a reference when fixing other drivers. --- .../winsys/drm/intel/common/intel_be_device.c | 46 +++++-------- src/gallium/winsys/egl_xlib/sw_winsys.c | 70 ++++--------------- .../winsys/g3dvl/nouveau/nouveau_winsys_pipe.c | 35 ++++------ src/gallium/winsys/g3dvl/xsp_winsys.c | 67 ++++-------------- src/gallium/winsys/gdi/gdi_softpipe_winsys.c | 68 ++++-------------- src/gallium/winsys/xlib/xlib_brw_screen.c | 63 ++++------------- src/gallium/winsys/xlib/xlib_cell.c | 80 +++++----------------- src/gallium/winsys/xlib/xlib_softpipe.c | 80 +++++----------------- 8 files changed, 122 insertions(+), 387 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/common/intel_be_device.c b/src/gallium/winsys/drm/intel/common/intel_be_device.c index 019ee5cbd2..14aeaf61db 100644 --- a/src/gallium/winsys/drm/intel/common/intel_be_device.c +++ b/src/gallium/winsys/drm/intel/common/intel_be_device.c @@ -157,35 +157,25 @@ err: } -/* - * Surface functions. - * - * Deprecated! - */ - -static struct pipe_surface * -intel_i915_surface_alloc(struct pipe_winsys *winsys) -{ - assert((size_t)"intel_i915_surface_alloc is deprecated" & 0); - return NULL; -} - -static int -intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, +static struct pipe_buffer * +intel_i915_surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, enum pipe_format format, - unsigned flags, - unsigned tex_usage) -{ - assert((size_t)"intel_i915_surface_alloc_storage is deprecated" & 0); - return -1; -} - -static void -intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) + unsigned usage, + unsigned *stride) { - assert((size_t)"intel_i915_surface_release is deprecated" & 0); + const unsigned alignment = 64; + struct pipe_format_block block; + unsigned nblocksx, nblocksy; + + pf_get_block(format, &block); + nblocksx = pf_get_nblocksx(&block, width); + nblocksy = pf_get_nblocksy(&block, height); + *stride = round_up(nblocksx * block.size, alignment); + + return winsys->buffer_create(winsys, alignment, + usage, + *stride * nblocksy); } @@ -238,9 +228,7 @@ intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id) dev->base.buffer_map = intel_be_buffer_map; dev->base.buffer_unmap = intel_be_buffer_unmap; dev->base.buffer_destroy = intel_be_buffer_destroy; - dev->base.surface_alloc = intel_i915_surface_alloc; - dev->base.surface_alloc_storage = intel_i915_surface_alloc_storage; - dev->base.surface_release = intel_i915_surface_release; + dev->base.surface_buffer_create = intel_i915_surface_buffer_create; dev->base.fence_reference = intel_be_fence_reference; dev->base.fence_signalled = intel_be_fence_signalled; dev->base.fence_finish = intel_be_fence_finish; diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index 2fd190da52..a09ad5e8e9 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -161,65 +161,25 @@ buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buf) } -/** - * Called via winsys->surface_alloc() to create new surfaces. - */ -static struct pipe_surface * -surface_alloc(struct pipe_winsys *ws) -{ - struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); - if (!surf) - return NULL; - - surf->refcount = 1; - surf->winsys = ws; - - return surf; -} - - -static int -surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, +static struct pipe_buffer * +surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, enum pipe_format format, - unsigned flags, - unsigned tex_usage) + unsigned usage, + unsigned *stride) { const unsigned alignment = 64; + struct pipe_format_block block; + unsigned nblocksx, nblocksy; - surf->width = width; - surf->height = height; - surf->format = format; - pf_get_block(surf->format, &surf->block); - surf->nblocksx = pf_get_nblocksx(&surf->block, width); - surf->nblocksy = pf_get_nblocksy(&surf->block, height); - surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); - surf->usage = flags; - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->stride * height); - if(!surf->buffer) - return -1; - - return 0; -} - + pf_get_block(format, &block); + nblocksx = pf_get_nblocksx(&block, width); + nblocksy = pf_get_nblocksy(&block, height); + *stride = round_up(nblocksx * block.size, alignment); -static void -surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - assert(!surf->texture); - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - winsys_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; + return winsys->buffer_create(winsys, alignment, + usage, + *stride * nblocksy); } @@ -268,9 +228,7 @@ create_sw_winsys(void) ws->Base.buffer_unmap = buffer_unmap; ws->Base.buffer_destroy = buffer_destroy; - ws->Base.surface_alloc = surface_alloc; - ws->Base.surface_alloc_storage = surface_alloc_storage; - ws->Base.surface_release = surface_release; + ws->Base.surface_buffer_create = surface_buffer_create; ws->Base.fence_reference = fence_reference; ws->Base.fence_signalled = fence_signalled; diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c index 17c409e1ce..2d8463037f 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c @@ -46,34 +46,29 @@ round_up(unsigned n, unsigned multiple) return (n + multiple - 1) & ~(multiple - 1); } -static int -nouveau_surface_alloc_storage +static struct pipe_buffer * +nouveau_surface_buffer_create ( struct pipe_winsys *pws, - struct pipe_surface *surface, unsigned width, unsigned height, enum pipe_format format, - unsigned flags, - unsigned tex_usage + unsigned usage, + unsigned *stride ) { const unsigned int ALIGNMENT = 256; + struct pipe_format_block block; + unsigned nblocksx, nblocksy; - assert(pws); - assert(surface); - - surface->width = width; - surface->height = height; - surface->format = format; - pf_get_block(format, &surface->block); - surface->nblocksx = pf_get_nblocksx(&surface->block, width); - surface->nblocksy = pf_get_nblocksy(&surface->block, height); - surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); - surface->usage = flags; - surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * surface->nblocksy); + pf_get_block(format, &block); + nblocksx = pf_get_nblocksx(&block, width); + nblocksy = pf_get_nblocksy(&block, height); + *stride = round_up(nblocksx * block.size, ALIGNMENT); - return 0; + return winsys->buffer_create(winsys, ALIGNMENT, + usage, + *stride * nblocksy); } static void @@ -269,9 +264,7 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv) pws->flush_frontbuffer = nouveau_flush_frontbuffer; - pws->surface_alloc = nouveau_surface_alloc; - pws->surface_alloc_storage = nouveau_surface_alloc_storage; - pws->surface_release = nouveau_surface_release; + pws->surface_buffer_create = nouveau_surface_buffer_create; pws->buffer_create = nouveau_pipe_bo_create; pws->buffer_destroy = nouveau_pipe_bo_del; diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index 68be2c2ea3..40d683234f 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -96,73 +96,34 @@ static void xsp_buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buff free(xsp_buf); } -static struct pipe_surface* xsp_surface_alloc(struct pipe_winsys *pws) -{ - struct pipe_surface *surface; - - assert(pws); - - surface = calloc(1, sizeof(struct pipe_surface)); - surface->refcount = 1; - surface->winsys = pws; - - return surface; -} - /* Borrowed from Mesa's xm_winsys */ static unsigned int round_up(unsigned n, unsigned multiple) { return (n + multiple - 1) & ~(multiple - 1); } -static int xsp_surface_alloc_storage +static struct pipe_buffer* xsp_surface_buffer_create ( struct pipe_winsys *pws, - struct pipe_surface *surface, unsigned width, unsigned height, enum pipe_format format, - unsigned flags, - unsigned tex_usage + unsigned usage, + unsigned *stride ) { const unsigned int ALIGNMENT = 1; + struct pipe_format_block block; + unsigned nblocksx, nblocksy; - assert(pws); - assert(surface); - - surface->width = width; - surface->height = height; - surface->format = format; - pf_get_block(format, &surface->block); - surface->nblocksx = pf_get_nblocksx(&surface->block, width); - surface->nblocksy = pf_get_nblocksy(&surface->block, height); - surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); - surface->usage = flags; - surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * surface->nblocksy); - - return 0; -} - -static void xsp_surface_release(struct pipe_winsys *pws, struct pipe_surface **surface) -{ - struct pipe_surface *s; - - assert(pws); - assert(surface); - assert(*surface); - - s = *surface; - - s->refcount--; - - if (s->refcount == 0) - { - winsys_buffer_reference(pws, &s->buffer, NULL); - free(s); - } + pf_get_block(format, &block); + nblocksx = pf_get_nblocksx(&block, width); + nblocksy = pf_get_nblocksy(&block, height); + *stride = round_up(nblocksx * block.size, ALIGNMENT); - *surface = NULL; + return winsys->buffer_create(winsys, ALIGNMENT, + usage, + *stride * nblocksy); } static void xsp_fence_reference(struct pipe_winsys *pws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence) @@ -273,9 +234,7 @@ struct pipe_context* create_pipe_context(Display *display, int screen) xsp_winsys->base.buffer_map = xsp_buffer_map; xsp_winsys->base.buffer_unmap = xsp_buffer_unmap; xsp_winsys->base.buffer_destroy = xsp_buffer_destroy; - xsp_winsys->base.surface_alloc = xsp_surface_alloc; - xsp_winsys->base.surface_alloc_storage = xsp_surface_alloc_storage; - xsp_winsys->base.surface_release = xsp_surface_release; + xsp_winsys->base.surface_buffer_create = xsp_surface_buffer_create; xsp_winsys->base.fence_reference = xsp_fence_reference; xsp_winsys->base.fence_signalled = xsp_fence_signalled; xsp_winsys->base.fence_finish = xsp_fence_finish; diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c index bd5aa10a20..cc12007193 100644 --- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -161,63 +161,25 @@ round_up(unsigned n, unsigned multiple) } -static int -gdi_softpipe_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, +static struct pipe_buffer * +gdi_softpipe_surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, enum pipe_format format, - unsigned flags, - unsigned tex_usage) + unsigned usage, + unsigned *stride) { const unsigned alignment = 64; + struct pipe_format_block block; + unsigned nblocksx, nblocksy; - surf->width = width; - surf->height = height; - surf->format = format; - pf_get_block(format, &surf->block); - surf->nblocksx = pf_get_nblocksx(&surf->block, width); - surf->nblocksy = pf_get_nblocksy(&surf->block, height); - surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); - surf->usage = flags; - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->stride * surf->nblocksy); - if(!surf->buffer) - return -1; - - return 0; -} - - -static struct pipe_surface * -gdi_softpipe_surface_alloc(struct pipe_winsys *winsys) -{ - struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); - - assert(winsys); - - surface->refcount = 1; - surface->winsys = winsys; - - return surface; -} - + pf_get_block(format, &block); + nblocksx = pf_get_nblocksx(&block, width); + nblocksy = pf_get_nblocksy(&block, height); + *stride = round_up(nblocksx * block.size, alignment); -static void -gdi_softpipe_surface_release(struct pipe_winsys *winsys, - struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - assert(!surf->texture); - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - winsys_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; + return winsys->buffer_create(winsys, alignment, + usage, + *stride * nblocksy); } @@ -281,9 +243,7 @@ gdi_softpipe_screen_create(void) winsys->buffer_unmap = gdi_softpipe_buffer_unmap; winsys->buffer_destroy = gdi_softpipe_buffer_destroy; - winsys->surface_alloc = gdi_softpipe_surface_alloc; - winsys->surface_alloc_storage = gdi_softpipe_surface_alloc_storage; - winsys->surface_release = gdi_softpipe_surface_release; + winsys->surface_buffer_create = gdi_softpipe_surface_buffer_create; winsys->fence_reference = gdi_softpipe_fence_reference; winsys->fence_signalled = gdi_softpipe_fence_signalled; diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c index 030cd66bd9..1fd7da8a2f 100644 --- a/src/gallium/winsys/xlib/xlib_brw_screen.c +++ b/src/gallium/winsys/xlib/xlib_brw_screen.c @@ -229,17 +229,6 @@ aub_flush_frontbuffer( struct pipe_winsys *winsys, aub_bo(surface->buffer)->offset ); } -static struct pipe_surface * -aub_i915_surface_alloc(struct pipe_winsys *winsys) -{ - struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); - if (surf) { - surf->refcount = 1; - surf->winsys = winsys; - } - return surf; -} - /** * Round n up to next multiple. @@ -250,50 +239,28 @@ round_up(unsigned n, unsigned multiple) return (n + multiple - 1) & ~(multiple - 1); } -static int -aub_i915_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, +static struct pipe_buffer * +aub_i915_surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, enum pipe_format format, - unsigned flags, - unsigned tex_usage) + unsigned usage, + unsigned *stride) { const unsigned alignment = 64; + struct pipe_format_block block; + unsigned nblocksx, nblocksy; - surf->width = width; - surf->height = height; - surf->format = format; - pf_get_block(format, &surf->block); - surf->nblocksx = pf_get_nblocksx(&surf->block, width); - surf->nblocksy = pf_get_nblocksy(&surf->block, height); - surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); - surf->usage = flags; - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->stride * surf->nblocksy); - if(!surf->buffer) - return -1; - - return 0; -} + pf_get_block(format, &block); + nblocksx = pf_get_nblocksx(&block, width); + nblocksy = pf_get_nblocksy(&block, height); + *stride = round_up(nblocksx * block.size, alignment); -static void -aub_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - winsys_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; + return winsys->buffer_create(winsys, alignment, + usage, + *stride * nblocksy); } - static const char * aub_get_name( struct pipe_winsys *winsys ) { @@ -333,9 +300,7 @@ xlib_create_brw_winsys( void ) iws->winsys.get_name = aub_get_name; iws->winsys.destroy = xlib_brw_destroy_pipe_winsys_aub; - iws->winsys.surface_alloc = aub_i915_surface_alloc; - iws->winsys.surface_alloc_storage = aub_i915_surface_alloc_storage; - iws->winsys.surface_release = aub_i915_surface_release; + iws->winsys.surface_buffer_create = aub_i915_surface_buffer_create; iws->aubfile = brw_aubfile_create(); iws->size = AUB_BUF_SIZE; diff --git a/src/gallium/winsys/xlib/xlib_cell.c b/src/gallium/winsys/xlib/xlib_cell.c index 93bc8ecd81..5af9ee3bb5 100644 --- a/src/gallium/winsys/xlib/xlib_cell.c +++ b/src/gallium/winsys/xlib/xlib_cell.c @@ -284,68 +284,26 @@ round_up(unsigned n, unsigned multiple) return (n + multiple - 1) & ~(multiple - 1); } -static int -xm_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, +static struct pipe_buffer * +xm_surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, - enum pipe_format format, - unsigned flags, - unsigned tex_usage) + enum pipe_format format, + unsigned usage, + unsigned *stride) { const unsigned alignment = 64; - - surf->width = width; - surf->height = height; - surf->format = format; - pf_get_block(format, &surf->block); - surf->nblocksx = pf_get_nblocksx(&surf->block, width); - surf->nblocksy = pf_get_nblocksy(&surf->block, height); - surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); - surf->usage = flags; - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - /* XXX a bit of a hack */ - surf->stride * round_up(surf->nblocksy, TILE_SIZE)); - - if(!surf->buffer) - return -1; - - return 0; -} - - -/** - * Called via winsys->surface_alloc() to create new surfaces. - */ -static struct pipe_surface * -xm_surface_alloc(struct pipe_winsys *ws) -{ - struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); - - assert(ws); - - surface->refcount = 1; - surface->winsys = ws; - - return surface; -} - - - -static void -xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - assert(!surf->texture); - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - winsys_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; + struct pipe_format_block block; + unsigned nblocksx, nblocksy; + + pf_get_block(format, &block); + nblocksx = pf_get_nblocksx(&block, width); + nblocksy = pf_get_nblocksy(&block, height); + *stride = round_up(nblocksx * block.size, alignment); + + return winsys->buffer_create(winsys, alignment, + usage, + /* XXX a bit of a hack */ + *stride * round_up(nblocksy, TILE_SIZE)); } @@ -395,9 +353,7 @@ xlib_create_cell_winsys( void ) ws->base.buffer_unmap = xm_buffer_unmap; ws->base.buffer_destroy = xm_buffer_destroy; - ws->base.surface_alloc = xm_surface_alloc; - ws->base.surface_alloc_storage = xm_surface_alloc_storage; - ws->base.surface_release = xm_surface_release; + ws->base.surface_buffer_create = xm_surface_buffer_create; ws->base.fence_reference = xm_fence_reference; ws->base.fence_signalled = xm_fence_signalled; diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index 0c3097c42e..c0bf37050a 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -344,67 +344,25 @@ xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) } -static int -xm_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, +static struct pipe_buffer * +xm_surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, - enum pipe_format format, - unsigned flags, - unsigned tex_usage) -{ - const int alignment = 64; - - surf->width = width; - surf->height = height; - surf->format = format; - pf_get_block(format, &surf->block); - surf->nblocksx = pf_get_nblocksx(&surf->block, width); - surf->nblocksy = pf_get_nblocksy(&surf->block, height); - surf->stride = align(surf->nblocksx * surf->block.size, alignment); - surf->usage = flags; - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->stride * surf->nblocksy); - - if(!surf->buffer) - return -1; - - return 0; -} - - -/** - * Called via winsys->surface_alloc() to create new surfaces. - */ -static struct pipe_surface * -xm_surface_alloc(struct pipe_winsys *ws) + enum pipe_format format, + unsigned usage, + unsigned *stride) { - struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); - - assert(ws); - - surface->refcount = 1; - surface->winsys = ws; - - return surface; -} - - - -static void -xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - assert(!surf->texture); - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - winsys_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; + const unsigned alignment = 64; + struct pipe_format_block block; + unsigned nblocksx, nblocksy; + + pf_get_block(format, &block); + nblocksx = pf_get_nblocksx(&block, width); + nblocksy = pf_get_nblocksy(&block, height); + *stride = align(nblocksx * block.size, alignment); + + return winsys->buffer_create(winsys, alignment, + usage, + *stride * nblocksy); } @@ -454,9 +412,7 @@ xlib_create_softpipe_winsys( void ) ws->base.buffer_unmap = xm_buffer_unmap; ws->base.buffer_destroy = xm_buffer_destroy; - ws->base.surface_alloc = xm_surface_alloc; - ws->base.surface_alloc_storage = xm_surface_alloc_storage; - ws->base.surface_release = xm_surface_release; + ws->base.surface_buffer_create = xm_surface_buffer_create; ws->base.fence_reference = xm_fence_reference; ws->base.fence_signalled = xm_fence_signalled; -- cgit v1.2.3 From 73a4c945d32e0041f7c26a69cef1bb0a8b7d870b Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 20 Jan 2009 19:08:52 +0100 Subject: i915: Fix gem backend after surface changes --- src/gallium/winsys/drm/intel/gem/intel_be_device.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c index 201a485049..5406636bcb 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c @@ -247,9 +247,7 @@ intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id) dev->base.buffer_destroy = intel_be_buffer_destroy; /* Not used anymore */ - dev->base.surface_alloc = NULL; - dev->base.surface_alloc_storage = NULL; - dev->base.surface_release = NULL; + dev->base.surface_buffer_create = NULL; dev->base.fence_reference = intel_be_fence_refunref; dev->base.fence_signalled = intel_be_fence_signalled; -- cgit v1.2.3 From 3af89cd3dec09b8cc5733cd45e2af05b689d0374 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 24 Jan 2009 19:56:13 +0200 Subject: nouveau: fix st_get_framebuffer_surface() breakage Someone changed the st_get_framebuffer_surface() signature, and did not update the users in Nouveau winsys. Surface is returned via a pointer now instead of returning it from the function. No semantic changes. Signed-off-by: Pekka Paalanen --- src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c index 38461b2b0c..e111eec932 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c @@ -58,7 +58,7 @@ nouveau_copy_sub_buffer(__DRIdrawablePrivate *dPriv, int x, int y, int w, int h) struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; struct pipe_surface *surf; - surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); + st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT, &surf); if (surf) { drm_clip_rect_t rect; rect.x1 = x; @@ -77,7 +77,7 @@ nouveau_swap_buffers(__DRIdrawablePrivate *dPriv) struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; struct pipe_surface *surf; - surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); + st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT, &surf); if (surf) { st_notify_swapbuffers(nvfb->stfb); nouveau_copy_buffer(dPriv, surf, NULL); -- cgit v1.2.3 From 0cd1ee764a1775d0a3da860ebb73e441adbaafb8 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 24 Jan 2009 16:15:51 -0500 Subject: g3dvl: Remove dead links to files that are now in libnouveaudrm. --- src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c | 1 - src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c | 1 - src/gallium/winsys/g3dvl/nouveau/nouveau_device.c | 1 - src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c | 1 - src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h | 1 - src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h | 1 - src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h | 1 - src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c | 1 - src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c | 1 - src/gallium/winsys/g3dvl/nouveau/nouveau_local.h | 1 - src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c | 92 ------- .../winsys/g3dvl/nouveau/nouveau_notifier.c | 1 - src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c | 1 - .../winsys/g3dvl/nouveau/nouveau_resource.c | 1 - src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c | 1 - .../winsys/g3dvl/nouveau/nouveau_winsys_pipe.c | 282 --------------------- .../winsys/g3dvl/nouveau/nouveau_winsys_pipe.h | 1 - .../winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c | 1 - src/gallium/winsys/g3dvl/nouveau/nv04_surface.c | 1 - src/gallium/winsys/g3dvl/nouveau/nv50_surface.c | 1 - 20 files changed, 392 deletions(-) delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_device.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_local.h delete mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c delete mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nv04_surface.c delete mode 120000 src/gallium/winsys/g3dvl/nouveau/nv50_surface.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c deleted file mode 120000 index 1005282dd4..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_bo.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c deleted file mode 120000 index 5af8202950..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_channel.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c deleted file mode 120000 index 63f1fa040c..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_device.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c deleted file mode 120000 index cd0d32e537..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_dma.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h deleted file mode 120000 index e6c7d4bc96..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_dma.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h deleted file mode 120000 index c8f9dbdc3a..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_dri.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h deleted file mode 120000 index 27082c9d34..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_drmif.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c deleted file mode 120000 index 51a50527e6..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_fence.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c deleted file mode 120000 index db17c72e6d..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_grobj.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h deleted file mode 120000 index 4e9d3042cb..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_local.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c deleted file mode 100644 index f292586974..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c +++ /dev/null @@ -1,92 +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 -#include -#include "nouveau_context.h" -#include "nouveau_screen.h" - -pipe_static_mutex(lockMutex); - -static void -nouveau_contended_lock(struct nouveau_context *nv, unsigned int flags) -{ - dri_drawable_t *dri_drawable = nv->dri_drawable; - dri_screen_t *dri_screen = nv->dri_context->dri_screen; - struct nouveau_screen *nv_screen = nv->nv_screen; - struct nouveau_device *dev = nv_screen->device; - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - drmGetLock(nvdev->fd, nvdev->ctx, flags); - - /* 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 (dri_drawable) - DRI_VALIDATE_DRAWABLE_INFO(dri_screen, dri_drawable); -} - -/* Lock the hardware and validate our state. - */ -void -LOCK_HARDWARE(struct nouveau_context *nv) -{ - struct nouveau_screen *nv_screen = nv->nv_screen; - struct nouveau_device *dev = nv_screen->device; - struct nouveau_device_priv *nvdev = nouveau_device(dev); - char __ret=0; - - pipe_mutex_lock(lockMutex); - assert(!nv->locked); - - DRM_CAS(nvdev->lock, nvdev->ctx, - (DRM_LOCK_HELD | nvdev->ctx), __ret); - - if (__ret) - nouveau_contended_lock(nv, 0); - nv->locked = 1; -} - - -/* Unlock the hardware using the global current context - */ -void -UNLOCK_HARDWARE(struct nouveau_context *nv) -{ - struct nouveau_screen *nv_screen = nv->nv_screen; - 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/g3dvl/nouveau/nouveau_notifier.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c deleted file mode 120000 index 703bc3ce4a..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_notifier.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c deleted file mode 120000 index 4ac137cada..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_pushbuf.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c deleted file mode 120000 index 2241af328f..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_resource.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c deleted file mode 120000 index ce4052d557..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_winsys.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c deleted file mode 100644 index 2d8463037f..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c +++ /dev/null @@ -1,282 +0,0 @@ -#include "pipe/p_winsys.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "util/u_memory.h" - -#include "nouveau_context.h" -#include "nouveau_local.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" -#include "nouveau_winsys_pipe.h" - -static void -nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, - void *context_private) -{ - struct nouveau_context *nv = context_private; - dri_drawable_t *dri_drawable = nv->dri_drawable; - - nouveau_copy_buffer(dri_drawable, surf, NULL); -} - -static const char * -nouveau_get_name(struct pipe_winsys *pws) -{ - return "Nouveau/DRI"; -} - -static struct pipe_surface * -nouveau_surface_alloc(struct pipe_winsys *ws) -{ - struct pipe_surface *surf; - - surf = CALLOC_STRUCT(pipe_surface); - if (!surf) - return NULL; - - surf->refcount = 1; - surf->winsys = ws; - return surf; -} - -/* Borrowed from Mesa's xm_winsys */ -static unsigned int -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - -static struct pipe_buffer * -nouveau_surface_buffer_create -( - struct pipe_winsys *pws, - unsigned width, - unsigned height, - enum pipe_format format, - unsigned usage, - unsigned *stride -) -{ - const unsigned int ALIGNMENT = 256; - struct pipe_format_block block; - unsigned nblocksx, nblocksy; - - pf_get_block(format, &block); - nblocksx = pf_get_nblocksx(&block, width); - nblocksy = pf_get_nblocksy(&block, height); - *stride = round_up(nblocksx * block.size, ALIGNMENT); - - return winsys->buffer_create(winsys, ALIGNMENT, - usage, - *stride * nblocksy); -} - -static void -nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - - *s = NULL; - if (--surf->refcount <= 0) { - if (surf->buffer) - winsys_buffer_reference(ws, &surf->buffer, NULL); - free(surf); - } -} - -static uint32_t -nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage) -{ - uint32_t flags = NOUVEAU_BO_LOCAL; - - 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; - } - - if (usage & PIPE_BUFFER_USAGE_VERTEX) { - if (nv->cap.hw_vertex_buffer) - flags |= NOUVEAU_BO_GART; - } - - if (usage & PIPE_BUFFER_USAGE_INDEX) { - if (nv->cap.hw_index_buffer) - flags |= NOUVEAU_BO_GART; - } - - return flags; -} - -static struct pipe_buffer * -nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, - unsigned usage, unsigned size) -{ - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; - struct nouveau_context *nv = nvpws->nv; - struct nouveau_device *dev = nv->nv_screen->device; - struct nouveau_pipe_buffer *nvbuf; - uint32_t flags; - - nvbuf = calloc(1, sizeof(*nvbuf)); - if (!nvbuf) - return NULL; - nvbuf->base.refcount = 1; - nvbuf->base.alignment = alignment; - nvbuf->base.usage = usage; - nvbuf->base.size = size; - - flags = nouveau_flags_from_usage(nv, 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 *pws, void *ptr, unsigned bytes) -{ - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; - struct nouveau_device *dev = nvpws->nv->nv_screen->device; - struct nouveau_pipe_buffer *nvbuf; - - nvbuf = calloc(1, sizeof(*nvbuf)); - if (!nvbuf) - return NULL; - nvbuf->base.refcount = 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_winsys *ws, struct pipe_buffer *buf) -{ - struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); - - nouveau_bo_del(&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_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 ((map_flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_WR && - !nouveau_bo_busy(nvbuf->bo, map_flags)) { - /* XXX: Technically incorrect. If the client maps a buffer for write-only - * and leaves part of the buffer untouched it probably expects those parts - * to remain intact. This is violated because we allocate a whole new buffer - * and don't copy the previous buffer's contents, so this optimization is - * only valid if the client intends to overwrite the whole buffer. - */ - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; - struct nouveau_context *nv = nvpws->nv; - struct nouveau_device *dev = nv->nv_screen->device; - struct nouveau_bo *rename; - uint32_t flags = nouveau_flags_from_usage(nv, buf->usage); - - if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) { - nouveau_bo_del(&nvbuf->bo); - nvbuf->bo = rename; - } - } - - 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_buffer(buf); - - nouveau_bo_unmap(nvbuf->bo); -} - -static INLINE struct nouveau_fence * -nouveau_pipe_fence(struct pipe_fence_handle *pfence) -{ - return (struct nouveau_fence *)pfence; -} - -static void -nouveau_pipe_fence_reference(struct pipe_winsys *ws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *pfence) -{ - nouveau_fence_ref((void *)pfence, (void *)ptr); -} - -static int -nouveau_pipe_fence_signalled(struct pipe_winsys *ws, - struct pipe_fence_handle *pfence, unsigned flag) -{ - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)ws; - struct nouveau_fence *fence = nouveau_pipe_fence(pfence); - - if (nouveau_fence(fence)->signalled == 0) - nouveau_fence_flush(nvpws->nv->nvc->channel); - - return !nouveau_fence(fence)->signalled; -} - -static int -nouveau_pipe_fence_finish(struct pipe_winsys *ws, - struct pipe_fence_handle *pfence, unsigned flag) -{ - struct nouveau_fence *fence = nouveau_pipe_fence(pfence); - struct nouveau_fence *ref = NULL; - - nouveau_fence_ref(fence, &ref); - return nouveau_fence_wait(&ref); -} - -struct pipe_winsys * -nouveau_create_pipe_winsys(struct nouveau_context *nv) -{ - struct nouveau_pipe_winsys *nvpws; - struct pipe_winsys *pws; - - nvpws = CALLOC_STRUCT(nouveau_pipe_winsys); - if (!nvpws) - return NULL; - nvpws->nv = nv; - pws = &nvpws->pws; - - pws->flush_frontbuffer = nouveau_flush_frontbuffer; - - pws->surface_buffer_create = nouveau_surface_buffer_create; - - pws->buffer_create = nouveau_pipe_bo_create; - pws->buffer_destroy = nouveau_pipe_bo_del; - pws->user_buffer_create = nouveau_pipe_bo_user_create; - pws->buffer_map = nouveau_pipe_bo_map; - pws->buffer_unmap = nouveau_pipe_bo_unmap; - - pws->fence_reference = nouveau_pipe_fence_reference; - pws->fence_signalled = nouveau_pipe_fence_signalled; - pws->fence_finish = nouveau_pipe_fence_finish; - - pws->get_name = nouveau_get_name; - - return &nvpws->pws; -} diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h deleted file mode 120000 index 9d9460883e..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_winsys_pipe.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c deleted file mode 120000 index ec613ecbf6..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nouveau_winsys_softpipe.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c b/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c deleted file mode 120000 index 4455d8f924..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nv04_surface.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c b/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c deleted file mode 120000 index 19f102001e..0000000000 --- a/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c +++ /dev/null @@ -1 +0,0 @@ -../../drm/nouveau/nv50_surface.c \ No newline at end of file -- cgit v1.2.3 From 005a375068dc876b664114c7eb00f8d6b469fc1a Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 26 Jan 2009 14:37:08 -0500 Subject: egl: compilation fix --- src/gallium/winsys/egl_xlib/egl_xlib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 477d766925..82aa60ae58 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -559,8 +559,10 @@ xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) { struct xlib_egl_surface *xsurf = lookup_surface(draw); struct pipe_winsys *pws = xsurf->winsys; - struct pipe_surface *psurf = - st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT); + struct pipe_surface *psurf; + + st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT, + &psurf); st_notify_swapbuffers(xsurf->Framebuffer); -- cgit v1.2.3 From 26fe7a5fc4421d91e43885da7f85ed9d13897a06 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 Jan 2009 23:22:28 +0100 Subject: intel: Supply the correct buffers to gem --- src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c index e83a4c42cd..b7bc3ee1c9 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c @@ -66,13 +66,15 @@ intel_be_offset_relocation(struct intel_be_batchbuffer *batch, assert(batch->base.relocs < batch->base.max_relocs); offset = (unsigned)(batch->base.ptr - batch->base.map); - batch->base.ptr += 4; - ret = drm_intel_bo_emit_reloc(bo, pre_add, - batch->bo, offset, + 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++; -- cgit v1.2.3 From 72b2733287ee89916d6180becf65ff3b45d5a23a Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 Jan 2009 23:24:42 +0100 Subject: i915: Add verbose debuging Only enabled while in development this commit will be reverted in the future. --- src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c | 7 +++++++ src/gallium/winsys/drm/intel/gem/intel_be_context.c | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c index b7bc3ee1c9..6efa68626b 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c @@ -105,10 +105,17 @@ intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch, batch->base.ptr += 8; } + debug_printf("%s\n", __FUNCTION__); + used = batch->base.ptr - batch->base.map; + debug_printf(" - subdata\n"); drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map); + debug_printf(" - exec\n"); ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0); + debug_printf(" - waiting\n"); + drm_intel_bo_wait_rendering(batch->bo); + debug_printf(" - done\n"); assert(ret == 0); diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c index 3e472e1e43..056a5f0502 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_context.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c @@ -29,15 +29,18 @@ intel_be_batch_reloc(struct i915_winsys *sws, } if (access_flags & I915_BUFFER_ACCESS_READ) { - read = I915_GEM_DOMAIN_SAMPLER | - I915_GEM_DOMAIN_VERTEX; + read = I915_GEM_DOMAIN_VERTEX; } + debug_printf("%s\n", __FUNCTION__); + debug_printf(" - flags: %u, read: %u, write: %u, delta: %p\n", access_flags, read, write, delta); ret = intel_be_offset_relocation(intel->batch, delta, bo, read, write); + debug_printf(" - ret = %i\n", ret); + assert(ret == 0); /* TODO change return type */ /* return ret; */ } -- cgit v1.2.3 From b5fc2a68e8fd07773d424aade2f9d32d4c7bf607 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 Jan 2009 23:37:23 +0100 Subject: intel: Fix typo --- src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c index 6efa68626b..a0574b8347 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c @@ -72,7 +72,7 @@ intel_be_offset_relocation(struct intel_be_batchbuffer *batch, read_domains, write_domain); - ((uint32_t*)batch->base.ptr)[0] = bo->offset = pre_add; + ((uint32_t*)batch->base.ptr)[0] = bo->offset - pre_add; batch->base.ptr += 4; if (!ret) -- cgit v1.2.3 From e74be3f08ec023ffe7c9e79a5ab589d3a12f3a3f Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 Jan 2009 23:40:10 +0100 Subject: intel: Fix type correctly this time Facepalm. --- src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c index a0574b8347..78f5ea0468 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c @@ -72,7 +72,7 @@ intel_be_offset_relocation(struct intel_be_batchbuffer *batch, read_domains, write_domain); - ((uint32_t*)batch->base.ptr)[0] = bo->offset - pre_add; + ((uint32_t*)batch->base.ptr)[0] = bo->offset + pre_add; batch->base.ptr += 4; if (!ret) -- cgit v1.2.3 From f1c0be75b7cd0b69c16aeccb3b7c651194e7e767 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 Jan 2009 01:27:38 +0100 Subject: intel: Change link order --- src/gallium/winsys/drm/intel/egl/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile index 4b22d17ccf..7147d89e0d 100644 --- a/src/gallium/winsys/drm/intel/egl/Makefile +++ b/src/gallium/winsys/drm/intel/egl/Makefile @@ -4,10 +4,11 @@ include $(TOP)/configs/current LIBNAME = EGL_i915.so PIPE_DRIVERS = \ + ../gem/libinteldrm.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ - ../gem/libinteldrm.a + DRIVER_SOURCES = \ intel_context.c \ -- cgit v1.2.3 From e67c020ad493269bab505d47ae5a7cac1e9ddb70 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 Jan 2009 01:33:49 +0100 Subject: intel: Dump batchbuffer before sending to hw --- src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c index 78f5ea0468..d891711712 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c @@ -1,4 +1,5 @@ +#include "i915simple/i915_debug.h" #include "intel_be_batchbuffer.h" #include "intel_be_context.h" #include "intel_be_device.h" @@ -105,6 +106,7 @@ intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch, batch->base.ptr += 8; } + i915_dump_batchbuffer(i915); debug_printf("%s\n", __FUNCTION__); used = batch->base.ptr - batch->base.map; -- cgit v1.2.3 From 178f991208680bea141e6b13c169ca84b703df36 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 Jan 2009 01:34:58 +0100 Subject: intel: Try forcing flushes --- src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c index d891711712..517c693a9b 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c @@ -68,6 +68,8 @@ intel_be_offset_relocation(struct intel_be_batchbuffer *batch, offset = (unsigned)(batch->base.ptr - batch->base.map); + debug_printf(" - offset: %p\n", offset); + ret = drm_intel_bo_emit_reloc(batch->bo, offset, bo, pre_add, read_domains, @@ -96,14 +98,12 @@ intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch, assert((used & 3) == 0); if (used & 4) { - ((uint32_t *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((uint32_t *) batch->base.ptr)[1] = 0; - ((uint32_t *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; - batch->base.ptr += 12; + 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 { - ((uint32_t *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((uint32_t *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; - batch->base.ptr += 8; + 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; } i915_dump_batchbuffer(i915); -- cgit v1.2.3 From 3b1b9f3cc70392bd1abb76e78a28db15bfbbbe85 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 Jan 2009 02:32:58 +0100 Subject: intel: Set render domain on read and write --- src/gallium/winsys/drm/intel/gem/intel_be_context.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c index 056a5f0502..c1f18a3a04 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_context.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c @@ -26,10 +26,11 @@ intel_be_batch_reloc(struct i915_winsys *sws, 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; + read |= I915_GEM_DOMAIN_VERTEX; } debug_printf("%s\n", __FUNCTION__); -- cgit v1.2.3 From 83a2a89663335b6a9203bf5d359659bf83a16dac Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 30 Jan 2009 01:55:09 +0100 Subject: intel: Remove debug print --- src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c | 10 ---------- src/gallium/winsys/drm/intel/gem/intel_be_context.c | 4 +--- 2 files changed, 1 insertion(+), 13 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c index 517c693a9b..d9556e1f38 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c @@ -68,8 +68,6 @@ intel_be_offset_relocation(struct intel_be_batchbuffer *batch, offset = (unsigned)(batch->base.ptr - batch->base.map); - debug_printf(" - offset: %p\n", offset); - ret = drm_intel_bo_emit_reloc(batch->bo, offset, bo, pre_add, read_domains, @@ -106,18 +104,10 @@ intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch, i915_batchbuffer_dword(i915, (0x0<<29)|(0xA<<23)); // MI_BATCH_BUFFER_END; } - i915_dump_batchbuffer(i915); - debug_printf("%s\n", __FUNCTION__); - used = batch->base.ptr - batch->base.map; - debug_printf(" - subdata\n"); drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map); - debug_printf(" - exec\n"); ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0); - debug_printf(" - waiting\n"); - drm_intel_bo_wait_rendering(batch->bo); - debug_printf(" - done\n"); assert(ret == 0); diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c index c1f18a3a04..95e761d78d 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_context.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c @@ -33,15 +33,13 @@ intel_be_batch_reloc(struct i915_winsys *sws, read |= I915_GEM_DOMAIN_VERTEX; } - debug_printf("%s\n", __FUNCTION__); - debug_printf(" - flags: %u, read: %u, write: %u, delta: %p\n", access_flags, read, write, delta); ret = intel_be_offset_relocation(intel->batch, delta, bo, read, write); - debug_printf(" - ret = %i\n", ret); assert(ret == 0); + /* TODO change return type */ /* return ret; */ } -- cgit v1.2.3 From 0c75e59bfd0944782ee767c964d2dd2fdf34f6ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 30 Jan 2009 14:32:11 +0000 Subject: gdi: Update for winsys interface changes. --- src/gallium/winsys/gdi/gdi_softpipe_winsys.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c index cc12007193..91e3c62d7f 100644 --- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -177,9 +177,9 @@ gdi_softpipe_surface_buffer_create(struct pipe_winsys *winsys, nblocksy = pf_get_nblocksy(&block, height); *stride = round_up(nblocksx * block.size, alignment); - return winsys->buffer_create(winsys, alignment, - usage, - *stride * nblocksy); + return winsys->_buffer_create(winsys, alignment, + usage, + *stride * nblocksy); } @@ -237,13 +237,13 @@ gdi_softpipe_screen_create(void) winsys->destroy = gdi_softpipe_destroy; - winsys->buffer_create = gdi_softpipe_buffer_create; - winsys->user_buffer_create = gdi_softpipe_user_buffer_create; - winsys->buffer_map = gdi_softpipe_buffer_map; - winsys->buffer_unmap = gdi_softpipe_buffer_unmap; - winsys->buffer_destroy = gdi_softpipe_buffer_destroy; + winsys->_buffer_create = gdi_softpipe_buffer_create; + winsys->_user_buffer_create = gdi_softpipe_user_buffer_create; + winsys->_buffer_map = gdi_softpipe_buffer_map; + winsys->_buffer_unmap = gdi_softpipe_buffer_unmap; + winsys->_buffer_destroy = gdi_softpipe_buffer_destroy; - winsys->surface_buffer_create = gdi_softpipe_surface_buffer_create; + winsys->_surface_buffer_create = gdi_softpipe_surface_buffer_create; winsys->fence_reference = gdi_softpipe_fence_reference; winsys->fence_signalled = gdi_softpipe_fence_signalled; -- cgit v1.2.3 From adfbba476db1fc55006efb748656ebb1a481d143 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 30 Jan 2009 15:56:00 -0500 Subject: gallium: make p_winsys internal move it to pipe/internal/p_winsys_screen.h and start converting the state trackers to the screen usage --- src/gallium/winsys/drm/intel/common/intel_be_device.c | 2 +- src/gallium/winsys/drm/intel/common/intel_be_device.h | 2 +- src/gallium/winsys/drm/intel/gem/intel_be_device.c | 2 +- src/gallium/winsys/drm/intel/gem/intel_be_device.h | 2 +- src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c | 2 +- src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h | 2 +- src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c | 2 +- src/gallium/winsys/egl_xlib/egl_xlib.c | 2 +- src/gallium/winsys/egl_xlib/sw_winsys.c | 2 +- src/gallium/winsys/gdi/gdi_softpipe_winsys.c | 2 +- src/gallium/winsys/xlib/xlib_brw_context.c | 2 +- src/gallium/winsys/xlib/xlib_brw_screen.c | 2 +- src/gallium/winsys/xlib/xlib_cell.c | 2 +- src/gallium/winsys/xlib/xlib_softpipe.c | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/common/intel_be_device.c b/src/gallium/winsys/drm/intel/common/intel_be_device.c index 14aeaf61db..85ab1a2684 100644 --- a/src/gallium/winsys/drm/intel/common/intel_be_device.c +++ b/src/gallium/winsys/drm/intel/common/intel_be_device.c @@ -10,7 +10,7 @@ #include "ws_dri_bufpool.h" #include "ws_dri_fencemgr.h" -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" #include "pipe/p_inlines.h" diff --git a/src/gallium/winsys/drm/intel/common/intel_be_device.h b/src/gallium/winsys/drm/intel/common/intel_be_device.h index 3f8b3f585c..534d638b6a 100644 --- a/src/gallium/winsys/drm/intel/common/intel_be_device.h +++ b/src/gallium/winsys/drm/intel/common/intel_be_device.h @@ -1,7 +1,7 @@ #ifndef INTEL_DRM_DEVICE_H #define INTEL_DRM_DEVICE_H -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_context.h" /* diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c index 5406636bcb..82c1cb2f32 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c @@ -1,7 +1,7 @@ #include "intel_be_device.h" -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" #include "pipe/p_inlines.h" diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.h b/src/gallium/winsys/drm/intel/gem/intel_be_device.h index 96e94c47e7..f06890163c 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h +++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h @@ -2,7 +2,7 @@ #ifndef INTEL_DRM_DEVICE_H #define INTEL_DRM_DEVICE_H -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_context.h" #include "drm.h" diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c index 5b3101fbba..8e889b9f36 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c @@ -1,4 +1,4 @@ -#include +#include "pipe/internal/p_winsys_screen.h" #include #include #include diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h index 14c728690d..d97ffdf337 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h @@ -2,7 +2,7 @@ #define NOUVEAU_PIPE_WINSYS_H #include "pipe/p_context.h" -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "nouveau_context.h" struct nouveau_pipe_buffer { diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c index 04def600f4..396e4f2a2e 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c @@ -29,7 +29,7 @@ * Authors: Keith Whitwell */ -#include +#include "pipe/internal/p_winsys_screen.h" #include #include #include diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 82aa60ae58..4876339107 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -38,7 +38,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" #include "pipe/p_state.h" -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "util/u_memory.h" #include "softpipe/sp_winsys.h" diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index a09ad5e8e9..739bfa1c1a 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -35,7 +35,7 @@ */ -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_state.h" #include "pipe/p_inlines.h" #include "util/u_math.h" diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c index 91e3c62d7f..738bca3eac 100644 --- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -38,7 +38,7 @@ #include -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_format.h" #include "pipe/p_context.h" #include "pipe/p_inlines.h" diff --git a/src/gallium/winsys/xlib/xlib_brw_context.c b/src/gallium/winsys/xlib/xlib_brw_context.c index 528473925a..09599507f4 100644 --- a/src/gallium/winsys/xlib/xlib_brw_context.c +++ b/src/gallium/winsys/xlib/xlib_brw_context.c @@ -36,7 +36,7 @@ //#include "glxheader.h" //#include "xmesaP.h" -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c index 1fd7da8a2f..5344c502ef 100644 --- a/src/gallium/winsys/xlib/xlib_brw_screen.c +++ b/src/gallium/winsys/xlib/xlib_brw_screen.c @@ -36,7 +36,7 @@ //#include "state_trackers/xlib/glxheader.h" //#include "state_trackers/xlib/xmesaP.h" -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" diff --git a/src/gallium/winsys/xlib/xlib_cell.c b/src/gallium/winsys/xlib/xlib_cell.c index 5af9ee3bb5..bf69593c5c 100644 --- a/src/gallium/winsys/xlib/xlib_cell.c +++ b/src/gallium/winsys/xlib/xlib_cell.c @@ -41,7 +41,7 @@ #undef ASSERT #undef Elements -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_format.h" #include "pipe/p_context.h" #include "pipe/p_inlines.h" diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index c0bf37050a..01d24584e2 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -38,7 +38,7 @@ #undef ASSERT #undef Elements -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_format.h" #include "pipe/p_context.h" #include "pipe/p_inlines.h" -- cgit v1.2.3 From b5d96a3e7f02314cbdc3897c4b89137f1e13bb0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 30 Jan 2009 21:51:59 +0000 Subject: stw: Don't use the winsys. --- src/gallium/winsys/gdi/gdi_softpipe_winsys.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c index 738bca3eac..1abe84b6a0 100644 --- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -177,9 +177,9 @@ gdi_softpipe_surface_buffer_create(struct pipe_winsys *winsys, nblocksy = pf_get_nblocksy(&block, height); *stride = round_up(nblocksx * block.size, alignment); - return winsys->_buffer_create(winsys, alignment, - usage, - *stride * nblocksy); + return winsys->buffer_create(winsys, alignment, + usage, + *stride * nblocksy); } @@ -237,13 +237,13 @@ gdi_softpipe_screen_create(void) winsys->destroy = gdi_softpipe_destroy; - winsys->_buffer_create = gdi_softpipe_buffer_create; - winsys->_user_buffer_create = gdi_softpipe_user_buffer_create; - winsys->_buffer_map = gdi_softpipe_buffer_map; - winsys->_buffer_unmap = gdi_softpipe_buffer_unmap; - winsys->_buffer_destroy = gdi_softpipe_buffer_destroy; + winsys->buffer_create = gdi_softpipe_buffer_create; + winsys->user_buffer_create = gdi_softpipe_user_buffer_create; + winsys->buffer_map = gdi_softpipe_buffer_map; + winsys->buffer_unmap = gdi_softpipe_buffer_unmap; + winsys->buffer_destroy = gdi_softpipe_buffer_destroy; - winsys->_surface_buffer_create = gdi_softpipe_surface_buffer_create; + winsys->surface_buffer_create = gdi_softpipe_surface_buffer_create; winsys->fence_reference = gdi_softpipe_fence_reference; winsys->fence_signalled = gdi_softpipe_fence_signalled; @@ -268,7 +268,7 @@ gdi_softpipe_context_create(struct pipe_screen *screen) static void -gdi_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, +gdi_softpipe_flush_frontbuffer(struct pipe_screen *screen, struct pipe_surface *surface, HDC hDC) { -- cgit v1.2.3 From 4035e0f8989754ee7d31212e69d6461f1bbff008 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 2 Feb 2009 02:12:46 +0100 Subject: nv04: some old changes I had lying around. --- src/gallium/winsys/drm/nouveau/common/nouveau_context.c | 2 ++ src/gallium/winsys/drm/nouveau/common/nouveau_fence.c | 9 ++++++--- src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c | 4 ++++ 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c index 2f245046d4..e093877381 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c @@ -84,6 +84,8 @@ nouveau_context_init(struct nouveau_screen *nv_screen, int i; switch (dev->chipset & 0xf0) { + case 0x00: + /* NV04 */ case 0x10: case 0x20: /* NV10 */ diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c b/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c index e7b0b4ff07..451011e112 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c @@ -148,9 +148,12 @@ nouveau_fence_emit(struct nouveau_fence *fence) NOUVEAU_ERR("AII wrap unhandled\n"); /*XXX: assumes subc 0 is populated */ - RING_SPACE_CH(fence->channel, 2); - OUT_RING_CH (fence->channel, 0x00040050); - OUT_RING_CH (fence->channel, nvfence->sequence); + /* Not the way to fence on nv4 */ + if (nvchan->base.device->chipset >= 0x10) { + RING_SPACE_CH(fence->channel, 2); + OUT_RING_CH (fence->channel, 0x00040050); + OUT_RING_CH (fence->channel, nvfence->sequence); + } if (nvchan->fence_tail) { nouveau_fence(nvchan->fence_tail)->next = fence; diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c index 364340e1d3..722694e4a4 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c @@ -100,6 +100,10 @@ nouveau_pipe_create(struct nouveau_context *nv) return NULL; switch (chipset & 0xf0) { + case 0x00: + hws_create = nv04_screen_create; + hw_create = nv04_create; + break; case 0x10: hws_create = nv10_screen_create; hw_create = nv10_create; -- cgit v1.2.3 From b3cf2af13a5d053ce3ff0c4f3715123d34bfcc32 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 18 Dec 2008 18:29:51 +0100 Subject: amd: initial winsys --- src/gallium/winsys/drm/amd/Makefile | 28 +++ src/gallium/winsys/drm/amd/amd_buffer.c | 240 ++++++++++++++++++ src/gallium/winsys/drm/amd/amd_buffer.h | 54 ++++ src/gallium/winsys/drm/amd/amd_context.c | 298 +++++++++++++++++++++++ src/gallium/winsys/drm/amd/amd_context.h | 68 ++++++ src/gallium/winsys/drm/amd/amd_screen.c | 286 ++++++++++++++++++++++ src/gallium/winsys/drm/amd/amd_screen.h | 42 ++++ src/gallium/winsys/drm/amd/amd_winsys_softpipe.c | 77 ++++++ src/gallium/winsys/drm/amd/amd_winsys_softpipe.h | 37 +++ 9 files changed, 1130 insertions(+) create mode 100644 src/gallium/winsys/drm/amd/Makefile create mode 100644 src/gallium/winsys/drm/amd/amd_buffer.c create mode 100644 src/gallium/winsys/drm/amd/amd_buffer.h create mode 100644 src/gallium/winsys/drm/amd/amd_context.c create mode 100644 src/gallium/winsys/drm/amd/amd_context.h create mode 100644 src/gallium/winsys/drm/amd/amd_screen.c create mode 100644 src/gallium/winsys/drm/amd/amd_screen.h create mode 100644 src/gallium/winsys/drm/amd/amd_winsys_softpipe.c create mode 100644 src/gallium/winsys/drm/amd/amd_winsys_softpipe.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/Makefile b/src/gallium/winsys/drm/amd/Makefile new file mode 100644 index 0000000000..a1b5602c05 --- /dev/null +++ b/src/gallium/winsys/drm/amd/Makefile @@ -0,0 +1,28 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = amd_dri.so + +MINIGLX_SOURCES = + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a + +DRIVER_SOURCES = \ + amd_buffer.c \ + amd_context.c \ + amd_screen.c \ + amd_winsys_softpipe.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../Makefile.template + +DRI_LIB_DEPS += -ldrm-radeon + +symlinks: diff --git a/src/gallium/winsys/drm/amd/amd_buffer.c b/src/gallium/winsys/drm/amd/amd_buffer.c new file mode 100644 index 0000000000..3d400243a5 --- /dev/null +++ b/src/gallium/winsys/drm/amd/amd_buffer.c @@ -0,0 +1,240 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#include +#include "dri_util.h" +#include "state_tracker/st_public.h" +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "amd_buffer.h" +#include "amd_screen.h" +#include "amd_context.h" +#include "radeon_bo.h" +#include "radeon_drm.h" + +static const char *amd_get_name(struct pipe_winsys *ws) +{ + return "AMD/DRI2"; +} + +static struct pipe_buffer *amd_buffer_create(struct pipe_winsys *ws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct amd_pipe_winsys *amd_ws = (struct amd_pipe_winsys *)ws; + struct amd_pipe_buffer *amd_buffer; + uint32_t domain; + + amd_buffer = calloc(1, sizeof(*amd_buffer)); + if (amd_buffer == NULL) { + return NULL; + } + amd_buffer->base.refcount = 1; + amd_buffer->base.alignment = alignment; + amd_buffer->base.usage = usage; + amd_buffer->base.size = size; + + domain = 0; + + if (usage & PIPE_BUFFER_USAGE_PIXEL) { + domain |= RADEON_GEM_DOMAIN_VRAM; + } + if (usage & PIPE_BUFFER_USAGE_VERTEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + + if (usage & PIPE_BUFFER_USAGE_INDEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + amd_buffer->bo = radeon_bo_open(amd_ws->amd_screen->bom, 0, + size, alignment, domain, 0); + if (amd_buffer->bo == NULL) { + free(amd_buffer); + } + return &amd_buffer->base; +} + +static struct pipe_buffer *amd_buffer_user_create(struct pipe_winsys *ws, + void *ptr, + unsigned bytes) +{ + struct amd_pipe_buffer *amd_buffer; + + amd_buffer = (struct amd_pipe_buffer*)amd_buffer_create(ws, 0, 0, bytes); + if (amd_buffer == NULL) { + return NULL; + } + radeon_bo_map(amd_buffer->bo, 1); + memcpy(amd_buffer->bo->ptr, ptr, bytes); + radeon_bo_unmap(amd_buffer->bo); + return &amd_buffer->base; +} + +static void amd_buffer_del(struct pipe_winsys *ws, struct pipe_buffer *buffer) +{ + struct amd_pipe_buffer *amd_buffer = (struct amd_pipe_buffer*)buffer; + + radeon_bo_unref(amd_buffer->bo); + free(amd_buffer); +} + +static void *amd_buffer_map(struct pipe_winsys *ws, + struct pipe_buffer *buffer, + unsigned flags) +{ + struct amd_pipe_buffer *amd_buffer = (struct amd_pipe_buffer*)buffer; + int write = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) { + write = 1; + } + if (radeon_bo_map(amd_buffer->bo, write)) + return NULL; + return amd_buffer->bo->ptr; +} + +static void amd_buffer_unmap(struct pipe_winsys *ws, struct pipe_buffer *buffer) +{ + struct amd_pipe_buffer *amd_buffer = (struct amd_pipe_buffer*)buffer; + + radeon_bo_unmap(amd_buffer->bo); +} + +static void amd_fence_reference(struct pipe_winsys *ws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *pfence) +{ +} + +static int amd_fence_signalled(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, + unsigned flag) +{ + return 1; +} + +static int amd_fence_finish(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, + unsigned flag) +{ + return 0; +} + +static void amd_flush_frontbuffer(struct pipe_winsys *pipe_winsys, + struct pipe_surface *pipe_surface, + void *context_private) +{ + /* TODO: call dri2CopyRegion */ +} + +struct pipe_winsys *amd_pipe_winsys(struct amd_screen *amd_screen) +{ + struct amd_pipe_winsys *amd_ws; + + amd_ws = calloc(1, sizeof(struct amd_pipe_winsys)); + if (amd_ws == NULL) { + return NULL; + } + amd_ws->amd_screen = amd_screen; + + amd_ws->winsys.flush_frontbuffer = amd_flush_frontbuffer; + + amd_ws->winsys.buffer_create = amd_buffer_create; + amd_ws->winsys.buffer_destroy = amd_buffer_del; + amd_ws->winsys.user_buffer_create = amd_buffer_user_create; + amd_ws->winsys.buffer_map = amd_buffer_map; + amd_ws->winsys.buffer_unmap = amd_buffer_unmap; + + amd_ws->winsys.fence_reference = amd_fence_reference; + amd_ws->winsys.fence_signalled = amd_fence_signalled; + amd_ws->winsys.fence_finish = amd_fence_finish; + + amd_ws->winsys.get_name = amd_get_name; + + return &amd_ws->winsys; +} + +static struct pipe_buffer *amd_buffer_from_handle(struct amd_screen *amd_screen, + uint32_t handle) +{ + struct amd_pipe_buffer *amd_buffer; + struct radeon_bo *bo = NULL; + + bo = radeon_bo_open(amd_screen->bom, handle, 0, 0, 0, 0); + if (bo == NULL) { + return NULL; + } + amd_buffer = calloc(1, sizeof(struct amd_pipe_buffer)); + if (amd_buffer == NULL) { + radeon_bo_unref(bo); + return NULL; + } + amd_buffer->base.refcount = 1; + amd_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL; + amd_buffer->bo = bo; + return &amd_buffer->base; +} + +struct pipe_surface *amd_surface_from_handle(struct amd_context *amd_context, + uint32_t handle, + enum pipe_format format, + int w, int h, int pitch) +{ + struct pipe_screen *pipe_screen = amd_context->pipe_screen; + struct pipe_winsys *pipe_winsys = amd_context->pipe_winsys; + struct pipe_texture tmpl; + struct pipe_surface *ps; + struct pipe_texture *pt; + struct pipe_buffer *pb; + + pb = amd_buffer_from_handle(amd_context->amd_screen, handle); + if (pb == NULL) { + return NULL; + } + memset(&tmpl, 0, sizeof(tmpl)); + tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + tmpl.target = PIPE_TEXTURE_2D; + tmpl.width[0] = w; + tmpl.height[0] = h; + tmpl.depth[0] = 1; + tmpl.format = format; + pf_get_block(tmpl.format, &tmpl.block); + tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w); + tmpl.nblocksy[0] = pf_get_nblocksy(&tmpl.block, h); + + pt = pipe_screen->texture_blanket(pipe_screen, &tmpl, &pitch, pb); + if (pt == NULL) { + winsys_buffer_reference(pipe_winsys, &pb, NULL); + } + ps = pipe_screen->get_tex_surface(pipe_screen, pt, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + return ps; +} diff --git a/src/gallium/winsys/drm/amd/amd_buffer.h b/src/gallium/winsys/drm/amd/amd_buffer.h new file mode 100644 index 0000000000..d67967ebea --- /dev/null +++ b/src/gallium/winsys/drm/amd/amd_buffer.h @@ -0,0 +1,54 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#ifndef AMD_BUFFER_H +#define AMD_BUFFER_H + +#include "pipe/p_winsys.h" +#include "amd_screen.h" +#include "amd_context.h" +#include "radeon_bo.h" + +struct amd_pipe_buffer { + struct pipe_buffer base; + struct radeon_bo *bo; +}; + +struct amd_pipe_winsys { + struct pipe_winsys winsys; + struct amd_screen *amd_screen; +}; + +struct pipe_winsys *amd_pipe_winsys(struct amd_screen *amd_screen); +struct pipe_surface *amd_surface_from_handle(struct amd_context *amd_context, + uint32_t handle, + enum pipe_format format, + int w, int h, int pitch); + +#endif diff --git a/src/gallium/winsys/drm/amd/amd_context.c b/src/gallium/winsys/drm/amd/amd_context.c new file mode 100644 index 0000000000..228bd826d3 --- /dev/null +++ b/src/gallium/winsys/drm/amd/amd_context.c @@ -0,0 +1,298 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#include +#include "dri_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "amd_screen.h" +#include "amd_context.h" +#include "amd_buffer.h" +#include "amd_winsys_softpipe.h" + +#define need_GL_ARB_fragment_program +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_shader_objects +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_vertex_shader +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_compiled_vertex_array +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_VERSION_2_0 +#define need_GL_VERSION_2_1 +#include "extension_helper.h" + +/** + * Extension strings exported by the amd driver. + */ +const struct dri_extension amd_card_extensions[] = { + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"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_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {NULL, NULL} +}; + +static void amd_update_renderbuffers(__DRIcontext *dri_context, + __DRIdrawable *dri_drawable) +{ + struct amd_framebuffer *amd_fb; + struct amd_context *amd_context; + unsigned attachments[10]; + __DRIbuffer *buffers; + __DRIscreen *screen; + int i, count; + + amd_context = dri_context->driverPrivate; + screen = dri_drawable->driScreenPriv; + amd_fb = dri_drawable->driverPrivate; + for (count = 0, i = 0; count < 6; count++) { + if (amd_fb->attachments & (1 << count)) { + attachments[i++] = count; + } + } + + buffers = (*screen->dri2.loader->getBuffers)(dri_drawable, + &dri_drawable->w, + &dri_drawable->h, + attachments, + i, + &count, + dri_drawable->loaderPrivate); + if (buffers == NULL) { + return; + } + + /* set one cliprect to cover the whole dri_drawable */ + dri_drawable->x = 0; + dri_drawable->y = 0; + dri_drawable->backX = 0; + dri_drawable->backY = 0; + dri_drawable->numClipRects = 1; + dri_drawable->pClipRects[0].x1 = 0; + dri_drawable->pClipRects[0].y1 = 0; + dri_drawable->pClipRects[0].x2 = dri_drawable->w; + dri_drawable->pClipRects[0].y2 = dri_drawable->h; + dri_drawable->numBackClipRects = 1; + dri_drawable->pBackClipRects[0].x1 = 0; + dri_drawable->pBackClipRects[0].y1 = 0; + dri_drawable->pBackClipRects[0].x2 = dri_drawable->w; + dri_drawable->pBackClipRects[0].y2 = dri_drawable->h; + + for (i = 0; i < count; i++) { + struct pipe_surface *ps; + enum pipe_format format = 0; + int index = 0; + + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + index = ST_SURFACE_FRONT_LEFT; + switch (buffers[i].cpp) { + case 4: + format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case 2: + format = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + /* FIXME: error */ + return; + } + break; + case __DRI_BUFFER_BACK_LEFT: + index = ST_SURFACE_BACK_LEFT; + switch (buffers[i].cpp) { + case 4: + format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case 2: + format = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + /* FIXME: error */ + return; + } + break; + case __DRI_BUFFER_STENCIL: + case __DRI_BUFFER_DEPTH: + index = ST_SURFACE_DEPTH; + switch (buffers[i].cpp) { + case 4: + format = PIPE_FORMAT_Z24S8_UNORM; + break; + case 2: + format = PIPE_FORMAT_Z16_UNORM; + break; + default: + /* FIXME: error */ + return; + } + break; + case __DRI_BUFFER_ACCUM: + default: + fprintf(stderr, + "unhandled buffer attach event, attacment type %d\n", + buffers[i].attachment); + return; + } + + ps = amd_surface_from_handle(amd_context, + buffers[i].name, + format, + dri_drawable->w, + dri_drawable->h, + buffers[i].pitch); + assert(ps); + st_set_framebuffer_surface(amd_fb->st_framebuffer, index, ps); + } + st_resize_framebuffer(amd_fb->st_framebuffer, + dri_drawable->w, + dri_drawable->h); +} + +GLboolean amd_context_create(const __GLcontextModes *visual, + __DRIcontextPrivate *dri_context, + void *shared_context) +{ + __DRIscreenPrivate *dri_screen; + struct amd_context *amd_context; + struct amd_screen *amd_screen; + struct pipe_context *pipe; + struct st_context *shared_st_context = NULL; + + dri_context->driverPrivate = NULL; + amd_context = calloc(1, sizeof(struct amd_context)); + if (amd_context == NULL) { + return GL_FALSE; + } + + if (shared_context) { + shared_st_context = ((struct amd_context*)shared_context)->st_context; + } + + dri_screen = dri_context->driScreenPriv; + amd_screen = dri_screen->private; + amd_context->dri_screen = dri_screen; + amd_context->amd_screen = amd_screen; + amd_context->drm_fd = dri_screen->fd; + + amd_context->pipe_winsys = amd_pipe_winsys(amd_screen); + if (amd_context->pipe_winsys == NULL) { + free(amd_context); + return GL_FALSE; + } + + pipe = amd_create_softpipe(amd_context); + amd_context->st_context = st_create_context(pipe, visual, + shared_st_context); + driInitExtensions(amd_context->st_context->ctx, + amd_card_extensions, GL_TRUE); + dri_context->driverPrivate = amd_context; + return GL_TRUE; +} + +void amd_context_destroy(__DRIcontextPrivate *dri_context) +{ + struct amd_context *amd_context; + + amd_context = dri_context->driverPrivate; + st_finish(amd_context->st_context); + st_destroy_context(amd_context->st_context); + free(amd_context); +} + +GLboolean amd_context_bind(__DRIcontextPrivate *dri_context, + __DRIdrawablePrivate *dri_drawable, + __DRIdrawablePrivate *dri_readable) +{ + struct amd_framebuffer *drawable; + struct amd_framebuffer *readable; + struct amd_context *amd_context; + + if (dri_context == NULL) { + st_make_current(NULL, NULL, NULL); + return GL_TRUE; + } + + amd_context = dri_context->driverPrivate; + drawable = dri_drawable->driverPrivate; + readable = dri_readable->driverPrivate; + st_make_current(amd_context->st_context, + drawable->st_framebuffer, + readable->st_framebuffer); + + amd_update_renderbuffers(dri_context, dri_drawable); + if (dri_drawable != dri_readable) { + amd_update_renderbuffers(dri_context, dri_readable); + } + return GL_TRUE; +} + +GLboolean amd_context_unbind(__DRIcontextPrivate *dri_context) +{ + struct amd_context *amd_context; + + amd_context = dri_context->driverPrivate; + st_flush(amd_context->st_context, PIPE_FLUSH_RENDER_CACHE, NULL); + return GL_TRUE; +} diff --git a/src/gallium/winsys/drm/amd/amd_context.h b/src/gallium/winsys/drm/amd/amd_context.h new file mode 100644 index 0000000000..54a831f15a --- /dev/null +++ b/src/gallium/winsys/drm/amd/amd_context.h @@ -0,0 +1,68 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#ifndef AMD_CONTEXT_H +#define AMD_CONTEXT_H + +#include "dri_util.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "amd_screen.h" + +struct amd_framebuffer { + struct st_framebuffer *st_framebuffer; + unsigned attachments; +}; + +struct amd_context { + /* st */ + struct st_context *st_context; + /* pipe */ + struct pipe_screen *pipe_screen; + struct pipe_winsys *pipe_winsys; + /* DRI */ + __DRIscreenPrivate *dri_screen; + __DRIdrawablePrivate *dri_drawable; + __DRIdrawablePrivate *dri_readable; + /* DRM */ + int drm_fd; + /* AMD */ + struct amd_screen *amd_screen; +}; + +GLboolean amd_context_create(const __GLcontextModes*, + __DRIcontextPrivate*, + void*); +void amd_context_destroy(__DRIcontextPrivate*); +GLboolean amd_context_bind(__DRIcontextPrivate*, + __DRIdrawablePrivate*, + __DRIdrawablePrivate*); +GLboolean amd_context_unbind(__DRIcontextPrivate*); + +#endif diff --git a/src/gallium/winsys/drm/amd/amd_screen.c b/src/gallium/winsys/drm/amd/amd_screen.c new file mode 100644 index 0000000000..22d8973eb7 --- /dev/null +++ b/src/gallium/winsys/drm/amd/amd_screen.c @@ -0,0 +1,286 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#include +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "utils.h" +#include "xf86drm.h" +#include "drm.h" +#include "dri_util.h" +#include "amd_screen.h" +#include "amd_context.h" +#include "amd_buffer.h" +#include "radeon_bo.h" +#include "radeon_bo_gem.h" +#include "radeon_drm.h" + +extern const struct dri_extension amd_card_extensions[]; + +static const __DRIextension *amd_screen_extensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + NULL +}; + +static __DRIconfig **amd_fill_in_modes(unsigned pixel_bits, + unsigned depth_bits, + GLboolean have_back_buffer) +{ + __DRIconfig **configs; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + unsigned num_modes; + GLenum fb_format; + GLenum fb_type; + uint8_t depth_bits_array[3]; + uint8_t stencil_bits_array[3]; + uint8_t msaa_samples_array[1]; + /* TODO: pageflipping ? */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + stencil_bits_array[0] = 0; + stencil_bits_array[1] = 0; + if (depth_bits == 24) { + stencil_bits_array[2] = 8; + num_modes = 3; + } + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + depth_bits_array[2] = depth_bits; + depth_buffer_factor = (depth_bits == 24) ? 3 : 2; + + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + msaa_samples_array[0] = 0; + + 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 = (__DRIconfig **)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", + __FILE__, __LINE__); + return NULL; + } + return configs; +} + +static void amd_screen_destroy(__DRIscreenPrivate *dri_screen) +{ + struct amd_screen *amd_screen = (struct amd_screen*)dri_screen->private; + + radeon_bo_manager_gem_dtor(amd_screen->bom); + dri_screen = NULL; + free(amd_screen); +} + +static const __DRIconfig **amd_screen_init(__DRIscreenPrivate *dri_screen) +{ + struct amd_screen *amd_screen; + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, amd_card_extensions, GL_FALSE); + + amd_screen = calloc(1, sizeof(struct amd_screen)); + if (amd_screen == NULL) { + fprintf(stderr, "\nERROR! Allocating private area failed\n"); + return NULL; + } + dri_screen->private = (void*)amd_screen; + dri_screen->extensions = amd_screen_extensions; + amd_screen->dri_screen = dri_screen; + + amd_screen->bom = radeon_bo_manager_gem_ctor(dri_screen->fd); + if (amd_screen->bom == NULL) { + amd_screen_destroy(dri_screen); + return NULL; + } + + return driConcatConfigs(amd_fill_in_modes(16, 16, 1), + amd_fill_in_modes(32, 24, 1)); +} + +static boolean amd_buffer_create(__DRIscreenPrivate *dri_screen, + __DRIdrawablePrivate *dri_drawable, + const __GLcontextModes *visual, + boolean is_pixmap) +{ + if (is_pixmap) { + /* TODO: implement ? */ + return GL_FALSE; + } else { + enum pipe_format color_format, depth_format, stencil_format; + struct amd_framebuffer *amd_fb; + + amd_fb = calloc(1, sizeof(struct amd_framebuffer)); + if (amd_fb == NULL) { + return GL_FALSE; + } + + switch (visual->redBits) { + case 5: + color_format = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + color_format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + } + + switch (visual->depthBits) { + case 16: + depth_format = PIPE_FORMAT_Z16_UNORM; + break; + case 24: + depth_format = PIPE_FORMAT_S8Z24_UNORM; + default: + depth_format = PIPE_FORMAT_NONE; + break; + } + + switch (visual->stencilBits) { + case 8: + /* force depth format */ + depth_format = PIPE_FORMAT_S8Z24_UNORM; + stencil_format = PIPE_FORMAT_S8Z24_UNORM; + break; + default: + stencil_format = PIPE_FORMAT_NONE; + break; + } + + amd_fb->st_framebuffer = st_create_framebuffer(visual, + color_format, + depth_format, + stencil_format, + dri_drawable->w, + dri_drawable->h, + (void*)amd_fb); + if (amd_fb->st_framebuffer == NULL) { + free(amd_fb); + return GL_FALSE; + } + dri_drawable->driverPrivate = (void *) amd_fb; + + amd_fb->attachments = (1 << __DRI_BUFFER_FRONT_LEFT); + if (visual->doubleBufferMode) { + amd_fb->attachments |= (1 << __DRI_BUFFER_BACK_LEFT); + } + if (visual->depthBits || visual->stencilBits) { + amd_fb->attachments |= (1 << __DRI_BUFFER_DEPTH); + } + + return GL_TRUE; + } +} + +static void amd_buffer_destroy(__DRIdrawablePrivate * dri_drawable) +{ + struct amd_framebuffer *amd_fb; + + amd_fb = dri_drawable->driverPrivate; + assert(amd_fb->st_framebuffer); + st_unreference_framebuffer(amd_fb->st_framebuffer); + free(amd_fb); +} + +static void amd_swap_buffers(__DRIdrawablePrivate *dri_drawable) +{ + struct amd_framebuffer *amd_fb; + struct pipe_surface *back_surf; + + amd_fb = dri_drawable->driverPrivate; + assert(amd_fb); + assert(amd_fb->st_framebuffer); + + back_surf = st_get_framebuffer_surface(amd_fb->st_framebuffer, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + st_notify_swapbuffers(amd_fb->st_framebuffer); + /* TODO: do we want to do anythings ? */ + st_notify_swapbuffers_complete(amd_fb->st_framebuffer); + } +} + +/** + * Called via glXCopySubBufferMESA() to copy a subrect of the back + * buffer to the front buffer/screen. + */ +static void amd_copy_sub_buffer(__DRIdrawablePrivate *dri_drawable, + int x, int y, int w, int h) +{ + /* TODO: ... */ +} + +const struct __DriverAPIRec driDriverAPI = { + .InitScreen = NULL, + .DestroyScreen = amd_screen_destroy, + .CreateContext = amd_context_create, + .DestroyContext = amd_context_destroy, + .CreateBuffer = amd_buffer_create, + .DestroyBuffer = amd_buffer_destroy, + .SwapBuffers = amd_swap_buffers, + .MakeCurrent = amd_context_bind, + .UnbindContext = amd_context_unbind, + .CopySubBuffer = amd_copy_sub_buffer, + .InitScreen2 = amd_screen_init, +}; diff --git a/src/gallium/winsys/drm/amd/amd_screen.h b/src/gallium/winsys/drm/amd/amd_screen.h new file mode 100644 index 0000000000..7f21fa477c --- /dev/null +++ b/src/gallium/winsys/drm/amd/amd_screen.h @@ -0,0 +1,42 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#ifndef AMD_SCREEN_H +#define AMD_SCREEN_H + +#include "pipe/p_winsys.h" +#include "dri_util.h" +#include "radeon_bo.h" + +struct amd_screen { + __DRIscreenPrivate *dri_screen; + struct radeon_bo_manager *bom; +}; + +#endif diff --git a/src/gallium/winsys/drm/amd/amd_winsys_softpipe.c b/src/gallium/winsys/drm/amd/amd_winsys_softpipe.c new file mode 100644 index 0000000000..b9b2a0e8b8 --- /dev/null +++ b/src/gallium/winsys/drm/amd/amd_winsys_softpipe.c @@ -0,0 +1,77 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ +#include +#include "imports.h" +#include "pipe/p_defines.h" +#include "pipe/p_format.h" +#include "softpipe/sp_winsys.h" +#include "amd_context.h" +#include "amd_winsys_softpipe.h" + +struct amd_softpipe_winsys { + struct softpipe_winsys sp_winsys; + struct amd_context *amd_context; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean amd_is_format_supported(struct softpipe_winsys *sws, uint format) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + }; + return FALSE; +} + +struct pipe_context *amd_create_softpipe(struct amd_context *amd_context) +{ + struct amd_softpipe_winsys *amd_sp_ws; + struct pipe_screen *pipe_screen; + + pipe_screen = softpipe_create_screen(amd_context->pipe_winsys); + + amd_sp_ws = CALLOC_STRUCT(amd_softpipe_winsys); + if (amd_sp_ws == NULL) { + return NULL; + } + amd_context->pipe_screen = pipe_screen; + amd_sp_ws->amd_context = amd_context; + amd_sp_ws->sp_winsys.is_format_supported = amd_is_format_supported; + return softpipe_create(pipe_screen, + amd_context->pipe_winsys, + &amd_sp_ws->sp_winsys); +} diff --git a/src/gallium/winsys/drm/amd/amd_winsys_softpipe.h b/src/gallium/winsys/drm/amd/amd_winsys_softpipe.h new file mode 100644 index 0000000000..e5b68cf8a5 --- /dev/null +++ b/src/gallium/winsys/drm/amd/amd_winsys_softpipe.h @@ -0,0 +1,37 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#ifndef AMD_WINSYS_SOFTPIPE_H +#define AMD_WINSYS_SOFTPIPE_H + +#include "amd_context.h" + +struct pipe_context *amd_create_softpipe(struct amd_context *amd_context); + +#endif -- cgit v1.2.3 From adb74f5c5262d22b3c60a555431c29d36e3170f7 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Fri, 9 Jan 2009 18:57:02 -0800 Subject: r300: Hook up to winsys, add missing header. In theory it works, which of course means that it doesn't. --- src/gallium/winsys/drm/amd/amd_context.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/amd_context.c b/src/gallium/winsys/drm/amd/amd_context.c index 228bd826d3..faca7d0c4b 100644 --- a/src/gallium/winsys/drm/amd/amd_context.c +++ b/src/gallium/winsys/drm/amd/amd_context.c @@ -242,7 +242,13 @@ GLboolean amd_context_create(const __GLcontextModes *visual, return GL_FALSE; } - pipe = amd_create_softpipe(amd_context); + if (GL_TRUE) { + /* XXX "NULL" is a struct pipe_screen* just in case we ever need it... */ + pipe = r300_create_context(NULL, amd_context->pipe_winsys, + (struct amd_pipe_winsys*)amd_context->pipe_winsys); + } else { + pipe = amd_create_softpipe(amd_context); + } amd_context->st_context = st_create_context(pipe, visual, shared_st_context); driInitExtensions(amd_context->st_context->ctx, -- cgit v1.2.3 From e9b08e7373c00306bce398ea8d34f42e54f98c6d Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Fri, 9 Jan 2009 21:28:23 -0800 Subject: Make r300 and amd build in scons. --- src/gallium/winsys/drm/amd/SConscript | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/gallium/winsys/drm/amd/SConscript (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/SConscript b/src/gallium/winsys/drm/amd/SConscript new file mode 100644 index 0000000000..a4856da23c --- /dev/null +++ b/src/gallium/winsys/drm/amd/SConscript @@ -0,0 +1,29 @@ +Import('*') + +if 'mesa' in env['statetrackers']: + + env = drienv.Clone() + + DRIVER_SOURCES = [ + 'amd_buffer.c', + 'amd_context.c', + 'amd_screen.c', + 'amd_winsys_softpipe.c', + ] + + sources = \ + COMMON_GALLIUM_SOURCES + \ + DRIVER_SOURCES + + drivers = [ + softpipe, + r300 + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='amd_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], + ) + -- cgit v1.2.3 From 4aaaecbfa6fa810899ef04de44f9f79ec4d8134f Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Fri, 9 Jan 2009 21:50:56 -0800 Subject: A bit of r300 cleanup. --- src/gallium/winsys/drm/amd/amd_context.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/amd_context.c b/src/gallium/winsys/drm/amd/amd_context.c index faca7d0c4b..5127cdf261 100644 --- a/src/gallium/winsys/drm/amd/amd_context.c +++ b/src/gallium/winsys/drm/amd/amd_context.c @@ -243,8 +243,10 @@ GLboolean amd_context_create(const __GLcontextModes *visual, } if (GL_TRUE) { - /* XXX "NULL" is a struct pipe_screen* just in case we ever need it... */ - pipe = r300_create_context(NULL, amd_context->pipe_winsys, + amd_context->pipe_screen = r300_create_screen(amd_context->pipe_winsys, + 0x0); + pipe = r300_create_context(amd_context->pipe_screen, + amd_context->pipe_winsys, (struct amd_pipe_winsys*)amd_context->pipe_winsys); } else { pipe = amd_create_softpipe(amd_context); -- cgit v1.2.3 From 0c59004fe3cc9f691c73da2b4a9321c7682410f4 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Fri, 9 Jan 2009 22:39:36 -0800 Subject: And unbreak traditional build. s/drm-radeon/drm_radeon/ --- src/gallium/winsys/drm/amd/Makefile | 2 +- src/gallium/winsys/drm/amd/amd_context.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/Makefile b/src/gallium/winsys/drm/amd/Makefile index a1b5602c05..0f23e3446c 100644 --- a/src/gallium/winsys/drm/amd/Makefile +++ b/src/gallium/winsys/drm/amd/Makefile @@ -23,6 +23,6 @@ ASM_SOURCES = include ../Makefile.template -DRI_LIB_DEPS += -ldrm-radeon +DRI_LIB_DEPS += -ldrm_radeon symlinks: diff --git a/src/gallium/winsys/drm/amd/amd_context.c b/src/gallium/winsys/drm/amd/amd_context.c index 5127cdf261..632caec6a7 100644 --- a/src/gallium/winsys/drm/amd/amd_context.c +++ b/src/gallium/winsys/drm/amd/amd_context.c @@ -243,6 +243,7 @@ GLboolean amd_context_create(const __GLcontextModes *visual, } if (GL_TRUE) { + /* XXX second arg should be PCI ID, but damned if I know why */ amd_context->pipe_screen = r300_create_screen(amd_context->pipe_winsys, 0x0); pipe = r300_create_context(amd_context->pipe_screen, -- cgit v1.2.3 From fbeeb6675733f5b2da36d40b0142dadf8cc953b4 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Mon, 12 Jan 2009 01:40:50 -0800 Subject: r300, amd: Make everything build. (Not necessarily work, mind you.) Lots of structural work, especially in getting the two parts to talk nicely. Todo: - Get damn blitter working. - Add CS flush. - Reverse order of above two items. --- src/gallium/winsys/drm/amd/Makefile | 6 +++- src/gallium/winsys/drm/amd/amd_context.c | 8 ++--- src/gallium/winsys/drm/amd/amd_context.h | 2 ++ src/gallium/winsys/drm/amd/amd_r300.c | 55 ++++++++++++++++++++++++++++++++ src/gallium/winsys/drm/amd/amd_r300.h | 29 +++++++++++++++++ 5 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 src/gallium/winsys/drm/amd/amd_r300.c create mode 100644 src/gallium/winsys/drm/amd/amd_r300.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/Makefile b/src/gallium/winsys/drm/amd/Makefile index 0f23e3446c..fb77873404 100644 --- a/src/gallium/winsys/drm/amd/Makefile +++ b/src/gallium/winsys/drm/amd/Makefile @@ -7,11 +7,13 @@ LIBNAME = amd_dri.so MINIGLX_SOURCES = PIPE_DRIVERS = \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/r300/libr300.a DRIVER_SOURCES = \ amd_buffer.c \ amd_context.c \ + amd_r300.c \ amd_screen.c \ amd_winsys_softpipe.c @@ -21,6 +23,8 @@ C_SOURCES = \ ASM_SOURCES = +DRIVER_DEFINES = -I../../../drivers/r300 + include ../Makefile.template DRI_LIB_DEPS += -ldrm_radeon diff --git a/src/gallium/winsys/drm/amd/amd_context.c b/src/gallium/winsys/drm/amd/amd_context.c index 632caec6a7..7784964867 100644 --- a/src/gallium/winsys/drm/amd/amd_context.c +++ b/src/gallium/winsys/drm/amd/amd_context.c @@ -243,12 +243,10 @@ GLboolean amd_context_create(const __GLcontextModes *visual, } if (GL_TRUE) { - /* XXX second arg should be PCI ID, but damned if I know why */ - amd_context->pipe_screen = r300_create_screen(amd_context->pipe_winsys, - 0x0); - pipe = r300_create_context(amd_context->pipe_screen, + fprintf(stderr, "Creating r300 context..."); + pipe = r300_create_context(NULL, amd_context->pipe_winsys, - (struct amd_pipe_winsys*)amd_context->pipe_winsys); + amd_create_r300_winsys(amd_context->drm_fd)); } else { pipe = amd_create_softpipe(amd_context); } diff --git a/src/gallium/winsys/drm/amd/amd_context.h b/src/gallium/winsys/drm/amd/amd_context.h index 54a831f15a..12557c40c4 100644 --- a/src/gallium/winsys/drm/amd/amd_context.h +++ b/src/gallium/winsys/drm/amd/amd_context.h @@ -35,6 +35,8 @@ #include "state_tracker/st_context.h" #include "amd_screen.h" +#include "amd_r300.h" + struct amd_framebuffer { struct st_framebuffer *st_framebuffer; unsigned attachments; diff --git a/src/gallium/winsys/drm/amd/amd_r300.c b/src/gallium/winsys/drm/amd/amd_r300.c new file mode 100644 index 0000000000..0bc0a842c1 --- /dev/null +++ b/src/gallium/winsys/drm/amd/amd_r300.c @@ -0,0 +1,55 @@ +/* + * Copyright 2008 Corbin Simpson + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "amd_r300.h" + +static boolean amd_r300_check_cs(struct radeon_cs* cs, int size) +{ + /* XXX check size here, lazy ass! */ + return TRUE; +} + +static void amd_r300_write_cs_reloc(struct radeon_cs* cs, + struct pipe_buffer* pbuffer, + uint32_t rd, + uint32_t wd, + uint32_t flags) +{ + radeon_cs_write_reloc(cs, ((struct amd_pipe_buffer*)pbuffer)->bo, rd, wd, flags); +} + +struct r300_winsys* amd_create_r300_winsys(int fd) +{ + struct r300_winsys* winsys = calloc(1, sizeof(struct r300_winsys)); + + struct radeon_cs_manager* csm = radeon_cs_manager_gem_ctor(fd); + + winsys->cs = radeon_cs_create(csm, 1024 * 64 / 4); + + winsys->check_cs = amd_r300_check_cs; + winsys->begin_cs = radeon_cs_begin; + winsys->write_cs_dword = radeon_cs_write_dword; + winsys->write_cs_reloc = amd_r300_write_cs_reloc; + winsys->end_cs = radeon_cs_end; + + return winsys; +} \ No newline at end of file diff --git a/src/gallium/winsys/drm/amd/amd_r300.h b/src/gallium/winsys/drm/amd/amd_r300.h new file mode 100644 index 0000000000..ef269454b3 --- /dev/null +++ b/src/gallium/winsys/drm/amd/amd_r300.h @@ -0,0 +1,29 @@ +/* + * Copyright 2008 Corbin Simpson + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "radeon_cs.h" + +#include "r300_winsys.h" + +#include "amd_buffer.h" + +struct r300_winsys* amd_create_r300_winsys(int fd); -- cgit v1.2.3 From 432ab001d042b816b5892398064e5735d0293955 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Tue, 13 Jan 2009 15:21:29 -0800 Subject: r300, amd: Add the ability to flush the CS. This is probably important, yeah? --- src/gallium/winsys/drm/amd/amd_r300.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/amd_r300.c b/src/gallium/winsys/drm/amd/amd_r300.c index 0bc0a842c1..0f543df9e1 100644 --- a/src/gallium/winsys/drm/amd/amd_r300.c +++ b/src/gallium/winsys/drm/amd/amd_r300.c @@ -37,6 +37,12 @@ static void amd_r300_write_cs_reloc(struct radeon_cs* cs, radeon_cs_write_reloc(cs, ((struct amd_pipe_buffer*)pbuffer)->bo, rd, wd, flags); } +static void amd_r300_flush_cs(struct radeon_cs* cs) +{ + radeon_cs_emit(cs); + radeon_cs_erase(cs); +} + struct r300_winsys* amd_create_r300_winsys(int fd) { struct r300_winsys* winsys = calloc(1, sizeof(struct r300_winsys)); @@ -50,6 +56,7 @@ struct r300_winsys* amd_create_r300_winsys(int fd) winsys->write_cs_dword = radeon_cs_write_dword; winsys->write_cs_reloc = amd_r300_write_cs_reloc; winsys->end_cs = radeon_cs_end; + winsys->flush_cs = amd_r300_flush_cs; return winsys; -} \ No newline at end of file +} -- cgit v1.2.3 From 502ddfcd57ff7ed1f2dac9171f51c45893ea3d92 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Tue, 20 Jan 2009 01:49:34 -0800 Subject: r300: Add path for pci_id in winsys. Needs to be hooked up to the getparam from the kernel. --- src/gallium/winsys/drm/amd/amd_context.c | 4 +++- src/gallium/winsys/drm/amd/amd_r300.c | 4 +++- src/gallium/winsys/drm/amd/amd_r300.h | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/amd_context.c b/src/gallium/winsys/drm/amd/amd_context.c index 7784964867..53311684de 100644 --- a/src/gallium/winsys/drm/amd/amd_context.c +++ b/src/gallium/winsys/drm/amd/amd_context.c @@ -244,9 +244,11 @@ GLboolean amd_context_create(const __GLcontextModes *visual, if (GL_TRUE) { fprintf(stderr, "Creating r300 context..."); + /* XXX today we pretend to be a very lame R300 vvvvvv */ pipe = r300_create_context(NULL, amd_context->pipe_winsys, - amd_create_r300_winsys(amd_context->drm_fd)); + amd_create_r300_winsys(amd_context->drm_fd, + 0x4144)); } else { pipe = amd_create_softpipe(amd_context); } diff --git a/src/gallium/winsys/drm/amd/amd_r300.c b/src/gallium/winsys/drm/amd/amd_r300.c index 0f543df9e1..a7a70fdd7f 100644 --- a/src/gallium/winsys/drm/amd/amd_r300.c +++ b/src/gallium/winsys/drm/amd/amd_r300.c @@ -43,12 +43,14 @@ static void amd_r300_flush_cs(struct radeon_cs* cs) radeon_cs_erase(cs); } -struct r300_winsys* amd_create_r300_winsys(int fd) +struct r300_winsys* amd_create_r300_winsys(int fd, uint32_t pci_id) { struct r300_winsys* winsys = calloc(1, sizeof(struct r300_winsys)); struct radeon_cs_manager* csm = radeon_cs_manager_gem_ctor(fd); + winsys->pci_id = pci_id; + winsys->cs = radeon_cs_create(csm, 1024 * 64 / 4); winsys->check_cs = amd_r300_check_cs; diff --git a/src/gallium/winsys/drm/amd/amd_r300.h b/src/gallium/winsys/drm/amd/amd_r300.h index ef269454b3..0d229fe0c4 100644 --- a/src/gallium/winsys/drm/amd/amd_r300.h +++ b/src/gallium/winsys/drm/amd/amd_r300.h @@ -26,4 +26,4 @@ #include "amd_buffer.h" -struct r300_winsys* amd_create_r300_winsys(int fd); +struct r300_winsys* amd_create_r300_winsys(int fd, uint32_t pci_id); -- cgit v1.2.3 From ecb7f29f74c8f7456302267fe31b1de4bcc103c5 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Thu, 22 Jan 2009 13:34:21 -0800 Subject: amd/r300: Wire up GETPARAM ioctls. Whoo, stuff is starting to look cleaner and cleaner. --- src/gallium/winsys/drm/amd/amd_context.c | 9 ++++---- src/gallium/winsys/drm/amd/amd_r300.c | 38 +++++++++++++++++++++++++++++--- src/gallium/winsys/drm/amd/amd_r300.h | 7 +++++- 3 files changed, 45 insertions(+), 9 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/amd_context.c b/src/gallium/winsys/drm/amd/amd_context.c index 53311684de..7a486c93a5 100644 --- a/src/gallium/winsys/drm/amd/amd_context.c +++ b/src/gallium/winsys/drm/amd/amd_context.c @@ -244,11 +244,10 @@ GLboolean amd_context_create(const __GLcontextModes *visual, if (GL_TRUE) { fprintf(stderr, "Creating r300 context..."); - /* XXX today we pretend to be a very lame R300 vvvvvv */ - pipe = r300_create_context(NULL, - amd_context->pipe_winsys, - amd_create_r300_winsys(amd_context->drm_fd, - 0x4144)); + pipe = + r300_create_context(NULL, + amd_context->pipe_winsys, + amd_create_r300_winsys(amd_context->drm_fd)); } else { pipe = amd_create_softpipe(amd_context); } diff --git a/src/gallium/winsys/drm/amd/amd_r300.c b/src/gallium/winsys/drm/amd/amd_r300.c index a7a70fdd7f..04295e8281 100644 --- a/src/gallium/winsys/drm/amd/amd_r300.c +++ b/src/gallium/winsys/drm/amd/amd_r300.c @@ -43,13 +43,45 @@ static void amd_r300_flush_cs(struct radeon_cs* cs) radeon_cs_erase(cs); } -struct r300_winsys* amd_create_r300_winsys(int fd, uint32_t pci_id) +/* Helper function to do the ioctls needed for setup and init. */ +static void do_ioctls(struct r300_winsys* winsys, int fd) +{ + drm_radeon_getparam_t gp; + uint32_t target; + int retval; + + /* XXX is this cast safe? */ + gp.value = (int*)⌖ + + /* First, get PCI ID */ + gp.param = RADEON_PARAM_DEVICE_ID; + retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); + if (retval) { + fprintf(stderr, "%s: Failed to get PCI ID, error number %d", + __FUNCTION__, retval); + exit(1); + } + winsys->pci_id = target; + + /* Then, get the number of pixel pipes */ + gp.param = RADEON_PARAM_NUM_GB_PIPES; + retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); + if (retval) { + fprintf(stderr, "%s: Failed to get GB pipe count, error number %d", + __FUNCTION__, retval); + exit(1); + } + winsys->gb_pipes = target; + +} + +struct r300_winsys* amd_create_r300_winsys(int fd) { struct r300_winsys* winsys = calloc(1, sizeof(struct r300_winsys)); - struct radeon_cs_manager* csm = radeon_cs_manager_gem_ctor(fd); + do_ioctls(winsys, fd); - winsys->pci_id = pci_id; + struct radeon_cs_manager* csm = radeon_cs_manager_gem_ctor(fd); winsys->cs = radeon_cs_create(csm, 1024 * 64 / 4); diff --git a/src/gallium/winsys/drm/amd/amd_r300.h b/src/gallium/winsys/drm/amd/amd_r300.h index 0d229fe0c4..d80c23594c 100644 --- a/src/gallium/winsys/drm/amd/amd_r300.h +++ b/src/gallium/winsys/drm/amd/amd_r300.h @@ -20,10 +20,15 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* XXX WTF is this! I shouldn't have to include those first three! FUCK! */ +#include +#include +#include "drm.h" +#include "radeon_drm.h" #include "radeon_cs.h" #include "r300_winsys.h" #include "amd_buffer.h" -struct r300_winsys* amd_create_r300_winsys(int fd, uint32_t pci_id); +struct r300_winsys* amd_create_r300_winsys(int fd); -- cgit v1.2.3 From 5f95f0538e5a354431cc3bbed662c4983e6d0614 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Fri, 23 Jan 2009 16:00:33 -0800 Subject: amd: Fix missing break statement. --- src/gallium/winsys/drm/amd/amd_screen.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/amd_screen.c b/src/gallium/winsys/drm/amd/amd_screen.c index 22d8973eb7..fcf8524525 100644 --- a/src/gallium/winsys/drm/amd/amd_screen.c +++ b/src/gallium/winsys/drm/amd/amd_screen.c @@ -187,11 +187,12 @@ static boolean amd_buffer_create(__DRIscreenPrivate *dri_screen, } switch (visual->depthBits) { + case 24: + depth_format = PIPE_FORMAT_S8Z24_UNORM; + break; case 16: depth_format = PIPE_FORMAT_Z16_UNORM; break; - case 24: - depth_format = PIPE_FORMAT_S8Z24_UNORM; default: depth_format = PIPE_FORMAT_NONE; break; -- cgit v1.2.3 From 02c6e523305de017b49d6851034fcea6c568e94c Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Fri, 23 Jan 2009 16:34:00 -0800 Subject: amd: Fix uninitialized pipe_screen. --- src/gallium/winsys/drm/amd/amd_context.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/amd_context.c b/src/gallium/winsys/drm/amd/amd_context.c index 7a486c93a5..df8eb850c8 100644 --- a/src/gallium/winsys/drm/amd/amd_context.c +++ b/src/gallium/winsys/drm/amd/amd_context.c @@ -243,11 +243,12 @@ GLboolean amd_context_create(const __GLcontextModes *visual, } if (GL_TRUE) { - fprintf(stderr, "Creating r300 context..."); + fprintf(stderr, "Creating r300 context...\n"); pipe = r300_create_context(NULL, amd_context->pipe_winsys, amd_create_r300_winsys(amd_context->drm_fd)); + amd_context->pipe_screen = pipe->screen; } else { pipe = amd_create_softpipe(amd_context); } -- cgit v1.2.3 From 412cf4d38be628200982208b7f93bb17530bb6db Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Sun, 25 Jan 2009 16:29:02 -0800 Subject: BROKEN This commit is only to protect against data loss, so please skip it when bisecting. Thanks. --- src/gallium/winsys/drm/amd/amd_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/amd_context.c b/src/gallium/winsys/drm/amd/amd_context.c index df8eb850c8..9b3c9c2ab2 100644 --- a/src/gallium/winsys/drm/amd/amd_context.c +++ b/src/gallium/winsys/drm/amd/amd_context.c @@ -242,7 +242,7 @@ GLboolean amd_context_create(const __GLcontextModes *visual, return GL_FALSE; } - if (GL_TRUE) { + if (1) { fprintf(stderr, "Creating r300 context...\n"); pipe = r300_create_context(NULL, -- cgit v1.2.3 From 7ccc9a92ce83d5e38549a6f6c5f22b358a90e578 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Thu, 29 Jan 2009 15:53:32 -0800 Subject: amd: Add AMD_SOFTPIPE environment option. If set, AMD_SOFTPIPE will make amd switch to softpipe. --- src/gallium/winsys/drm/amd/amd_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/amd_context.c b/src/gallium/winsys/drm/amd/amd_context.c index 9b3c9c2ab2..86e6e0f5f7 100644 --- a/src/gallium/winsys/drm/amd/amd_context.c +++ b/src/gallium/winsys/drm/amd/amd_context.c @@ -242,7 +242,7 @@ GLboolean amd_context_create(const __GLcontextModes *visual, return GL_FALSE; } - if (1) { + if (!getenv("AMD_SOFTPIPE")) { fprintf(stderr, "Creating r300 context...\n"); pipe = r300_create_context(NULL, -- cgit v1.2.3 From ffc5e9a422da5b3eaadc57995afcbc483739f426 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Mon, 2 Feb 2009 00:18:25 -0800 Subject: amd: Fix build errors from rebase. --- src/gallium/winsys/drm/amd/amd_buffer.c | 1 - src/gallium/winsys/drm/amd/amd_buffer.h | 2 +- src/gallium/winsys/drm/amd/amd_context.c | 1 - src/gallium/winsys/drm/amd/amd_screen.c | 7 ++++--- src/gallium/winsys/drm/amd/amd_screen.h | 1 - 5 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/amd_buffer.c b/src/gallium/winsys/drm/amd/amd_buffer.c index 3d400243a5..fb7c6f33ed 100644 --- a/src/gallium/winsys/drm/amd/amd_buffer.c +++ b/src/gallium/winsys/drm/amd/amd_buffer.c @@ -30,7 +30,6 @@ #include #include "dri_util.h" #include "state_tracker/st_public.h" -#include "pipe/p_winsys.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" #include "amd_buffer.h" diff --git a/src/gallium/winsys/drm/amd/amd_buffer.h b/src/gallium/winsys/drm/amd/amd_buffer.h index d67967ebea..238ca572ae 100644 --- a/src/gallium/winsys/drm/amd/amd_buffer.h +++ b/src/gallium/winsys/drm/amd/amd_buffer.h @@ -30,7 +30,7 @@ #ifndef AMD_BUFFER_H #define AMD_BUFFER_H -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "amd_screen.h" #include "amd_context.h" #include "radeon_bo.h" diff --git a/src/gallium/winsys/drm/amd/amd_context.c b/src/gallium/winsys/drm/amd/amd_context.c index 86e6e0f5f7..e089cf6874 100644 --- a/src/gallium/winsys/drm/amd/amd_context.c +++ b/src/gallium/winsys/drm/amd/amd_context.c @@ -29,7 +29,6 @@ */ #include #include "dri_util.h" -#include "pipe/p_winsys.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" #include "state_tracker/st_public.h" diff --git a/src/gallium/winsys/drm/amd/amd_screen.c b/src/gallium/winsys/drm/amd/amd_screen.c index fcf8524525..d62b47f36d 100644 --- a/src/gallium/winsys/drm/amd/amd_screen.c +++ b/src/gallium/winsys/drm/amd/amd_screen.c @@ -247,14 +247,15 @@ static void amd_buffer_destroy(__DRIdrawablePrivate * dri_drawable) static void amd_swap_buffers(__DRIdrawablePrivate *dri_drawable) { struct amd_framebuffer *amd_fb; - struct pipe_surface *back_surf; + struct pipe_surface *back_surf = NULL; amd_fb = dri_drawable->driverPrivate; assert(amd_fb); assert(amd_fb->st_framebuffer); - back_surf = st_get_framebuffer_surface(amd_fb->st_framebuffer, - ST_SURFACE_BACK_LEFT); + st_get_framebuffer_surface(amd_fb->st_framebuffer, + ST_SURFACE_BACK_LEFT, + &back_surf); if (back_surf) { st_notify_swapbuffers(amd_fb->st_framebuffer); /* TODO: do we want to do anythings ? */ diff --git a/src/gallium/winsys/drm/amd/amd_screen.h b/src/gallium/winsys/drm/amd/amd_screen.h index 7f21fa477c..2617393f2e 100644 --- a/src/gallium/winsys/drm/amd/amd_screen.h +++ b/src/gallium/winsys/drm/amd/amd_screen.h @@ -30,7 +30,6 @@ #ifndef AMD_SCREEN_H #define AMD_SCREEN_H -#include "pipe/p_winsys.h" #include "dri_util.h" #include "radeon_bo.h" -- cgit v1.2.3 From 859db22527d796d186d3cdf83d503669472863cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 2 Feb 2009 15:49:33 +0100 Subject: scons: Fixups for the introduction of the xlib state_tracker. Not quite working yet; glxinfo complains about glXChooseVisual being undefined. --- src/gallium/winsys/xlib/SConscript | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 3aef3b6ced..434572fcd0 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -15,13 +15,7 @@ if env['platform'] == 'linux' \ '#/src/mesa/main', ]) - sources = [ - 'glxapi.c', - 'fakeglx.c', - 'xfonts.c', - 'xm_api.c', - 'xm_winsys.c', - ] + sources = []; drivers = []; @@ -43,7 +37,7 @@ if env['platform'] == 'linux' \ libgl = env.SharedLibrary( target ='GL', source = sources, - LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], + LIBS = st_xlib + glapi + mesa + drivers + auxiliaries + env['LIBS'], ) env.InstallSharedLibrary(libgl, version=(1, 5)) -- cgit v1.2.3 From f0ad6b6144bb416bc22ddccca0be4e614131a2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 2 Feb 2009 15:32:31 +0000 Subject: gdi: Update for wgl st reorg. --- src/gallium/winsys/gdi/SConscript | 4 ++-- src/gallium/winsys/gdi/gdi_softpipe_winsys.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript index e68d5db7f4..f9c1a34668 100644 --- a/src/gallium/winsys/gdi/SConscript +++ b/src/gallium/winsys/gdi/SConscript @@ -8,7 +8,7 @@ if env['platform'] == 'windows': env = env.Clone() env.Append(CPPPATH = [ - '#src/mesa/state_tracker/wgl', + '#src/gallium/state_trackers/wgl', ]) env.Append(CPPDEFINES = [ @@ -24,7 +24,7 @@ if env['platform'] == 'windows': ]) sources = [ - '#src/mesa/state_tracker/wgl/opengl32.def', + '#src/gallium/state_trackers/wgl/opengl32.def', 'gdi_softpipe_winsys.c', ] diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c index 1abe84b6a0..2136cd5f83 100644 --- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -45,7 +45,7 @@ #include "util/u_math.h" #include "util/u_memory.h" #include "softpipe/sp_winsys.h" -#include "stw_winsys.h" +#include "shared/stw_winsys.h" struct gdi_softpipe_buffer -- cgit v1.2.3 From df73c964d85d2f44d8c62558b5752b2f4443763f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 2 Feb 2009 15:37:58 +0000 Subject: xlib: Get conditional compilation of drivers working again. --- src/gallium/winsys/xlib/Makefile | 10 ++++++++-- src/gallium/winsys/xlib/SConscript | 27 +++++++++++++++++++++------ src/gallium/winsys/xlib/xlib.c | 8 ++++++++ 3 files changed, 37 insertions(+), 8 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 14d3849f75..5b71e6dc38 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -22,6 +22,12 @@ INCLUDE_DIRS = \ -I$(TOP)/src/gallium/state_trackers/glx/xlib \ -I$(TOP)/src/gallium/auxiliary +DEFINES = \ + -DGALLIUM_SOFTPIPE \ + -DGALLIUM_CELL \ + -DGALLIUM_TRACE \ + -DGALLIUM_BRW + XLIB_WINSYS_SOURCES = \ xlib.c \ xlib_cell.c \ @@ -49,10 +55,10 @@ LIBS = \ .SUFFIXES : .cpp .c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@ .cpp.o: - $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@ + $(CXX) -c $(INCLUDE_DIRS) $(DEFINES) $(CXXFLAGS) $< -o $@ diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 434572fcd0..0fb4b50f63 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -13,24 +13,39 @@ if env['platform'] == 'linux' \ env.Append(CPPPATH = [ '#/src/mesa', '#/src/mesa/main', + '#src/gallium/state_trackers/glx/xlib', ]) - sources = []; + env.Append(CPPDEFINES = ['USE_XSHM']) - drivers = []; + sources = [ + 'xlib.c', + ] + + drivers = [] if 'softpipe' in env['drivers']: + env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE') + sources += ['xlib_softpipe.c'] drivers += [softpipe] if 'i965simple' in env['drivers']: - drivers += [i965simple] + env.Append(CPPDEFINES = 'GALLIUM_I965SIMPLE') sources += [ - 'brw_aub.c', - 'xm_winsys_aub.c', - ] + 'xlib_brw_aub.c', + 'xlib_brw_context.c', + 'xlib_brw_screen.c', + ] + drivers += [i965simple] + if 'cell' in env['drivers']: + env.Append(CPPDEFINES = 'GALLIUM_CELL') + sources += ['xlib_cell.c'] + drivers += [cell] + if 'trace' in env['drivers']: env.Append(CPPDEFINES = 'GALLIUM_TRACE') + sources += ['xlib_trace.c'] drivers += [trace] # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions diff --git a/src/gallium/winsys/xlib/xlib.c b/src/gallium/winsys/xlib/xlib.c index 4982230000..da72228215 100644 --- a/src/gallium/winsys/xlib/xlib.c +++ b/src/gallium/winsys/xlib/xlib.c @@ -73,16 +73,24 @@ static void _init( void ) switch (xlib_mode) { case MODE_TRACE: +#if defined(GALLIUM_TRACE) && defined(GALLIUM_SOFTPIPE) xmesa_set_driver( &xlib_trace_driver ); +#endif break; case MODE_BRW: +#if defined(GALLIUM_BRW) xmesa_set_driver( &xlib_brw_driver ); +#endif break; case MODE_CELL: +#if defined(GALLIUM_CELL) xmesa_set_driver( &xlib_cell_driver ); +#endif break; case MODE_SOFTPIPE: +#if defined(GALLIUM_SOFTPIPE) xmesa_set_driver( &xlib_softpipe_driver ); +#endif break; default: assert(0); -- cgit v1.2.3 From a2416e3d7ecb2fcf18d93a08bc3cc3639ed97b39 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Mon, 2 Feb 2009 14:42:04 -0800 Subject: r300, amd: Oops, a couple more API changes. Somehow I forgot to commit these. --- src/gallium/winsys/drm/amd/amd_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/amd_buffer.c b/src/gallium/winsys/drm/amd/amd_buffer.c index fb7c6f33ed..4b831c7fcc 100644 --- a/src/gallium/winsys/drm/amd/amd_buffer.c +++ b/src/gallium/winsys/drm/amd/amd_buffer.c @@ -231,7 +231,7 @@ struct pipe_surface *amd_surface_from_handle(struct amd_context *amd_context, pt = pipe_screen->texture_blanket(pipe_screen, &tmpl, &pitch, pb); if (pt == NULL) { - winsys_buffer_reference(pipe_winsys, &pb, NULL); + pipe_buffer_reference(pipe_screen, &pb, NULL); } ps = pipe_screen->get_tex_surface(pipe_screen, pt, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); -- cgit v1.2.3 From 5069bfed29bcee2c89c36c74c6d65d388eb7792e Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 2 Feb 2009 23:47:16 -0500 Subject: gallium: remove pipe_buffer from surfaces this change disassociates, at least from the driver perspective, the surface from buffer. surfaces are technically now views on the textures so make it so by hiding the buffer in the internals of textures. --- src/gallium/winsys/egl_xlib/egl_xlib.c | 5 +++-- src/gallium/winsys/xlib/Makefile | 4 ++-- src/gallium/winsys/xlib/xlib_brw_screen.c | 13 ++++++++++--- src/gallium/winsys/xlib/xlib_cell.c | 4 +++- src/gallium/winsys/xlib/xlib_softpipe.c | 8 +++++--- 5 files changed, 23 insertions(+), 11 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 4876339107..c6b0e3d8c5 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -41,6 +41,7 @@ #include "pipe/internal/p_winsys_screen.h" #include "util/u_memory.h" #include "softpipe/sp_winsys.h" +#include "softpipe/sp_texture.h" #include "eglconfig.h" #include "eglconfigutil.h" @@ -292,7 +293,7 @@ display_surface(struct pipe_winsys *pws, assert(ximage->format); assert(ximage->bitmap_unit); - data = pws->buffer_map(pws, psurf->buffer, 0); + data = pws->buffer_map(pws, softpipe_texture(psurf->texture)->buffer, 0); /* update XImage's fields */ ximage->data = data; @@ -308,7 +309,7 @@ display_surface(struct pipe_winsys *pws, ximage->data = NULL; XDestroyImage(ximage); - pws->buffer_unmap(pws, psurf->buffer); + pws->buffer_unmap(pws, softpipe_texture(psurf->texture)->buffer); } diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 5b71e6dc38..8c2892d49b 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -22,11 +22,11 @@ INCLUDE_DIRS = \ -I$(TOP)/src/gallium/state_trackers/glx/xlib \ -I$(TOP)/src/gallium/auxiliary -DEFINES = \ +DEFINES += \ -DGALLIUM_SOFTPIPE \ - -DGALLIUM_CELL \ -DGALLIUM_TRACE \ -DGALLIUM_BRW +#-DGALLIUM_CELL will be defined by the config */ XLIB_WINSYS_SOURCES = \ xlib.c \ diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c index 5344c502ef..51740a9af6 100644 --- a/src/gallium/winsys/xlib/xlib_brw_screen.c +++ b/src/gallium/winsys/xlib/xlib_brw_screen.c @@ -42,12 +42,19 @@ #include "util/u_memory.h" #include "i965simple/brw_winsys.h" #include "i965simple/brw_screen.h" +#include "i965simple/brw_context.h" + #include "xlib_brw_aub.h" #include "xlib_brw.h" #include "xlib.h" - +static struct pipe_buffer * +buffer_from_surface(struct pipe_surface *surface) +{ + struct brw_texture *texture = (struct brw_texture *)surface; + return texture->buffer; +} struct aub_buffer { char *data; @@ -226,7 +233,7 @@ aub_flush_frontbuffer( struct pipe_winsys *winsys, // struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); brw_aub_dump_bmp( global_winsys->aubfile, surface, - aub_bo(surface->buffer)->offset ); + aub_bo(buffer_from_surface(surface))->offset ); } @@ -449,7 +456,7 @@ xlib_brw_display_surface(struct xmesa_buffer *b, { brw_aub_dump_bmp( global_winsys->aubfile, surf, - aub_bo(surf->buffer)->offset ); + aub_bo(buffer_from_surface(surf))->offset ); } diff --git a/src/gallium/winsys/xlib/xlib_cell.c b/src/gallium/winsys/xlib/xlib_cell.c index bf69593c5c..c87564f4dc 100644 --- a/src/gallium/winsys/xlib/xlib_cell.c +++ b/src/gallium/winsys/xlib/xlib_cell.c @@ -51,6 +51,7 @@ #include "cell/ppu/cell_context.h" #include "cell/ppu/cell_screen.h" #include "cell/ppu/cell_winsys.h" +#include "cell/ppu/cell_texture.h" /** @@ -164,7 +165,8 @@ static void xlib_cell_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf) { XImage *ximage; - struct xm_buffer *xm_buf = xm_buffer(surf->buffer); + struct xm_buffer *xm_buf = xm_buffer( + cell_texture(surf->texture)->buffer); const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE; uint x, y; diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index 01d24584e2..586e1dfca5 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -45,6 +45,7 @@ #include "util/u_math.h" #include "util/u_memory.h" #include "softpipe/sp_winsys.h" +#include "softpipe/sp_texture.h" #include "xlib.h" @@ -58,7 +59,7 @@ struct xm_buffer boolean userBuffer; /** Is this a user-space buffer? */ void *data; void *mapped; - + XImage *tempImage; int shm; XShmSegmentInfo shminfo; @@ -225,11 +226,12 @@ xm_buffer_destroy(struct pipe_winsys *pws, * by the XMesaBuffer. */ static void -xlib_softpipe_display_surface(struct xmesa_buffer *b, +xlib_softpipe_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf) { XImage *ximage; - struct xm_buffer *xm_buf = xm_buffer(surf->buffer); + struct xm_buffer *xm_buf = xm_buffer( + softpipe_texture(surf->texture)->buffer); static boolean no_swap = 0; static boolean firsttime = 1; -- cgit v1.2.3 From e0c3b4970da052308bf7b4e5cbe9186a4b8321db Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 2 Feb 2009 23:54:28 -0500 Subject: gallium: adjust gdi for the latest changes --- src/gallium/winsys/gdi/gdi_softpipe_winsys.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c index 2136cd5f83..4924dbf26a 100644 --- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -45,6 +45,7 @@ #include "util/u_math.h" #include "util/u_memory.h" #include "softpipe/sp_winsys.h" +#include "softpipe/sp_texture.h" #include "shared/stw_winsys.h" @@ -275,7 +276,7 @@ gdi_softpipe_flush_frontbuffer(struct pipe_screen *screen, struct gdi_softpipe_buffer *buffer; BITMAPINFO bmi; - buffer = gdi_softpipe_buffer(surface->buffer); + buffer = gdi_softpipe_buffer(softpipe_texture(surface->texture)->buffer); memset(&bmi, 0, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); -- cgit v1.2.3 From c10fb9579027ae34eda0c52acb353e8da5832495 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 4 Feb 2009 14:55:13 +1000 Subject: nouveau: link against libdrm_nouveau (installed with libdrm) --- src/gallium/winsys/drm/nouveau/common/Makefile | 13 +- src/gallium/winsys/drm/nouveau/common/nouveau_bo.c | 504 --------------------- .../winsys/drm/nouveau/common/nouveau_channel.c | 126 ------ .../winsys/drm/nouveau/common/nouveau_context.c | 20 +- .../winsys/drm/nouveau/common/nouveau_context.h | 10 +- .../winsys/drm/nouveau/common/nouveau_device.c | 159 ------- .../winsys/drm/nouveau/common/nouveau_dma.c | 219 --------- .../winsys/drm/nouveau/common/nouveau_dma.h | 143 ------ .../winsys/drm/nouveau/common/nouveau_drmif.h | 313 ------------- .../winsys/drm/nouveau/common/nouveau_fence.c | 217 --------- .../winsys/drm/nouveau/common/nouveau_grobj.c | 107 ----- .../winsys/drm/nouveau/common/nouveau_local.h | 96 ---- .../winsys/drm/nouveau/common/nouveau_notifier.c | 137 ------ .../winsys/drm/nouveau/common/nouveau_pushbuf.c | 270 ----------- .../winsys/drm/nouveau/common/nouveau_resource.c | 116 ----- .../winsys/drm/nouveau/common/nouveau_winsys.c | 15 +- .../drm/nouveau/common/nouveau_winsys_pipe.c | 28 +- .../winsys/drm/nouveau/common/nv04_surface.c | 8 - .../winsys/drm/nouveau/common/nv50_surface.c | 3 +- src/gallium/winsys/drm/nouveau/dri/Makefile | 3 + .../winsys/drm/nouveau/dri/nouveau_context_dri.h | 2 - .../winsys/drm/nouveau/dri/nouveau_screen_dri.c | 2 +- 22 files changed, 33 insertions(+), 2478 deletions(-) delete mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_bo.c delete mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_channel.c delete mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_device.c delete mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_dma.c delete mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_dma.h delete mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h delete mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_fence.c delete mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c delete mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c delete mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c delete mode 100644 src/gallium/winsys/drm/nouveau/common/nouveau_resource.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/common/Makefile b/src/gallium/winsys/drm/nouveau/common/Makefile index 06f558959d..9bc5c42585 100644 --- a/src/gallium/winsys/drm/nouveau/common/Makefile +++ b/src/gallium/winsys/drm/nouveau/common/Makefile @@ -4,17 +4,8 @@ include $(TOP)/configs/current LIBNAME = nouveaudrm C_SOURCES = \ - nouveau_bo.c \ - nouveau_channel.c \ - nouveau_context.c \ - nouveau_device.c \ - nouveau_dma.c \ - nouveau_fence.c \ - nouveau_grobj.c \ + nouveau_context.c \ nouveau_lock.c \ - nouveau_notifier.c \ - nouveau_pushbuf.c \ - nouveau_resource.c \ nouveau_screen.c \ nouveau_winsys.c \ nouveau_winsys_pipe.c \ @@ -27,6 +18,8 @@ include ./Makefile.template DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \ && pkg-config libdrm --atleast-version=2.3.1 \ + && pkg-config libdrm_nouveau --exact-version=0.5 \ + && pkg-config libdrm_nouveau --cflags \ && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") symlinks: diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_bo.c b/src/gallium/winsys/drm/nouveau/common/nouveau_bo.c deleted file mode 100644 index 76b98bed67..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_bo.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" -#include "nouveau_local.h" - -static void -nouveau_mem_free(struct nouveau_device *dev, struct drm_nouveau_mem_alloc *ma, - void **map) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct drm_nouveau_mem_free mf; - - if (map && *map) { - drmUnmap(*map, ma->size); - *map = NULL; - } - - if (ma->size) { - mf.offset = ma->offset; - mf.flags = ma->flags; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_MEM_FREE, - &mf, sizeof(mf)); - ma->size = 0; - } -} - -static int -nouveau_mem_alloc(struct nouveau_device *dev, unsigned size, unsigned align, - uint32_t flags, struct drm_nouveau_mem_alloc *ma, void **map) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - int ret; - - ma->alignment = align; - ma->size = size; - ma->flags = flags; - if (map) - ma->flags |= NOUVEAU_MEM_MAPPED; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_MEM_ALLOC, ma, - sizeof(struct drm_nouveau_mem_alloc)); - if (ret) - return ret; - - if (map) { - ret = drmMap(nvdev->fd, ma->map_handle, ma->size, map); - if (ret) { - *map = NULL; - nouveau_mem_free(dev, ma, map); - return ret; - } - } - - return 0; -} - -static void -nouveau_bo_tmp_del(void *priv) -{ - struct nouveau_resource *r = priv; - - nouveau_fence_ref(NULL, (struct nouveau_fence **)&r->priv); - nouveau_resource_free(&r); -} - -static unsigned -nouveau_bo_tmp_max(struct nouveau_device_priv *nvdev) -{ - struct nouveau_resource *r = nvdev->sa_heap; - unsigned max = 0; - - while (r) { - if (r->in_use && !nouveau_fence(r->priv)->emitted) { - r = r->next; - continue; - } - - if (max < r->size) - max = r->size; - r = r->next; - } - - return max; -} - -static struct nouveau_resource * -nouveau_bo_tmp(struct nouveau_channel *chan, unsigned size, - struct nouveau_fence *fence) -{ - struct nouveau_device_priv *nvdev = nouveau_device(chan->device); - struct nouveau_resource *r = NULL; - struct nouveau_fence *ref = NULL; - - if (fence) - nouveau_fence_ref(fence, &ref); - else - nouveau_fence_new(chan, &ref); - assert(ref); - - while (nouveau_resource_alloc(nvdev->sa_heap, size, ref, &r)) { - if (nouveau_bo_tmp_max(nvdev) < size) { - nouveau_fence_ref(NULL, &ref); - return NULL; - } - - nouveau_fence_flush(chan); - } - nouveau_fence_signal_cb(ref, nouveau_bo_tmp_del, r); - - return r; -} - -int -nouveau_bo_init(struct nouveau_device *dev) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - int ret; - - ret = nouveau_mem_alloc(dev, 128*1024, 0, NOUVEAU_MEM_AGP | - NOUVEAU_MEM_PCI, &nvdev->sa, &nvdev->sa_map); - if (ret) - return ret; - - ret = nouveau_resource_init(&nvdev->sa_heap, 0, nvdev->sa.size); - if (ret) { - nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); - return ret; - } - - return 0; -} - -void -nouveau_bo_takedown(struct nouveau_device *dev) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); -} - -int -nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, - int size, struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo; - int ret; - - if (!dev || !bo || *bo) - return -EINVAL; - - nvbo = calloc(1, sizeof(struct nouveau_bo_priv)); - if (!nvbo) - return -ENOMEM; - nvbo->base.device = dev; - nvbo->base.size = size; - nvbo->base.handle = bo_to_ptr(nvbo); - nvbo->drm.alignment = align; - nvbo->refcount = 1; - - if (flags & NOUVEAU_BO_TILED) { - nvbo->tiled = 1; - if (flags & NOUVEAU_BO_ZTILE) - nvbo->tiled |= 2; - flags &= ~NOUVEAU_BO_TILED; - } - - ret = nouveau_bo_set_status(&nvbo->base, flags); - if (ret) { - free(nvbo); - return ret; - } - - *bo = &nvbo->base; - return 0; -} - -int -nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size, - struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo; - - if (!dev || !bo || *bo) - return -EINVAL; - - nvbo = calloc(1, sizeof(*nvbo)); - if (!nvbo) - return -ENOMEM; - nvbo->base.device = dev; - - nvbo->sysmem = ptr; - nvbo->user = 1; - - nvbo->base.size = size; - nvbo->base.offset = nvbo->drm.offset; - nvbo->base.handle = bo_to_ptr(nvbo); - nvbo->refcount = 1; - *bo = &nvbo->base; - return 0; -} - -int -nouveau_bo_ref(struct nouveau_device *dev, uint64_t handle, - struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo = ptr_to_bo(handle); - - if (!dev || !bo || *bo) - return -EINVAL; - - nvbo->refcount++; - *bo = &nvbo->base; - return 0; -} - -static void -nouveau_bo_del_cb(void *priv) -{ - struct nouveau_bo_priv *nvbo = priv; - - nouveau_fence_ref(NULL, &nvbo->fence); - nouveau_mem_free(nvbo->base.device, &nvbo->drm, &nvbo->map); - if (nvbo->sysmem && !nvbo->user) - free(nvbo->sysmem); - free(nvbo); -} - -void -nouveau_bo_del(struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo; - - if (!bo || !*bo) - return; - nvbo = nouveau_bo(*bo); - *bo = NULL; - - if (--nvbo->refcount) - return; - - if (nvbo->pending) - nouveau_pushbuf_flush(nvbo->pending->channel, 0); - - if (nvbo->fence) - nouveau_fence_signal_cb(nvbo->fence, nouveau_bo_del_cb, nvbo); - else - nouveau_bo_del_cb(nvbo); -} - -int -nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_fence *fence; - - if (!nvbo) - return -EINVAL; - - /* If the buffer is pending it must be busy, unless - * both are RD, in which case we can allow access */ - if (nvbo->pending) { - if ((nvbo->pending->flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD && - (flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD) - return 0; - else - return 1; - } - - if (flags & NOUVEAU_BO_WR) - fence = nvbo->fence; - else - fence = nvbo->wr_fence; - - /* If the buffer is not pending and doesn't have a fence - * that conflicts with our flags then it can't be busy - */ - if (!fence) - return 0; - else - /* If the fence is signalled the buffer is not busy, else is busy */ - return !nouveau_fence(fence)->signalled; -} - -int -nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - - if (!nvbo) - return -EINVAL; - - if (nvbo->pending && - (nvbo->pending->flags & NOUVEAU_BO_WR || flags & NOUVEAU_BO_WR)) { - nouveau_pushbuf_flush(nvbo->pending->channel, 0); - } - - if (flags & NOUVEAU_BO_WR) - nouveau_fence_wait(&nvbo->fence); - else - nouveau_fence_wait(&nvbo->wr_fence); - - if (nvbo->sysmem) - bo->map = nvbo->sysmem; - else - bo->map = nvbo->map; - return 0; -} - -void -nouveau_bo_unmap(struct nouveau_bo *bo) -{ - bo->map = NULL; -} - -static int -nouveau_bo_upload(struct nouveau_bo_priv *nvbo) -{ - if (nvbo->fence) - nouveau_fence_wait(&nvbo->fence); - memcpy(nvbo->map, nvbo->sysmem, nvbo->drm.size); - return 0; -} - -int -nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct drm_nouveau_mem_alloc new; - void *new_map = NULL, *new_sysmem = NULL; - unsigned new_flags = 0, ret; - - assert(!bo->map); - - /* Check current memtype vs requested, if they match do nothing */ - if ((nvbo->drm.flags & NOUVEAU_MEM_FB) && (flags & NOUVEAU_BO_VRAM)) - return 0; - if ((nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) && - (flags & NOUVEAU_BO_GART)) - return 0; - if (nvbo->drm.size == 0 && nvbo->sysmem && (flags & NOUVEAU_BO_LOCAL)) - return 0; - - memset(&new, 0x00, sizeof(new)); - - /* Allocate new memory */ - if (flags & NOUVEAU_BO_VRAM) - new_flags |= NOUVEAU_MEM_FB; - else - if (flags & NOUVEAU_BO_GART) - new_flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI); - - if (nvbo->tiled && flags) { - new_flags |= NOUVEAU_MEM_TILE; - if (nvbo->tiled & 2) - new_flags |= NOUVEAU_MEM_TILE_ZETA; - } - - if (new_flags) { - ret = nouveau_mem_alloc(bo->device, bo->size, - nvbo->drm.alignment, new_flags, - &new, &new_map); - if (ret) - return ret; - } else - if (!nvbo->user) { - new_sysmem = malloc(bo->size); - } - - /* Copy old -> new */ - /*XXX: use M2MF */ - if (nvbo->sysmem || nvbo->map) { - struct nouveau_pushbuf_bo *pbo = nvbo->pending; - nvbo->pending = NULL; - nouveau_bo_map(bo, NOUVEAU_BO_RD); - memcpy(new_map, bo->map, bo->size); - nouveau_bo_unmap(bo); - nvbo->pending = pbo; - } - - /* Free old memory */ - if (nvbo->fence) - nouveau_fence_wait(&nvbo->fence); - nouveau_mem_free(bo->device, &nvbo->drm, &nvbo->map); - if (nvbo->sysmem && !nvbo->user) - free(nvbo->sysmem); - - nvbo->drm = new; - nvbo->map = new_map; - if (!nvbo->user) - nvbo->sysmem = new_sysmem; - bo->flags = flags; - bo->offset = nvbo->drm.offset; - return 0; -} - -static int -nouveau_bo_validate_user(struct nouveau_channel *chan, struct nouveau_bo *bo, - struct nouveau_fence *fence, uint32_t flags) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_device_priv *nvdev = nouveau_device(chan->device); - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_resource *r; - - if (nvchan->user_charge + bo->size > nvdev->sa.size) - return 1; - - if (!(flags & NOUVEAU_BO_GART)) - return 1; - - r = nouveau_bo_tmp(chan, bo->size, fence); - if (!r) - return 1; - nvchan->user_charge += bo->size; - - memcpy(nvdev->sa_map + r->start, nvbo->sysmem, bo->size); - - nvbo->offset = nvdev->sa.offset + r->start; - nvbo->flags = NOUVEAU_BO_GART; - return 0; -} - -static int -nouveau_bo_validate_bo(struct nouveau_channel *chan, struct nouveau_bo *bo, - struct nouveau_fence *fence, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - int ret; - - ret = nouveau_bo_set_status(bo, flags); - if (ret) { - nouveau_fence_flush(chan); - - ret = nouveau_bo_set_status(bo, flags); - if (ret) - return ret; - } - - if (nvbo->user) - nouveau_bo_upload(nvbo); - - nvbo->offset = nvbo->drm.offset; - if (nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) - nvbo->flags = NOUVEAU_BO_GART; - else - nvbo->flags = NOUVEAU_BO_VRAM; - - return 0; -} - -int -nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo, - uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_fence *fence = nouveau_pushbuf(chan->pushbuf)->fence; - int ret; - - assert(bo->map == NULL); - - if (nvbo->user) { - ret = nouveau_bo_validate_user(chan, bo, fence, flags); - if (ret) { - ret = nouveau_bo_validate_bo(chan, bo, fence, flags); - if (ret) - return ret; - } - } else { - ret = nouveau_bo_validate_bo(chan, bo, fence, flags); - if (ret) - return ret; - } - - if (flags & NOUVEAU_BO_WR) - nouveau_fence_ref(fence, &nvbo->wr_fence); - nouveau_fence_ref(fence, &nvbo->fence); - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_channel.c b/src/gallium/winsys/drm/nouveau/common/nouveau_channel.c deleted file mode 100644 index b7298131c1..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_channel.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include -#include -#include "nouveau_drmif.h" -#include "nouveau_dma.h" - -int -nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, - uint32_t tt_ctxdma, struct nouveau_channel **chan) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct nouveau_channel_priv *nvchan; - int ret; - - if (!nvdev || !chan || *chan) - return -EINVAL; - - nvchan = CALLOC_STRUCT(nouveau_channel_priv); - if (!nvchan) - return -ENOMEM; - nvchan->base.device = dev; - - nvchan->drm.fb_ctxdma_handle = fb_ctxdma; - nvchan->drm.tt_ctxdma_handle = tt_ctxdma; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, - &nvchan->drm, sizeof(nvchan->drm)); - if (ret) { - FREE(nvchan); - return ret; - } - - nvchan->base.id = nvchan->drm.channel; - if (nouveau_grobj_ref(&nvchan->base, nvchan->drm.fb_ctxdma_handle, - &nvchan->base.vram) || - nouveau_grobj_ref(&nvchan->base, nvchan->drm.tt_ctxdma_handle, - &nvchan->base.gart)) { - nouveau_channel_free((void *)&nvchan); - return -EINVAL; - } - - ret = drmMap(nvdev->fd, nvchan->drm.ctrl, nvchan->drm.ctrl_size, - (void*)&nvchan->user); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - nvchan->put = &nvchan->user[0x40/4]; - nvchan->get = &nvchan->user[0x44/4]; - nvchan->ref_cnt = &nvchan->user[0x48/4]; - - ret = drmMap(nvdev->fd, nvchan->drm.notifier, nvchan->drm.notifier_size, - (drmAddressPtr)&nvchan->notifier_block); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - - ret = drmMap(nvdev->fd, nvchan->drm.cmdbuf, nvchan->drm.cmdbuf_size, - (void*)&nvchan->pushbuf); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - - ret = nouveau_grobj_alloc(&nvchan->base, 0x00000000, 0x0030, - &nvchan->base.nullobj); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - - nouveau_dma_channel_init(&nvchan->base); - nouveau_pushbuf_init(&nvchan->base); - - *chan = &nvchan->base; - return 0; -} - -void -nouveau_channel_free(struct nouveau_channel **chan) -{ - struct nouveau_channel_priv *nvchan; - struct nouveau_device_priv *nvdev; - struct drm_nouveau_channel_free cf; - - if (!chan || !*chan) - return; - nvchan = nouveau_channel(*chan); - *chan = NULL; - nvdev = nouveau_device(nvchan->base.device); - - FIRE_RING_CH(&nvchan->base); - - nouveau_grobj_free(&nvchan->base.vram); - nouveau_grobj_free(&nvchan->base.gart); - nouveau_grobj_free(&nvchan->base.nullobj); - - FREE(nvchan->pb.buffers); - FREE(nvchan->pb.relocs); - cf.channel = nvchan->drm.channel; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf)); - FREE(nvchan); -} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c index e093877381..de4a90e25f 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c @@ -43,7 +43,7 @@ nouveau_channel_context_create(struct nouveau_device *dev) return NULL; } - nvc->next_handle = 0x80000000; + nvc->next_handle = 0x88000000; if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, &nvc->sync_notifier))) { @@ -120,22 +120,12 @@ nouveau_context_init(struct nouveau_screen *nv_screen, { struct pipe_surface *fb_surf; struct nouveau_pipe_buffer *fb_buf; - struct nouveau_bo_priv *fb_bo; - - fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); - fb_bo->drm.offset = nv_screen->front_offset; - fb_bo->drm.flags = NOUVEAU_MEM_FB; - fb_bo->drm.size = nv_screen->front_pitch * - nv_screen->front_height; - fb_bo->refcount = 1; - fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; - fb_bo->base.offset = fb_bo->drm.offset; - fb_bo->base.handle = (unsigned long)fb_bo; - fb_bo->base.size = fb_bo->drm.size; - fb_bo->base.device = nv_screen->device; fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); - fb_buf->bo = &fb_bo->base; + + nouveau_bo_fake(dev, nv_screen->front_offset, NOUVEAU_BO_VRAM, + nv_screen->front_pitch*nv_screen->front_height, + NULL, &fb_buf->bo); fb_surf = calloc(1, sizeof(struct pipe_surface)); if (nv_screen->front_cpp == 2) diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h index b1bdb01bdf..d7199db3de 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h @@ -3,7 +3,14 @@ #include "nouveau/nouveau_winsys.h" #include "nouveau_drmif.h" -#include "nouveau_dma.h" +#include "nouveau_device.h" +#include "nouveau_channel.h" +#include "nouveau_pushbuf.h" +#include "nouveau_bo.h" +#include "nouveau_grobj.h" +#include "nouveau_notifier.h" +#include "nouveau_class.h" +#include "nouveau_local.h" struct nouveau_channel_context { struct pipe_screen *pscreen; @@ -29,7 +36,6 @@ struct nouveau_channel_context { struct nouveau_grobj *Nv2D; uint32_t next_handle; - uint32_t next_subchannel; uint32_t next_sequence; }; diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_device.c b/src/gallium/winsys/drm/nouveau/common/nouveau_device.c deleted file mode 100644 index 92b57b834b..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_device.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include -#include -#include "nouveau_drmif.h" - -int -nouveau_device_open_existing(struct nouveau_device **dev, int close, - int fd, drm_context_t ctx) -{ - struct nouveau_device_priv *nvdev; - int ret; - - if (!dev || *dev) - return -EINVAL; - - nvdev = CALLOC_STRUCT(nouveau_device_priv); - if (!nvdev) - return -ENOMEM; - nvdev->fd = fd; - nvdev->ctx = ctx; - nvdev->needs_close = close; - - drmCommandNone(nvdev->fd, DRM_NOUVEAU_CARD_INIT); - - if ((ret = nouveau_bo_init(&nvdev->base))) { - nouveau_device_close((void *)&nvdev); - return ret; - } - - { - uint64_t value; - - ret = nouveau_device_get_param(&nvdev->base, - NOUVEAU_GETPARAM_CHIPSET_ID, - &value); - if (ret) { - nouveau_device_close((void *)&nvdev); - return ret; - } - nvdev->base.chipset = value; - } - - *dev = &nvdev->base; - return 0; -} - -int -nouveau_device_open(struct nouveau_device **dev, const char *busid) -{ - drm_context_t ctx; - int fd, ret; - - if (!dev || *dev) - return -EINVAL; - - fd = drmOpen("nouveau", busid); - if (fd < 0) - return -EINVAL; - - ret = drmCreateContext(fd, &ctx); - if (ret) { - drmClose(fd); - return ret; - } - - ret = nouveau_device_open_existing(dev, 1, fd, ctx); - if (ret) { - drmDestroyContext(fd, ctx); - drmClose(fd); - return ret; - } - - return 0; -} - -void -nouveau_device_close(struct nouveau_device **dev) -{ - struct nouveau_device_priv *nvdev; - - if (dev || !*dev) - return; - nvdev = nouveau_device(*dev); - *dev = NULL; - - nouveau_bo_takedown(&nvdev->base); - - if (nvdev->needs_close) { - drmDestroyContext(nvdev->fd, nvdev->ctx); - drmClose(nvdev->fd); - } - FREE(nvdev); -} - -int -nouveau_device_get_param(struct nouveau_device *dev, - uint64_t param, uint64_t *value) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct drm_nouveau_getparam g; - int ret; - - if (!nvdev || !value) - return -EINVAL; - - g.param = param; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GETPARAM, - &g, sizeof(g)); - if (ret) - return ret; - - *value = g.value; - return 0; -} - -int -nouveau_device_set_param(struct nouveau_device *dev, - uint64_t param, uint64_t value) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct drm_nouveau_setparam s; - int ret; - - if (!nvdev) - return -EINVAL; - - s.param = param; - s.value = value; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_SETPARAM, - &s, sizeof(s)); - if (ret) - return ret; - - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_dma.c b/src/gallium/winsys/drm/nouveau/common/nouveau_dma.c deleted file mode 100644 index f8a8ba04f6..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_dma.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" -#include "nouveau_local.h" - -static inline uint32_t -READ_GET(struct nouveau_channel_priv *nvchan) -{ - return *nvchan->get; -} - -static inline void -WRITE_PUT(struct nouveau_channel_priv *nvchan, uint32_t val) -{ - uint32_t put = ((val << 2) + nvchan->dma->base); - volatile int dum; - - NOUVEAU_DMA_BARRIER; - dum = READ_GET(nvchan); - - *nvchan->put = put; - nvchan->dma->put = val; -#ifdef NOUVEAU_DMA_TRACE - NOUVEAU_MSG("WRITE_PUT %d/0x%08x\n", nvchan->drm.channel, put); -#endif - - NOUVEAU_DMA_BARRIER; -} - -static inline int -LOCAL_GET(struct nouveau_dma_priv *dma, uint32_t *val) -{ - uint32_t get = *val; - - if (get >= dma->base && get <= (dma->base + (dma->max << 2))) { - *val = (get - dma->base) >> 2; - return 1; - } - - return 0; -} - -void -nouveau_dma_channel_init(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - int i; - - nvchan->dma = &nvchan->dma_master; - nvchan->dma->base = nvchan->drm.put_base; - nvchan->dma->cur = nvchan->dma->put = 0; - nvchan->dma->max = (nvchan->drm.cmdbuf_size >> 2) - 2; - nvchan->dma->free = nvchan->dma->max - nvchan->dma->cur; - - RING_SPACE_CH(chan, RING_SKIPS); - for (i = 0; i < RING_SKIPS; i++) - OUT_RING_CH(chan, 0); -} - -#define CHECK_TIMEOUT() do { \ - if ((NOUVEAU_TIME_MSEC() - t_start) > NOUVEAU_DMA_TIMEOUT) \ - return - EBUSY; \ -} while(0) - -int -nouveau_dma_wait(struct nouveau_channel *chan, int size) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - uint32_t get, t_start; - - FIRE_RING_CH(chan); - - t_start = NOUVEAU_TIME_MSEC(); - while (dma->free < size) { - CHECK_TIMEOUT(); - - get = READ_GET(nvchan); - if (!LOCAL_GET(dma, &get)) - continue; - - if (dma->put >= get) { - dma->free = dma->max - dma->cur; - - if (dma->free < size) { -#ifdef NOUVEAU_DMA_DEBUG - dma->push_free = 1; -#endif - OUT_RING_CH(chan, 0x20000000 | dma->base); - if (get <= RING_SKIPS) { - /*corner case - will be idle*/ - if (dma->put <= RING_SKIPS) - WRITE_PUT(nvchan, - RING_SKIPS + 1); - - do { - CHECK_TIMEOUT(); - get = READ_GET(nvchan); - if (!LOCAL_GET(dma, &get)) - get = 0; - } while (get <= RING_SKIPS); - } - - WRITE_PUT(nvchan, RING_SKIPS); - dma->cur = dma->put = RING_SKIPS; - dma->free = get - (RING_SKIPS + 1); - } - } else { - dma->free = get - dma->cur - 1; - } - } - - return 0; -} - -#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF -static void -nouveau_dma_parse_pushbuf(struct nouveau_channel *chan, int get, int put) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - unsigned mthd_count = 0; - - while (get != put) { - uint32_t gpuget = (get << 2) + nvchan->drm.put_base; - uint32_t data; - - if (get < 0 || get >= nvchan->drm.cmdbuf_size) { - NOUVEAU_ERR("DMA_PT 0x%08x\n", gpuget); - assert(0); - } - data = nvchan->pushbuf[get++]; - - if (mthd_count) { - NOUVEAU_MSG("0x%08x 0x%08x\n", gpuget, data); - mthd_count--; - continue; - } - - switch (data & 0x60000000) { - case 0x00000000: - mthd_count = (data >> 18) & 0x7ff; - NOUVEAU_MSG("0x%08x 0x%08x MTHD " - "Sc %d Mthd 0x%04x Size %d\n", - gpuget, data, (data>>13) & 7, data & 0x1ffc, - mthd_count); - break; - case 0x20000000: - get = (data & 0x1ffffffc) >> 2; - NOUVEAU_MSG("0x%08x 0x%08x JUMP 0x%08x\n", - gpuget, data, data & 0x1ffffffc); - continue; - case 0x40000000: - mthd_count = (data >> 18) & 0x7ff; - NOUVEAU_MSG("0x%08x 0x%08x NINC " - "Sc %d Mthd 0x%04x Size %d\n", - gpuget, data, (data>>13) & 7, data & 0x1ffc, - mthd_count); - break; - case 0x60000000: - /* DMA_OPCODE_CALL apparently, doesn't seem to work on - * my NV40 at least.. - */ - /* fall-through */ - default: - NOUVEAU_MSG("DMA_PUSHER 0x%08x 0x%08x\n", - gpuget, data); - assert(0); - } - } -} -#endif - -void -nouveau_dma_kickoff(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - - if (dma->cur == dma->put) - return; - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free) { - NOUVEAU_ERR("Packet incomplete: %d left\n", dma->push_free); - return; - } -#endif - -#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF - nouveau_dma_parse_pushbuf(chan, dma->put, dma->cur); -#endif - - WRITE_PUT(nvchan, dma->cur); -} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_dma.h b/src/gallium/winsys/drm/nouveau/common/nouveau_dma.h deleted file mode 100644 index cfa6d26e82..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_dma.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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. - */ - -#ifndef __NOUVEAU_DMA_H__ -#define __NOUVEAU_DMA_H__ - -#include -#include "nouveau_drmif.h" -#include "nouveau_local.h" - -#define RING_SKIPS 8 - -extern int nouveau_dma_wait(struct nouveau_channel *chan, int size); -extern void nouveau_dma_subc_bind(struct nouveau_grobj *); -extern void nouveau_dma_channel_init(struct nouveau_channel *); -extern void nouveau_dma_kickoff(struct nouveau_channel *); - -#ifdef NOUVEAU_DMA_DEBUG -static char faulty[1024]; -#endif - -static inline void -nouveau_dma_out(struct nouveau_channel *chan, uint32_t data) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free == 0) { - NOUVEAU_ERR("No space left in packet at %s\n", faulty); - return; - } - dma->push_free--; -#endif -#ifdef NOUVEAU_DMA_TRACE - { - uint32_t offset = (dma->cur << 2) + dma->base; - NOUVEAU_MSG("\tOUT_RING %d/0x%08x -> 0x%08x\n", - nvchan->drm.channel, offset, data); - } -#endif - nvchan->pushbuf[dma->cur + (dma->base - nvchan->drm.put_base)/4] = data; - dma->cur++; -} - -static inline void -nouveau_dma_outp(struct nouveau_channel *chan, uint32_t *ptr, int size) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - (void)dma; - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free < size) { - NOUVEAU_ERR("Packet too small. Free=%d, Need=%d\n", - dma->push_free, size); - return; - } -#endif -#ifdef NOUVEAU_DMA_TRACE - while (size--) { - nouveau_dma_out(chan, *ptr); - ptr++; - } -#else - memcpy(&nvchan->pushbuf[dma->cur], ptr, size << 2); -#ifdef NOUVEAU_DMA_DEBUG - dma->push_free -= size; -#endif - dma->cur += size; -#endif -} - -static inline void -nouveau_dma_space(struct nouveau_channel *chan, int size) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - - if (dma->free < size) { - if (nouveau_dma_wait(chan, size) && chan->hang_notify) - chan->hang_notify(chan); - } - dma->free -= size; -#ifdef NOUVEAU_DMA_DEBUG - dma->push_free = size; -#endif -} - -static inline void -nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj, - int method, int size, const char* file, int line) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - (void)dma; - -#ifdef NOUVEAU_DMA_TRACE - NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", nvchan->drm.channel, - grobj->handle, grobj->subc, method, size); -#endif - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free) { - NOUVEAU_ERR("Previous packet incomplete: %d left at %s\n", - dma->push_free, faulty); - return; - } - sprintf(faulty,"%s:%d",file,line); -#endif - - nouveau_dma_space(chan, (size + 1)); - nouveau_dma_out(chan, (size << 18) | (grobj->subc << 13) | method); -} - -#define RING_SPACE_CH(ch,sz) nouveau_dma_space((ch), (sz)) -#define BEGIN_RING_CH(ch,gr,m,sz) nouveau_dma_begin((ch), (gr), (m), (sz), __FUNCTION__, __LINE__ ) -#define OUT_RING_CH(ch, data) nouveau_dma_out((ch), (data)) -#define OUT_RINGp_CH(ch,ptr,dwords) nouveau_dma_outp((ch), (void*)(ptr), \ - (dwords)) -#define FIRE_RING_CH(ch) nouveau_dma_kickoff((ch)) -#define WAIT_RING_CH(ch,sz) nouveau_dma_wait((ch), (sz)) - -#endif diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h b/src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h deleted file mode 100644 index 5f72800676..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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. - */ - -#ifndef __NOUVEAU_DRMIF_H__ -#define __NOUVEAU_DRMIF_H__ - -#include -#include -#include - -#include "nouveau/nouveau_device.h" -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_grobj.h" -#include "nouveau/nouveau_notifier.h" -#include "nouveau/nouveau_bo.h" -#include "nouveau/nouveau_resource.h" -#include "nouveau/nouveau_pushbuf.h" - -struct nouveau_device_priv { - struct nouveau_device base; - - int fd; - drm_context_t ctx; - drmLock *lock; - int needs_close; - - struct drm_nouveau_mem_alloc sa; - void *sa_map; - struct nouveau_resource *sa_heap; -}; -#define nouveau_device(n) ((struct nouveau_device_priv *)(n)) - -extern int -nouveau_device_open_existing(struct nouveau_device **, int close, - int fd, drm_context_t ctx); - -extern int -nouveau_device_open(struct nouveau_device **, const char *busid); - -extern void -nouveau_device_close(struct nouveau_device **); - -extern int -nouveau_device_get_param(struct nouveau_device *, uint64_t param, uint64_t *v); - -extern int -nouveau_device_set_param(struct nouveau_device *, uint64_t param, uint64_t val); - -struct nouveau_fence { - struct nouveau_channel *channel; -}; - -struct nouveau_fence_cb { - struct nouveau_fence_cb *next; - void (*func)(void *); - void *priv; -}; - -struct nouveau_fence_priv { - struct nouveau_fence base; - int refcount; - - struct nouveau_fence *next; - struct nouveau_fence_cb *signal_cb; - - uint32_t sequence; - int emitted; - int signalled; -}; -#define nouveau_fence(n) ((struct nouveau_fence_priv *)(n)) - -extern int -nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **); - -extern int -nouveau_fence_ref(struct nouveau_fence *, struct nouveau_fence **); - -extern int -nouveau_fence_signal_cb(struct nouveau_fence *, void (*)(void *), void *); - -extern void -nouveau_fence_emit(struct nouveau_fence *); - -extern int -nouveau_fence_wait(struct nouveau_fence **); - -extern void -nouveau_fence_flush(struct nouveau_channel *); - -struct nouveau_pushbuf_reloc { - struct nouveau_pushbuf_bo *pbbo; - uint32_t *ptr; - uint32_t flags; - uint32_t data; - uint32_t vor; - uint32_t tor; -}; - -struct nouveau_pushbuf_bo { - struct nouveau_channel *channel; - struct nouveau_bo *bo; - unsigned flags; - unsigned handled; -}; - -#define NOUVEAU_PUSHBUF_MAX_BUFFERS 1024 -#define NOUVEAU_PUSHBUF_MAX_RELOCS 1024 -struct nouveau_pushbuf_priv { - struct nouveau_pushbuf base; - - struct nouveau_fence *fence; - - unsigned nop_jump; - unsigned start; - unsigned size; - - struct nouveau_pushbuf_bo *buffers; - unsigned nr_buffers; - struct nouveau_pushbuf_reloc *relocs; - unsigned nr_relocs; -}; -#define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n)) - -#define pbbo_to_ptr(o) ((uint64_t)(unsigned long)(o)) -#define ptr_to_pbbo(h) ((struct nouveau_pushbuf_bo *)(unsigned long)(h)) -#define pbrel_to_ptr(o) ((uint64_t)(unsigned long)(o)) -#define ptr_to_pbrel(h) ((struct nouveau_pushbuf_reloc *)(unsigned long)(h)) -#define bo_to_ptr(o) ((uint64_t)(unsigned long)(o)) -#define ptr_to_bo(h) ((struct nouveau_bo_priv *)(unsigned long)(h)) - -extern int -nouveau_pushbuf_init(struct nouveau_channel *); - -extern int -nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); - -extern int -nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr, - struct nouveau_bo *, uint32_t data, uint32_t flags, - uint32_t vor, uint32_t tor); - -struct nouveau_dma_priv { - uint32_t base; - uint32_t max; - uint32_t cur; - uint32_t put; - uint32_t free; - - int push_free; -} dma; - -struct nouveau_channel_priv { - struct nouveau_channel base; - - struct drm_nouveau_channel_alloc drm; - - uint32_t *pushbuf; - void *notifier_block; - - volatile uint32_t *user; - volatile uint32_t *put; - volatile uint32_t *get; - volatile uint32_t *ref_cnt; - - struct nouveau_dma_priv dma_master; - struct nouveau_dma_priv dma_bufmgr; - struct nouveau_dma_priv *dma; - - struct nouveau_fence *fence_head; - struct nouveau_fence *fence_tail; - uint32_t fence_sequence; - - struct nouveau_pushbuf_priv pb; - - unsigned user_charge; -}; -#define nouveau_channel(n) ((struct nouveau_channel_priv *)(n)) - -extern int -nouveau_channel_alloc(struct nouveau_device *, uint32_t fb, uint32_t tt, - struct nouveau_channel **); - -extern void -nouveau_channel_free(struct nouveau_channel **); - -struct nouveau_grobj_priv { - struct nouveau_grobj base; -}; -#define nouveau_grobj(n) ((struct nouveau_grobj_priv *)(n)) - -extern int nouveau_grobj_alloc(struct nouveau_channel *, uint32_t handle, - int class, struct nouveau_grobj **); -extern int nouveau_grobj_ref(struct nouveau_channel *, uint32_t handle, - struct nouveau_grobj **); -extern void nouveau_grobj_free(struct nouveau_grobj **); - - -struct nouveau_notifier_priv { - struct nouveau_notifier base; - - struct drm_nouveau_notifierobj_alloc drm; - volatile void *map; -}; -#define nouveau_notifier(n) ((struct nouveau_notifier_priv *)(n)) - -extern int -nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, int count, - struct nouveau_notifier **); - -extern void -nouveau_notifier_free(struct nouveau_notifier **); - -extern void -nouveau_notifier_reset(struct nouveau_notifier *, int id); - -extern uint32_t -nouveau_notifier_status(struct nouveau_notifier *, int id); - -extern uint32_t -nouveau_notifier_return_val(struct nouveau_notifier *, int id); - -extern int -nouveau_notifier_wait_status(struct nouveau_notifier *, int id, int status, - int timeout); - -struct nouveau_bo_priv { - struct nouveau_bo base; - - struct nouveau_pushbuf_bo *pending; - struct nouveau_fence *fence; - struct nouveau_fence *wr_fence; - - struct drm_nouveau_mem_alloc drm; - void *map; - - void *sysmem; - int user; - - int refcount; - - uint64_t offset; - uint64_t flags; - int tiled; -}; -#define nouveau_bo(n) ((struct nouveau_bo_priv *)(n)) - -extern int -nouveau_bo_init(struct nouveau_device *); - -extern void -nouveau_bo_takedown(struct nouveau_device *); - -extern int -nouveau_bo_new(struct nouveau_device *, uint32_t flags, int align, int size, - struct nouveau_bo **); - -extern int -nouveau_bo_user(struct nouveau_device *, void *ptr, int size, - struct nouveau_bo **); - -extern int -nouveau_bo_ref(struct nouveau_device *, uint64_t handle, struct nouveau_bo **); - -extern int -nouveau_bo_set_status(struct nouveau_bo *, uint32_t flags); - -extern void -nouveau_bo_del(struct nouveau_bo **); - -extern int -nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags); - -extern int -nouveau_bo_map(struct nouveau_bo *, uint32_t flags); - -extern void -nouveau_bo_unmap(struct nouveau_bo *); - -extern int -nouveau_bo_validate(struct nouveau_channel *, struct nouveau_bo *, - uint32_t flags); - -extern int -nouveau_resource_init(struct nouveau_resource **heap, unsigned start, - unsigned size); - -extern int -nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, - struct nouveau_resource **); - -extern void -nouveau_resource_free(struct nouveau_resource **); - -#endif diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c b/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c deleted file mode 100644 index 451011e112..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" -#include "nouveau_local.h" - -static void -nouveau_fence_del_unsignalled(struct nouveau_fence *fence) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); - struct nouveau_fence *le; - - if (nvchan->fence_head == fence) { - nvchan->fence_head = nouveau_fence(fence)->next; - if (nvchan->fence_head == NULL) - nvchan->fence_tail = NULL; - return; - } - - le = nvchan->fence_head; - while (le && nouveau_fence(le)->next != fence) - le = nouveau_fence(le)->next; - assert(le && nouveau_fence(le)->next == fence); - nouveau_fence(le)->next = nouveau_fence(fence)->next; - if (nvchan->fence_tail == fence) - nvchan->fence_tail = le; -} - -static void -nouveau_fence_del(struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!fence || !*fence) - return; - nvfence = nouveau_fence(*fence); - *fence = NULL; - - if (--nvfence->refcount) - return; - - if (nvfence->emitted && !nvfence->signalled) { - if (nvfence->signal_cb) { - nvfence->refcount++; - nouveau_fence_wait((void *)&nvfence); - return; - } - - nouveau_fence_del_unsignalled(&nvfence->base); - } - free(nvfence); -} - -int -nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!chan || !fence || *fence) - return -EINVAL; - - nvfence = calloc(1, sizeof(struct nouveau_fence_priv)); - if (!nvfence) - return -ENOMEM; - nvfence->base.channel = chan; - nvfence->refcount = 1; - - *fence = &nvfence->base; - return 0; -} - -int -nouveau_fence_ref(struct nouveau_fence *ref, struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!fence) - return -EINVAL; - - if (*fence) { - nouveau_fence_del(fence); - *fence = NULL; - } - - if (ref) { - nvfence = nouveau_fence(ref); - nvfence->refcount++; - *fence = &nvfence->base; - } - - return 0; -} - -int -nouveau_fence_signal_cb(struct nouveau_fence *fence, void (*func)(void *), - void *priv) -{ - struct nouveau_fence_priv *nvfence = nouveau_fence(fence); - struct nouveau_fence_cb *cb; - - if (!nvfence || !func) - return -EINVAL; - - cb = malloc(sizeof(struct nouveau_fence_cb)); - if (!cb) - return -ENOMEM; - - cb->func = func; - cb->priv = priv; - cb->next = nvfence->signal_cb; - nvfence->signal_cb = cb; - return 0; -} - -void -nouveau_fence_emit(struct nouveau_fence *fence) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); - struct nouveau_fence_priv *nvfence = nouveau_fence(fence); - - nvfence->emitted = 1; - nvfence->sequence = ++nvchan->fence_sequence; - if (nvfence->sequence == 0xffffffff) - NOUVEAU_ERR("AII wrap unhandled\n"); - - /*XXX: assumes subc 0 is populated */ - /* Not the way to fence on nv4 */ - if (nvchan->base.device->chipset >= 0x10) { - RING_SPACE_CH(fence->channel, 2); - OUT_RING_CH (fence->channel, 0x00040050); - OUT_RING_CH (fence->channel, nvfence->sequence); - } - - if (nvchan->fence_tail) { - nouveau_fence(nvchan->fence_tail)->next = fence; - } else { - nvchan->fence_head = fence; - } - nvchan->fence_tail = fence; -} - -void -nouveau_fence_flush(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - uint32_t sequence = *nvchan->ref_cnt; - - while (nvchan->fence_head) { - struct nouveau_fence_priv *nvfence; - - nvfence = nouveau_fence(nvchan->fence_head); - if (nvfence->sequence > sequence) - break; - nouveau_fence_del_unsignalled(&nvfence->base); - nvfence->signalled = 1; - - if (nvfence->signal_cb) { - struct nouveau_fence *fence = NULL; - - nouveau_fence_ref(&nvfence->base, &fence); - - while (nvfence->signal_cb) { - struct nouveau_fence_cb *cb; - - cb = nvfence->signal_cb; - nvfence->signal_cb = cb->next; - cb->func(cb->priv); - free(cb); - } - - nouveau_fence_ref(NULL, &fence); - } - } -} - -int -nouveau_fence_wait(struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!fence || !*fence) - return -EINVAL; - nvfence = nouveau_fence(*fence); - - if (nvfence->emitted) { - while (!nvfence->signalled) - nouveau_fence_flush(nvfence->base.channel); - } - nouveau_fence_ref(NULL, fence); - - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c b/src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c deleted file mode 100644 index fb430a25b8..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include -#include "nouveau_drmif.h" - -int -nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle, - int class, struct nouveau_grobj **grobj) -{ - struct nouveau_device_priv *nvdev = nouveau_device(chan->device); - struct nouveau_grobj_priv *nvgrobj; - struct drm_nouveau_grobj_alloc g; - int ret; - - if (!nvdev || !grobj || *grobj) - return -EINVAL; - - nvgrobj = CALLOC_STRUCT(nouveau_grobj_priv); - if (!nvgrobj) - return -ENOMEM; - nvgrobj->base.channel = chan; - nvgrobj->base.handle = handle; - nvgrobj->base.grclass = class; - - g.channel = chan->id; - g.handle = handle; - g.class = class; - ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GROBJ_ALLOC, - &g, sizeof(g)); - if (ret) { - nouveau_grobj_free((void *)&nvgrobj); - return ret; - } - - *grobj = &nvgrobj->base; - return 0; -} - -int -nouveau_grobj_ref(struct nouveau_channel *chan, uint32_t handle, - struct nouveau_grobj **grobj) -{ - struct nouveau_grobj_priv *nvgrobj; - - if (!chan || !grobj || *grobj) - return -EINVAL; - - nvgrobj = CALLOC_STRUCT(nouveau_grobj_priv); - if (!nvgrobj) - return -ENOMEM; - nvgrobj->base.channel = chan; - nvgrobj->base.handle = handle; - nvgrobj->base.grclass = 0; - - *grobj = &nvgrobj->base; - return 0; -} - -void -nouveau_grobj_free(struct nouveau_grobj **grobj) -{ - struct nouveau_device_priv *nvdev; - struct nouveau_channel_priv *chan; - struct nouveau_grobj_priv *nvgrobj; - - if (!grobj || !*grobj) - return; - nvgrobj = nouveau_grobj(*grobj); - *grobj = NULL; - - - chan = nouveau_channel(nvgrobj->base.channel); - nvdev = nouveau_device(chan->base.device); - - if (nvgrobj->base.grclass) { - struct drm_nouveau_gpuobj_free f; - - f.channel = chan->drm.channel; - f.handle = nvgrobj->base.handle; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, - &f, sizeof(f)); - } - FREE(nvgrobj); -} - diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_local.h b/src/gallium/winsys/drm/nouveau/common/nouveau_local.h index 877c7a8c47..11175bce7a 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_local.h +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_local.h @@ -16,100 +16,4 @@ fflush(stderr); \ } while(0) -#define NOUVEAU_TIME_MSEC() 0 - -/* User FIFO control */ -//#define NOUVEAU_DMA_TRACE -//#define NOUVEAU_DMA_DEBUG -//#define NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF -#define NOUVEAU_DMA_BARRIER -#define NOUVEAU_DMA_TIMEOUT 2000 - -/* Push buffer access macros */ -static INLINE void -OUT_RING(struct nouveau_channel *chan, unsigned data) -{ - *(chan->pushbuf->cur++) = (data); -} - -static INLINE void -OUT_RINGp(struct nouveau_channel *chan, uint32_t *data, unsigned size) -{ - memcpy(chan->pushbuf->cur, data, size * 4); - chan->pushbuf->cur += size; -} - -static INLINE void -OUT_RINGf(struct nouveau_channel *chan, float f) -{ - union { uint32_t i; float f; } c; - c.f = f; - OUT_RING(chan, c.i); -} - -static INLINE void -BEGIN_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, - unsigned mthd, unsigned size) -{ - if (chan->pushbuf->remaining < (size + 1)) - nouveau_pushbuf_flush(chan, (size + 1)); - OUT_RING(chan, (gr->subc << 13) | (size << 18) | mthd); - chan->pushbuf->remaining -= (size + 1); -} - -static INLINE void -FIRE_RING(struct nouveau_channel *chan) -{ - nouveau_pushbuf_flush(chan, 0); -} - -static INLINE void -BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc) -{ - gr->subc = subc; - BEGIN_RING(chan, gr, 0x0000, 1); - OUT_RING (chan, gr->handle); -} - -static INLINE void -OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned data, unsigned flags, unsigned vor, unsigned tor) -{ - nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, - data, flags, vor, tor); -} - -/* Raw data + flags depending on FB/TT buffer */ -static INLINE void -OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned data, unsigned flags, unsigned vor, unsigned tor) -{ - OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor); -} - -/* FB/TT object handle */ -static INLINE void -OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned flags) -{ - OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR, - chan->vram->handle, chan->gart->handle); -} - -/* Low 32-bits of offset */ -static INLINE void -OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned delta, unsigned flags) -{ - OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0); -} - -/* High 32-bits of offset */ -static INLINE void -OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned delta, unsigned flags) -{ - OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); -} - #endif diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c b/src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c deleted file mode 100644 index 01e8f38440..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include - -#include "nouveau_drmif.h" -#include "nouveau_local.h" - -#define NOTIFIER(__v) \ - struct nouveau_notifier_priv *nvnotify = nouveau_notifier(notifier); \ - volatile uint32_t *__v = (void*)nvnotify->map + (id * 32) - -int -nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, - int count, struct nouveau_notifier **notifier) -{ - struct nouveau_notifier_priv *nvnotify; - int ret; - - if (!chan || !notifier || *notifier) - return -EINVAL; - - nvnotify = calloc(1, sizeof(struct nouveau_notifier_priv)); - if (!nvnotify) - return -ENOMEM; - nvnotify->base.channel = chan; - nvnotify->base.handle = handle; - - nvnotify->drm.channel = chan->id; - nvnotify->drm.handle = handle; - nvnotify->drm.count = count; - if ((ret = drmCommandWriteRead(nouveau_device(chan->device)->fd, - DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, - &nvnotify->drm, - sizeof(nvnotify->drm)))) { - nouveau_notifier_free((void *)&nvnotify); - return ret; - } - - nvnotify->map = (void *)nouveau_channel(chan)->notifier_block + - nvnotify->drm.offset; - *notifier = &nvnotify->base; - return 0; -} - -void -nouveau_notifier_free(struct nouveau_notifier **notifier) -{ - - struct nouveau_notifier_priv *nvnotify; - struct nouveau_channel_priv *nvchan; - struct nouveau_device_priv *nvdev; - struct drm_nouveau_gpuobj_free f; - - if (!notifier || !*notifier) - return; - nvnotify = nouveau_notifier(*notifier); - *notifier = NULL; - - nvchan = nouveau_channel(nvnotify->base.channel); - nvdev = nouveau_device(nvchan->base.device); - - f.channel = nvchan->drm.channel; - f.handle = nvnotify->base.handle; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, &f, sizeof(f)); - free(nvnotify); -} - -void -nouveau_notifier_reset(struct nouveau_notifier *notifier, int id) -{ - NOTIFIER(n); - - n[NV_NOTIFY_TIME_0 /4] = 0x00000000; - n[NV_NOTIFY_TIME_1 /4] = 0x00000000; - n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000; - n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS << - NV_NOTIFY_STATE_STATUS_SHIFT); -} - -uint32_t -nouveau_notifier_status(struct nouveau_notifier *notifier, int id) -{ - NOTIFIER(n); - - return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; -} - -uint32_t -nouveau_notifier_return_val(struct nouveau_notifier *notifier, int id) -{ - NOTIFIER(n); - - return n[NV_NOTIFY_RETURN_VALUE/4]; -} - -int -nouveau_notifier_wait_status(struct nouveau_notifier *notifier, int id, - int status, int timeout) -{ - NOTIFIER(n); - uint32_t time = 0, t_start = NOUVEAU_TIME_MSEC(); - - while (time <= timeout) { - uint32_t v; - - v = n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; - if (v == status) - return 0; - - if (timeout) - time = NOUVEAU_TIME_MSEC() - t_start; - } - - return -EBUSY; -} - diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c b/src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c deleted file mode 100644 index 7c094eb795..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include -#include -#include "nouveau_drmif.h" -#include "nouveau_dma.h" - -#define PB_BUFMGR_DWORDS (4096 / 2) -#define PB_MIN_USER_DWORDS 2048 - -static int -nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; - - assert((min + 1) <= nvchan->dma->max); - - /* Wait for enough space in push buffer */ - min = min < PB_MIN_USER_DWORDS ? PB_MIN_USER_DWORDS : min; - min += 1; /* a bit extra for the NOP */ - if (nvchan->dma->free < min) - WAIT_RING_CH(chan, min); - - /* Insert NOP, may turn into a jump later */ - RING_SPACE_CH(chan, 1); - nvpb->nop_jump = nvchan->dma->cur; - OUT_RING_CH(chan, 0); - - /* Any remaining space is available to the user */ - nvpb->start = nvchan->dma->cur; - nvpb->size = nvchan->dma->free; - nvpb->base.channel = chan; - nvpb->base.remaining = nvpb->size; - nvpb->base.cur = &nvchan->pushbuf[nvpb->start]; - - /* Create a new fence object for this "frame" */ - nouveau_fence_ref(NULL, &nvpb->fence); - nouveau_fence_new(chan, &nvpb->fence); - - return 0; -} - -int -nouveau_pushbuf_init(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *m = &nvchan->dma_master; - struct nouveau_dma_priv *b = &nvchan->dma_bufmgr; - int i; - - if (!nvchan) - return -EINVAL; - - /* Reassign last bit of push buffer for a "separate" bufmgr - * ring buffer - */ - m->max -= PB_BUFMGR_DWORDS; - m->free -= PB_BUFMGR_DWORDS; - - b->base = m->base + ((m->max + 2) << 2); - b->max = PB_BUFMGR_DWORDS - 2; - b->cur = b->put = 0; - b->free = b->max - b->cur; - - /* Some NOPs just to be safe - *XXX: RING_SKIPS - */ - nvchan->dma = b; - RING_SPACE_CH(chan, 8); - for (i = 0; i < 8; i++) - OUT_RING_CH(chan, 0); - nvchan->dma = m; - - nouveau_pushbuf_space(chan, 0); - chan->pushbuf = &nvchan->pb.base; - - nvchan->pb.buffers = CALLOC(NOUVEAU_PUSHBUF_MAX_BUFFERS, - sizeof(struct nouveau_pushbuf_bo)); - nvchan->pb.relocs = CALLOC(NOUVEAU_PUSHBUF_MAX_RELOCS, - sizeof(struct nouveau_pushbuf_reloc)); - return 0; -} - -static uint32_t -nouveau_pushbuf_calc_reloc(struct nouveau_bo *bo, - struct nouveau_pushbuf_reloc *r) -{ - uint32_t push; - - if (r->flags & NOUVEAU_BO_LOW) { - push = bo->offset + r->data; - } else - if (r->flags & NOUVEAU_BO_HIGH) { - push = (bo->offset + r->data) >> 32; - } else { - push = r->data; - } - - if (r->flags & NOUVEAU_BO_OR) { - if (bo->flags & NOUVEAU_BO_VRAM) - push |= r->vor; - else - push |= r->tor; - } - - return push; -} - -/* This would be our TTM "superioctl" */ -int -nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; - int ret, i; - - if (nvpb->base.remaining == nvpb->size) - return 0; - - nouveau_fence_flush(chan); - - nvpb->size -= nvpb->base.remaining; - nvchan->dma->cur += nvpb->size; - nvchan->dma->free -= nvpb->size; - assert(nvchan->dma->cur <= nvchan->dma->max); - - nvchan->dma = &nvchan->dma_bufmgr; - nvchan->pushbuf[nvpb->nop_jump] = 0x20000000 | - (nvchan->dma->base + (nvchan->dma->cur << 2)); - - /* Validate buffers + apply relocations */ - nvchan->user_charge = 0; - for (i = 0; i < nvpb->nr_relocs; i++) { - struct nouveau_pushbuf_reloc *r = &nvpb->relocs[i]; - struct nouveau_pushbuf_bo *pbbo = r->pbbo; - struct nouveau_bo *bo = pbbo->bo; - - /* Validated, mem matches presumed, no relocation necessary */ - if (pbbo->handled & 2) { - if (!(pbbo->handled & 1)) - assert(0); - continue; - } - - /* Not yet validated, do it now */ - if (!(pbbo->handled & 1)) { - ret = nouveau_bo_validate(chan, bo, pbbo->flags); - if (ret) { - assert(0); - return ret; - } - pbbo->handled |= 1; - - if (bo->offset == nouveau_bo(bo)->offset && - bo->flags == nouveau_bo(bo)->flags) { - pbbo->handled |= 2; - continue; - } - bo->offset = nouveau_bo(bo)->offset; - bo->flags = nouveau_bo(bo)->flags; - } - - /* Apply the relocation */ - *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); - } - nvpb->nr_relocs = 0; - - /* Dereference all buffers on validate list */ - for (i = 0; i < nvpb->nr_buffers; i++) { - struct nouveau_pushbuf_bo *pbbo = &nvpb->buffers[i]; - - nouveau_bo(pbbo->bo)->pending = NULL; - nouveau_bo_del(&pbbo->bo); - } - nvpb->nr_buffers = 0; - - /* Switch back to user's ring */ - RING_SPACE_CH(chan, 1); - OUT_RING_CH(chan, 0x20000000 | ((nvpb->start << 2) + - nvchan->dma_master.base)); - nvchan->dma = &nvchan->dma_master; - - /* Fence + kickoff */ - nouveau_fence_emit(nvpb->fence); - FIRE_RING_CH(chan); - - /* Allocate space for next push buffer */ - ret = nouveau_pushbuf_space(chan, min); - assert(!ret); - - return 0; -} - -static struct nouveau_pushbuf_bo * -nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) -{ - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_pushbuf_bo *pbbo; - - if (nvbo->pending) - return nvbo->pending; - - if (nvpb->nr_buffers >= NOUVEAU_PUSHBUF_MAX_BUFFERS) - return NULL; - pbbo = nvpb->buffers + nvpb->nr_buffers++; - nvbo->pending = pbbo; - - nouveau_bo_ref(bo->device, bo->handle, &pbbo->bo); - pbbo->channel = chan; - pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; - pbbo->handled = 0; - return pbbo; -} - -int -nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, - struct nouveau_bo *bo, uint32_t data, uint32_t flags, - uint32_t vor, uint32_t tor) -{ - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); - struct nouveau_pushbuf_bo *pbbo; - struct nouveau_pushbuf_reloc *r; - - if (nvpb->nr_relocs >= NOUVEAU_PUSHBUF_MAX_RELOCS) - return -ENOMEM; - - pbbo = nouveau_pushbuf_emit_buffer(chan, bo); - if (!pbbo) - return -ENOMEM; - pbbo->flags |= (flags & NOUVEAU_BO_RDWR); - pbbo->flags &= (flags | NOUVEAU_BO_RDWR); - - r = nvpb->relocs + nvpb->nr_relocs++; - r->pbbo = pbbo; - r->ptr = ptr; - r->flags = flags; - r->data = data; - r->vor = vor; - r->tor = tor; - - if (flags & NOUVEAU_BO_DUMMY) - *(uint32_t *)ptr = 0; - else - *(uint32_t *)ptr = nouveau_pushbuf_calc_reloc(bo, r); - return 0; -} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_resource.c b/src/gallium/winsys/drm/nouveau/common/nouveau_resource.c deleted file mode 100644 index 766fd279fe..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_resource.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2007 Nouveau Project - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS 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 -#include -#include -#include "nouveau_drmif.h" -#include "nouveau_local.h" - -int -nouveau_resource_init(struct nouveau_resource **heap, - unsigned start, unsigned size) -{ - struct nouveau_resource *r; - - r = CALLOC_STRUCT(nouveau_resource); - if (!r) - return 1; - - r->start = start; - r->size = size; - *heap = r; - return 0; -} - -int -nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, - struct nouveau_resource **res) -{ - struct nouveau_resource *r; - - if (!heap || !size || !res || *res) - return 1; - - while (heap) { - if (!heap->in_use && heap->size >= size) { - r = CALLOC_STRUCT(nouveau_resource); - if (!r) - return 1; - - r->start = (heap->start + heap->size) - size; - r->size = size; - r->in_use = 1; - r->priv = priv; - - heap->size -= size; - - r->next = heap->next; - if (heap->next) - heap->next->prev = r; - r->prev = heap; - heap->next = r; - - *res = r; - return 0; - } - - heap = heap->next; - } - - return 1; -} - -void -nouveau_resource_free(struct nouveau_resource **res) -{ - struct nouveau_resource *r; - - if (!res || !*res) - return; - r = *res; - *res = NULL; - - r->in_use = 0; - - if (r->next && !r->next->in_use) { - struct nouveau_resource *new = r->next; - - new->prev = r->prev; - if (r->prev) - r->prev->next = new; - new->size += r->size; - new->start = r->start; - - free(r); - r = new; - } - - if (r->prev && !r->prev->in_use) { - r->prev->next = r->next; - if (r->next) - r->next->prev = r->prev; - r->prev->size += r->size; - FREE(r); - } - -} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c index 722694e4a4..3b2b86cd40 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c @@ -29,8 +29,9 @@ nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass, if (ret) return ret; - assert(nv->nvc->next_subchannel < 7); - BIND_RING(chan, *grobj, nv->nvc->next_subchannel++); + BEGIN_RING(chan, *grobj, 0x0000, 1); + OUT_RING (chan, (*grobj)->handle); + (*grobj)->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT; return 0; } @@ -73,14 +74,8 @@ static int nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size, struct pipe_fence_handle **fence) { - if (fence) { - struct nouveau_pushbuf *pb = nvws->channel->pushbuf; - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(pb); - struct nouveau_fence *ref = NULL; - - nouveau_fence_ref(nvpb->fence, &ref); - *fence = (struct pipe_fence_handle *)ref; - } + if (fence) + *fence = NULL; return nouveau_pushbuf_flush(nvws->channel, size); } diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c index 8e889b9f36..6f79e0800a 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c @@ -105,7 +105,7 @@ nouveau_pipe_bo_del(struct pipe_winsys *ws, struct pipe_buffer *buf) { struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); - nouveau_bo_del(&nvbuf->bo); + nouveau_bo_ref(NULL, &nvbuf->bo); FREE(nvbuf); } @@ -121,6 +121,7 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) map_flags |= NOUVEAU_BO_WR; +#if 0 if (flags & PIPE_BUFFER_USAGE_DISCARD && !(flags & PIPE_BUFFER_USAGE_CPU_READ) && nouveau_bo_busy(nvbuf->bo, map_flags)) { @@ -131,10 +132,11 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, uint32_t flags = nouveau_flags_from_usage(nv, buf->usage); if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) { - nouveau_bo_del(&nvbuf->bo); + nouveau_bo_ref(NULL, &nvbuf->bo); nvbuf->bo = rename; } } +#endif if (nouveau_bo_map(nvbuf->bo, map_flags)) return NULL; @@ -149,42 +151,26 @@ nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) nouveau_bo_unmap(nvbuf->bo); } -static INLINE struct nouveau_fence * -nouveau_pipe_fence(struct pipe_fence_handle *pfence) -{ - return (struct nouveau_fence *)pfence; -} - static void nouveau_pipe_fence_reference(struct pipe_winsys *ws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *pfence) { - nouveau_fence_ref((void *)pfence, (void *)ptr); + *ptr = pfence; } static int nouveau_pipe_fence_signalled(struct pipe_winsys *ws, struct pipe_fence_handle *pfence, unsigned flag) { - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)ws; - struct nouveau_fence *fence = nouveau_pipe_fence(pfence); - - if (nouveau_fence(fence)->signalled == 0) - nouveau_fence_flush(nvpws->nv->nvc->channel); - - return !nouveau_fence(fence)->signalled; + return 0; } static int nouveau_pipe_fence_finish(struct pipe_winsys *ws, struct pipe_fence_handle *pfence, unsigned flag) { - struct nouveau_fence *fence = nouveau_pipe_fence(pfence); - struct nouveau_fence *ref = NULL; - - nouveau_fence_ref(fence, &ref); - return nouveau_fence_wait(&ref); + return 0; } static void diff --git a/src/gallium/winsys/drm/nouveau/common/nv04_surface.c b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c index e9a8a2ac1c..b83f3475df 100644 --- a/src/gallium/winsys/drm/nouveau/common/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c @@ -354,7 +354,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NOUVEAU_ERR("Error creating m2mf object: %d\n", ret); return 1; } - BIND_RING (chan, nvc->NvM2MF, nvc->next_subchannel++); BEGIN_RING(chan, nvc->NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); OUT_RING (chan, nvc->sync_notifier->handle); @@ -366,7 +365,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); return 1; } - BIND_RING (chan, nvc->NvCtxSurf2D, nvc->next_subchannel++); BEGIN_RING(chan, nvc->NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); OUT_RING (chan, nvc->channel->vram->handle); @@ -378,7 +376,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NOUVEAU_ERR("Error creating blit object: %d\n", ret); return 1; } - BIND_RING (chan, nvc->NvImageBlit, nvc->next_subchannel++); BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); OUT_RING (chan, nvc->sync_notifier->handle); BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); @@ -392,7 +389,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NOUVEAU_ERR("Error creating rect object: %d\n", ret); return 1; } - BIND_RING (chan, nvc->NvGdiRect, nvc->next_subchannel++); BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); OUT_RING (chan, nvc->sync_notifier->handle); BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); @@ -431,8 +427,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) return 1; } - BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); - if (chipset < 0x10) { class = NV04_SCALED_IMAGE_FROM_MEMORY; } else @@ -449,8 +443,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) return 1; } - BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); - return 0; } diff --git a/src/gallium/winsys/drm/nouveau/common/nv50_surface.c b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c index c8ab7f690f..d16f3a97d5 100644 --- a/src/gallium/winsys/drm/nouveau/common/nv50_surface.c +++ b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c @@ -34,7 +34,7 @@ nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) if (surf_format < 0) return 1; - if (!nouveau_bo(bo)->tiled) { + if (!bo->tiled) { BEGIN_RING(chan, eng2d, mthd, 2); OUT_RING (chan, surf_format); OUT_RING (chan, 1); @@ -166,7 +166,6 @@ nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) return ret; nvc->Nv2D = eng2d; - BIND_RING (chan, eng2d, nvc->next_subchannel++); BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4); OUT_RING (chan, nvc->sync_notifier->handle); OUT_RING (chan, chan->vram->handle); diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/winsys/drm/nouveau/dri/Makefile index e129e42e97..3f3553b61d 100644 --- a/src/gallium/winsys/drm/nouveau/dri/Makefile +++ b/src/gallium/winsys/drm/nouveau/dri/Makefile @@ -26,6 +26,9 @@ C_SOURCES = \ ASM_SOURCES = +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_dri.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h index 8257790d47..64cf326411 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h @@ -5,8 +5,6 @@ #include #include #include "../common/nouveau_context.h" -#include "../common/nouveau_drmif.h" -#include "../common/nouveau_dma.h" struct nouveau_framebuffer { struct st_framebuffer *stfb; diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c index 1d7c92376f..964a9028aa 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c @@ -12,7 +12,7 @@ #include "nouveau_screen_dri.h" #include "nouveau_swapbuffers.h" -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 12 #error nouveau_drm.h version does not match expected version #endif -- cgit v1.2.3 From 79bf0bdc7ffe97ec128e5dd143c4ed54648aae42 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 4 Feb 2009 20:59:49 +1000 Subject: nouveau: get things building/running again after pipe_surface.buffer removal Don't look at nouveau_winsys_pipe.h... I promise it's temporary! --- .../winsys/drm/nouveau/common/nouveau_context.c | 60 +++++++++++----------- .../winsys/drm/nouveau/common/nouveau_context.h | 1 + .../winsys/drm/nouveau/common/nouveau_winsys.c | 5 +- .../drm/nouveau/common/nouveau_winsys_pipe.c | 38 ++++++++++++-- .../drm/nouveau/common/nouveau_winsys_pipe.h | 14 ++++- .../winsys/drm/nouveau/common/nv04_surface.c | 32 ++++++------ .../winsys/drm/nouveau/common/nv50_surface.c | 2 +- 7 files changed, 98 insertions(+), 54 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c index de4a90e25f..70f005b888 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c @@ -113,35 +113,6 @@ nouveau_context_init(struct nouveau_screen *nv_screen, nvdev->lock = sarea_lock; } - /*XXX: Hack up a fake region and buffer object for front buffer. - * This will go away with TTM, replaced with a simple reference - * of the front buffer handle passed to us by the DDX. - */ - { - struct pipe_surface *fb_surf; - struct nouveau_pipe_buffer *fb_buf; - - fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); - - nouveau_bo_fake(dev, nv_screen->front_offset, NOUVEAU_BO_VRAM, - nv_screen->front_pitch*nv_screen->front_height, - NULL, &fb_buf->bo); - - fb_surf = calloc(1, sizeof(struct pipe_surface)); - if (nv_screen->front_cpp == 2) - fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; - else - fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; - pf_get_block(fb_surf->format, &fb_surf->block); - fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; - fb_surf->height = nv_screen->front_height; - fb_surf->stride = fb_surf->width * fb_surf->block.size; - fb_surf->refcount = 1; - fb_surf->buffer = &fb_buf->base; - - nv->frontbuffer = fb_surf; - } - /* Attempt to share a single channel between multiple contexts from * a single process. */ @@ -229,8 +200,37 @@ nouveau_context_init(struct nouveau_screen *nv_screen, } } - pipe->priv = nv; + { + struct pipe_texture *fb_tex; + struct pipe_surface *fb_surf; + struct nouveau_pipe_buffer *fb_buf; + enum pipe_format format; + + fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); + fb_buf->base.refcount = 1; + fb_buf->base.usage = PIPE_BUFFER_USAGE_PIXEL; + + nouveau_bo_fake(dev, nv_screen->front_offset, NOUVEAU_BO_VRAM, + nv_screen->front_pitch*nv_screen->front_height, + NULL, &fb_buf->bo); + + if (nv_screen->front_cpp == 4) + format = PIPE_FORMAT_A8R8G8B8_UNORM; + else + format = PIPE_FORMAT_R5G6B5_UNORM; + + fb_surf = nouveau_surface_buffer_ref(nv, &fb_buf->base, format, + nv_screen->front_pitch / + nv_screen->front_cpp, + nv_screen->front_height, + nv_screen->front_pitch, + &fb_tex); + nv->frontbuffer = fb_surf; + nv->frontbuffer_texture = fb_tex; + } + + pipe->priv = nv; return 0; } diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h index d7199db3de..6f6bdafe6b 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h @@ -43,6 +43,7 @@ struct nouveau_context { int locked; struct nouveau_screen *nv_screen; struct pipe_surface *frontbuffer; + struct pipe_texture *frontbuffer_texture; struct { int hw_vertex_buffer; diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c index 3b2b86cd40..527c09cf6b 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c @@ -65,8 +65,9 @@ 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) { - return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, - nouveau_buffer(buf)->bo, + struct nouveau_bo *bo = ((struct nouveau_pipe_buffer *)buf)->bo; + + return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, bo, data, flags, vor, tor); } diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c index 6f79e0800a..c17d8a05e6 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c @@ -103,7 +103,7 @@ nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) static void nouveau_pipe_bo_del(struct pipe_winsys *ws, struct pipe_buffer *buf) { - struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + struct nouveau_pipe_buffer *nvbuf = (void *)buf; nouveau_bo_ref(NULL, &nvbuf->bo); FREE(nvbuf); @@ -113,7 +113,7 @@ static void * nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags) { - struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + struct nouveau_pipe_buffer *nvbuf = (void *)buf; uint32_t map_flags = 0; if (flags & PIPE_BUFFER_USAGE_CPU_READ) @@ -146,7 +146,7 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, static void nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) { - struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + struct nouveau_pipe_buffer *nvbuf = (void *)buf; nouveau_bo_unmap(nvbuf->bo); } @@ -173,6 +173,38 @@ nouveau_pipe_fence_finish(struct pipe_winsys *ws, return 0; } +struct pipe_surface * +nouveau_surface_buffer_ref(struct nouveau_context *nv, struct pipe_buffer *pb, + enum pipe_format format, int w, int h, + unsigned pitch, struct pipe_texture **ppt) +{ + struct pipe_screen *pscreen = nv->nvc->pscreen; + struct pipe_texture tmpl, *pt; + struct pipe_surface *ps; + + memset(&tmpl, 0, sizeof(tmpl)); + tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + NOUVEAU_TEXTURE_USAGE_LINEAR; + tmpl.target = PIPE_TEXTURE_2D; + tmpl.width[0] = w; + tmpl.height[0] = h; + tmpl.depth[0] = 1; + tmpl.format = format; + pf_get_block(tmpl.format, &tmpl.block); + tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w); + tmpl.nblocksy[0] = pf_get_nblocksy(&tmpl.block, h); + + pt = pscreen->texture_blanket(pscreen, &tmpl, &pitch, pb); + if (!pt) + return NULL; + + ps = pscreen->get_tex_surface(pscreen, pt, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + + *ppt = pt; + return ps; +} + static void nouveau_destroy(struct pipe_winsys *pws) { diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h index d97ffdf337..b041a77e38 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h @@ -10,10 +10,15 @@ struct nouveau_pipe_buffer { struct nouveau_bo *bo; }; +/* This is so horrible I should be shot - I promise I'll fix it properly + * tomorrow. Just to make the winsys build again however... The TG guys + * don't like to make life easy :) + */ static inline struct nouveau_pipe_buffer * -nouveau_buffer(struct pipe_buffer *buf) +nouveau_buffer(struct pipe_surface *ps) { - return (struct nouveau_pipe_buffer *)buf; + return *(struct nouveau_pipe_buffer **) + ((void *)ps->texture + sizeof(struct pipe_texture)); } struct nouveau_pipe_winsys { @@ -36,4 +41,9 @@ extern void nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, void *context_private); +struct pipe_surface * +nouveau_surface_buffer_ref(struct nouveau_context *nv, struct pipe_buffer *pb, + enum pipe_format format, int w, int h, + unsigned pitch, struct pipe_texture **ppt); + #endif diff --git a/src/gallium/winsys/drm/nouveau/common/nv04_surface.c b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c index b83f3475df..214c843782 100644 --- a/src/gallium/winsys/drm/nouveau/common/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c @@ -132,7 +132,7 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, assert(!(w & (w - 1)) && !(h & (h - 1))); BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(dst)->bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); OUT_RING (chan, nv04_surface_format(dst->format) | @@ -140,7 +140,7 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(src)->bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); OUT_RING (chan, nv->nvc->NvSwzSurf->handle); @@ -148,7 +148,7 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, for (cy = 0; cy < h; cy += sub_h) { for (cx = 0; cx < w; cx += sub_w) { BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_OFFSET, 1); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, + OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst->offset + nv04_swizzle_bits(cx, cy) * dst->block.size, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); @@ -168,7 +168,7 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, OUT_RING (chan, src->stride | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, + OUT_RELOCl(chan, nouveau_buffer(src)->bo, src->offset + cy * src->stride + cx * src->block.size, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); OUT_RING (chan, 0); @@ -193,9 +193,9 @@ nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, BEGIN_RING(chan, nv->nvc->NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src_offset, + OUT_RELOCl(chan, nouveau_buffer(src)->bo, src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst_offset, + OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); OUT_RING (chan, src->stride); OUT_RING (chan, dst->stride); @@ -253,9 +253,9 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, if ((src->offset & 63) || (dst->offset & 63)) { BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(src)->bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(dst)->bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); nv->surface_copy = nv04_surface_copy_m2mf; @@ -273,18 +273,18 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(src)->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(dst)->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); OUT_RING (chan, format); OUT_RING (chan, (dst->stride << 16) | src->stride); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, + OUT_RELOCl(chan, nouveau_buffer(src)->bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); return 0; @@ -317,16 +317,16 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, } BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(dst)->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + OUT_RELOCo(chan, nouveau_buffer(dst)->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); OUT_RING (chan, cs2d_format); OUT_RING (chan, (dst->stride << 16) | dst->stride); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); diff --git a/src/gallium/winsys/drm/nouveau/common/nv50_surface.c b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c index d16f3a97d5..540240cd23 100644 --- a/src/gallium/winsys/drm/nouveau/common/nv50_surface.c +++ b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c @@ -26,7 +26,7 @@ nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) { struct nouveau_channel *chan = nv->nvc->channel; struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->bo; + struct nouveau_bo *bo = nouveau_buffer(surf)->bo; int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); -- cgit v1.2.3 From ae8a7544d1ab96240f646ea91fb149227067a2db Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 5 Feb 2009 13:17:12 +1000 Subject: nouveau: support getting "native" bo from winsys --- src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c index 527c09cf6b..ef7e8aac54 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c @@ -81,6 +81,12 @@ nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size, return nouveau_pushbuf_flush(nvws->channel, size); } +static struct nouveau_bo * +nouveau_pipe_get_bo(struct pipe_buffer *pb) +{ + return ((struct nouveau_pipe_buffer *)pb)->bo; +} + struct pipe_context * nouveau_pipe_create(struct nouveau_context *nv) { @@ -151,6 +157,8 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->surface_copy = nouveau_pipe_surface_copy; nvws->surface_fill = nouveau_pipe_surface_fill; + nvws->get_bo = nouveau_pipe_get_bo; + ws = nouveau_create_pipe_winsys(nv); if (!nvc->pscreen) -- cgit v1.2.3 From 13393736dbab1087589f8dd788bc412d16b431d1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 5 Feb 2009 14:04:45 +1000 Subject: nv50: move 2d blit/fill code into pipe driver --- src/gallium/winsys/drm/nouveau/common/Makefile | 3 +- .../winsys/drm/nouveau/common/nouveau_context.c | 5 +- .../winsys/drm/nouveau/common/nouveau_context.h | 3 - .../winsys/drm/nouveau/common/nv50_surface.c | 193 --------------------- .../winsys/drm/nouveau/dri/nouveau_swapbuffers.c | 42 +++-- 5 files changed, 33 insertions(+), 213 deletions(-) delete mode 100644 src/gallium/winsys/drm/nouveau/common/nv50_surface.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/common/Makefile b/src/gallium/winsys/drm/nouveau/common/Makefile index 9bc5c42585..4cd315e289 100644 --- a/src/gallium/winsys/drm/nouveau/common/Makefile +++ b/src/gallium/winsys/drm/nouveau/common/Makefile @@ -10,8 +10,7 @@ C_SOURCES = \ nouveau_winsys.c \ nouveau_winsys_pipe.c \ nouveau_winsys_softpipe.c \ - nv04_surface.c \ - nv50_surface.c + nv04_surface.c include ./Makefile.template diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c index 70f005b888..7be3e94d49 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c @@ -56,7 +56,7 @@ nouveau_channel_context_create(struct nouveau_device *dev) case 0x50: case 0x80: case 0x90: - ret = nouveau_surface_channel_create_nv50(nvc); + /* pipe driver does this */ break; default: ret = nouveau_surface_channel_create_nv04(nvc); @@ -168,8 +168,7 @@ nouveau_context_init(struct nouveau_screen *nv_screen, case 0x50: case 0x80: case 0x90: - if (nouveau_surface_init_nv50(nv)) - return 1; + /* pipe driver does this */ break; default: if (nouveau_surface_init_nv04(nv)) diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h index 6f6bdafe6b..66883e85fe 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h @@ -78,10 +78,7 @@ extern void UNLOCK_HARDWARE(struct nouveau_context *); extern int nouveau_surface_channel_create_nv04(struct nouveau_channel_context *); -extern int -nouveau_surface_channel_create_nv50(struct nouveau_channel_context *); extern int nouveau_surface_init_nv04(struct nouveau_context *); -extern int nouveau_surface_init_nv50(struct nouveau_context *); extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int); extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *); diff --git a/src/gallium/winsys/drm/nouveau/common/nv50_surface.c b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c deleted file mode 100644 index 540240cd23..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nv50_surface.c +++ /dev/null @@ -1,193 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_format.h" - -#include "nouveau_context.h" - -static INLINE int -nv50_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return NV50_2D_DST_FORMAT_32BPP; - case PIPE_FORMAT_X8R8G8B8_UNORM: - return NV50_2D_DST_FORMAT_24BPP; - case PIPE_FORMAT_R5G6B5_UNORM: - return NV50_2D_DST_FORMAT_16BPP; - case PIPE_FORMAT_A8_UNORM: - return NV50_2D_DST_FORMAT_8BPP; - default: - return -1; - } -} - -static int -nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - struct nouveau_bo *bo = nouveau_buffer(surf)->bo; - int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; - int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); - - surf_format = nv50_format(surf->format); - if (surf_format < 0) - return 1; - - if (!bo->tiled) { - BEGIN_RING(chan, eng2d, mthd, 2); - OUT_RING (chan, surf_format); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, mthd + 0x14, 5); - OUT_RING (chan, surf->stride); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - OUT_RELOCh(chan, bo, surf->offset, flags); - OUT_RELOCl(chan, bo, surf->offset, flags); - } else { - BEGIN_RING(chan, eng2d, mthd, 5); - OUT_RING (chan, surf_format); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, mthd + 0x18, 4); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - OUT_RELOCh(chan, bo, surf->offset, flags); - OUT_RELOCl(chan, bo, surf->offset, flags); - } - -#if 0 - if (dst) { - BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - } -#endif - - return 0; -} - -static int -nv50_surface_copy_prep(struct nouveau_context *nv, - struct pipe_surface *dst, struct pipe_surface *src) -{ - int ret; - - assert(src->format == dst->format); - - ret = nv50_surface_set(nv, dst, 1); - if (ret) - return ret; - - ret = nv50_surface_set(nv, src, 0); - if (ret) - return ret; - - return 0; -} - -static void -nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - - BEGIN_RING(chan, eng2d, 0x088c, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4); - OUT_RING (chan, dx); - OUT_RING (chan, dy); - OUT_RING (chan, w); - OUT_RING (chan, h); - BEGIN_RING(chan, eng2d, 0x08c0, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, 0x08d0, 4); - OUT_RING (chan, 0); - OUT_RING (chan, sx); - OUT_RING (chan, 0); - OUT_RING (chan, sy); -} - -static void -nv50_surface_copy_done(struct nouveau_context *nv) -{ - FIRE_RING(nv->nvc->channel); -} - -static int -nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, - unsigned dx, unsigned dy, unsigned w, unsigned h, - unsigned value) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - int rect_format, ret; - - rect_format = nv50_format(dst->format); - if (rect_format < 0) - return 1; - - ret = nv50_surface_set(nv, dst, 1); - if (ret) - return ret; - - BEGIN_RING(chan, eng2d, 0x0580, 3); - OUT_RING (chan, 4); - OUT_RING (chan, rect_format); - OUT_RING (chan, value); - - BEGIN_RING(chan, eng2d, NV50_2D_RECT_X1, 4); - OUT_RING (chan, dx); - OUT_RING (chan, dy); - OUT_RING (chan, dx + w); - OUT_RING (chan, dy + h); - - FIRE_RING(chan); - return 0; -} - -int -nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) -{ - struct nouveau_channel *chan = nvc->channel; - struct nouveau_grobj *eng2d = NULL; - int ret; - - ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d); - if (ret) - return ret; - nvc->Nv2D = eng2d; - - BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4); - OUT_RING (chan, nvc->sync_notifier->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1); - OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); - BEGIN_RING(chan, eng2d, 0x0290, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, 0x0888, 1); - OUT_RING (chan, 1); - - return 0; -} - -int -nouveau_surface_init_nv50(struct nouveau_context *nv) -{ - nv->surface_copy_prep = nv50_surface_copy_prep; - nv->surface_copy = nv50_surface_copy; - nv->surface_copy_done = nv50_surface_copy_done; - nv->surface_fill = nv50_surface_fill; - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c index e111eec932..450c981ca4 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c @@ -28,18 +28,36 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, pbox = dPriv->pClipRects; nbox = dPriv->numClipRects; - nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf); - 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; - - nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h); + if (nv->base.surface_copy_prep) { + nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf); + 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; + + nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h); + } + } else { + struct pipe_context *pipe = nv->base.nvc->pctx[nv->base.pctx_id]; + + 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, FALSE, nv->base.frontbuffer, + dx, dy, surf, sx, sy, w, h); + } } FIRE_RING(nv->base.nvc->channel); -- cgit v1.2.3 From ff8dff017e537c6db4c86aad43e92b768cb187e4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 5 Feb 2009 18:19:32 +1000 Subject: nv04-nv40: move 2d blit/fill code into pipe driver --- src/gallium/winsys/drm/nouveau/common/Makefile | 4 +- .../winsys/drm/nouveau/common/nouveau_context.c | 49 +-- .../winsys/drm/nouveau/common/nouveau_context.h | 33 +- .../winsys/drm/nouveau/common/nouveau_winsys.c | 32 +- .../drm/nouveau/common/nouveau_winsys_pipe.c | 6 +- .../drm/nouveau/common/nouveau_winsys_pipe.h | 11 +- .../winsys/drm/nouveau/common/nv04_surface.c | 458 --------------------- .../winsys/drm/nouveau/dri/nouveau_swapbuffers.c | 43 +- 8 files changed, 24 insertions(+), 612 deletions(-) delete mode 100644 src/gallium/winsys/drm/nouveau/common/nv04_surface.c (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/nouveau/common/Makefile b/src/gallium/winsys/drm/nouveau/common/Makefile index 4cd315e289..c6dd6dd7f9 100644 --- a/src/gallium/winsys/drm/nouveau/common/Makefile +++ b/src/gallium/winsys/drm/nouveau/common/Makefile @@ -9,9 +9,7 @@ C_SOURCES = \ nouveau_screen.c \ nouveau_winsys.c \ nouveau_winsys_pipe.c \ - nouveau_winsys_softpipe.c \ - nv04_surface.c - + nouveau_winsys_softpipe.c include ./Makefile.template diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c index 7be3e94d49..d6ae0827cd 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c @@ -11,16 +11,6 @@ static void nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) { - nouveau_grobj_free(&nvc->NvCtxSurf2D); - nouveau_grobj_free(&nvc->NvImageBlit); - nouveau_grobj_free(&nvc->NvGdiRect); - nouveau_grobj_free(&nvc->NvM2MF); - nouveau_grobj_free(&nvc->Nv2D); - nouveau_grobj_free(&nvc->NvSwzSurf); - nouveau_grobj_free(&nvc->NvSIFM); - - nouveau_notifier_free(&nvc->sync_notifier); - nouveau_channel_free(&nvc->channel); FREE(nvc); @@ -43,32 +33,7 @@ nouveau_channel_context_create(struct nouveau_device *dev) return NULL; } - nvc->next_handle = 0x88000000; - - if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, - &nvc->sync_notifier))) { - NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); - nouveau_channel_context_destroy(nvc); - return NULL; - } - - switch (dev->chipset & 0xf0) { - case 0x50: - case 0x80: - case 0x90: - /* pipe driver does this */ - break; - default: - ret = nouveau_surface_channel_create_nv04(nvc); - break; - } - - if (ret) { - NOUVEAU_ERR("Error initialising surface objects: %d\n", ret); - nouveau_channel_context_destroy(nvc); - return NULL; - } - + nvc->next_handle = 0x77000000; return nvc; } @@ -164,18 +129,6 @@ nouveau_context_init(struct nouveau_screen *nv_screen, } /* Create pipe */ - switch (dev->chipset & 0xf0) { - case 0x50: - case 0x80: - case 0x90: - /* pipe driver does this */ - break; - default: - if (nouveau_surface_init_nv04(nv)) - return 1; - break; - } - if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { struct pipe_screen *pscreen; diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h index 66883e85fe..02d2745680 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h @@ -21,22 +21,7 @@ struct nouveau_channel_context { struct pipe_context **pctx; struct nouveau_channel *channel; - - struct nouveau_notifier *sync_notifier; - - /* Common */ - struct nouveau_grobj *NvM2MF; - /* NV04-NV40 */ - struct nouveau_grobj *NvCtxSurf2D; - struct nouveau_grobj *NvSwzSurf; - struct nouveau_grobj *NvImageBlit; - struct nouveau_grobj *NvGdiRect; - struct nouveau_grobj *NvSIFM; - /* G80 */ - struct nouveau_grobj *Nv2D; - - uint32_t next_handle; - uint32_t next_sequence; + unsigned next_handle; }; struct nouveau_context { @@ -53,18 +38,6 @@ struct nouveau_context { /* Hardware context */ struct nouveau_channel_context *nvc; int pctx_id; - - /* pipe_surface accel */ - struct pipe_surface *surf_src, *surf_dst; - unsigned surf_src_offset, surf_dst_offset; - int (*surface_copy_prep)(struct nouveau_context *, - struct pipe_surface *dst, - struct pipe_surface *src); - void (*surface_copy)(struct nouveau_context *, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h); - void (*surface_copy_done)(struct nouveau_context *); - int (*surface_fill)(struct nouveau_context *, struct pipe_surface *, - unsigned, unsigned, unsigned, unsigned, unsigned); }; extern int nouveau_context_init(struct nouveau_screen *nv_screen, @@ -76,10 +49,6 @@ extern void nouveau_context_cleanup(struct nouveau_context *nv); extern void LOCK_HARDWARE(struct nouveau_context *); extern void UNLOCK_HARDWARE(struct nouveau_context *); -extern int -nouveau_surface_channel_create_nv04(struct nouveau_channel_context *); -extern int nouveau_surface_init_nv04(struct nouveau_context *); - extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int); extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *); diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c index ef7e8aac54..b6199f8e6d 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c @@ -35,37 +35,12 @@ nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass, return 0; } -static int -nouveau_pipe_surface_copy(struct nouveau_winsys *nvws, struct pipe_surface *dst, - unsigned dx, unsigned dy, struct pipe_surface *src, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_context *nv = nvws->nv; - - if (nv->surface_copy_prep(nv, dst, src)) - return 1; - nv->surface_copy(nv, dx, dy, sx, sy, w, h); - nv->surface_copy_done(nv); - - return 0; -} - -static int -nouveau_pipe_surface_fill(struct nouveau_winsys *nvws, struct pipe_surface *dst, - unsigned dx, unsigned dy, unsigned w, unsigned h, - unsigned value) -{ - if (nvws->nv->surface_fill(nvws->nv, dst, dx, dy, w, h, value)) - return 1; - 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 = ((struct nouveau_pipe_buffer *)buf)->bo; + struct nouveau_bo *bo = nouveau_pipe_buffer(buf)->bo; return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, bo, data, flags, vor, tor); @@ -84,7 +59,7 @@ nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size, static struct nouveau_bo * nouveau_pipe_get_bo(struct pipe_buffer *pb) { - return ((struct nouveau_pipe_buffer *)pb)->bo; + return nouveau_pipe_buffer(pb)->bo; } struct pipe_context * @@ -154,9 +129,6 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->notifier_retval = nouveau_notifier_return_val; nvws->notifier_wait = nouveau_notifier_wait_status; - nvws->surface_copy = nouveau_pipe_surface_copy; - nvws->surface_fill = nouveau_pipe_surface_fill; - nvws->get_bo = nouveau_pipe_get_bo; ws = nouveau_create_pipe_winsys(nv); diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c index c17d8a05e6..881df98556 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c @@ -103,7 +103,7 @@ nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) static void nouveau_pipe_bo_del(struct pipe_winsys *ws, struct pipe_buffer *buf) { - struct nouveau_pipe_buffer *nvbuf = (void *)buf; + struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf); nouveau_bo_ref(NULL, &nvbuf->bo); FREE(nvbuf); @@ -113,7 +113,7 @@ static void * nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags) { - struct nouveau_pipe_buffer *nvbuf = (void *)buf; + struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf); uint32_t map_flags = 0; if (flags & PIPE_BUFFER_USAGE_CPU_READ) @@ -146,7 +146,7 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, static void nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) { - struct nouveau_pipe_buffer *nvbuf = (void *)buf; + struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf); nouveau_bo_unmap(nvbuf->bo); } diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h index b041a77e38..1eb8043478 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h @@ -10,15 +10,10 @@ struct nouveau_pipe_buffer { struct nouveau_bo *bo; }; -/* This is so horrible I should be shot - I promise I'll fix it properly - * tomorrow. Just to make the winsys build again however... The TG guys - * don't like to make life easy :) - */ -static inline struct nouveau_pipe_buffer * -nouveau_buffer(struct pipe_surface *ps) +static INLINE struct nouveau_pipe_buffer * +nouveau_pipe_buffer(struct pipe_buffer *buf) { - return *(struct nouveau_pipe_buffer **) - ((void *)ps->texture + sizeof(struct pipe_texture)); + return (struct nouveau_pipe_buffer *)buf; } struct nouveau_pipe_winsys { diff --git a/src/gallium/winsys/drm/nouveau/common/nv04_surface.c b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c deleted file mode 100644 index 214c843782..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nv04_surface.c +++ /dev/null @@ -1,458 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_format.h" - -#include "nouveau_context.h" - -static INLINE int log2i(int i) -{ - int r = 0; - - if (i & 0xffff0000) { - i >>= 16; - r += 16; - } - if (i & 0x0000ff00) { - i >>= 8; - r += 8; - } - if (i & 0x000000f0) { - i >>= 4; - r += 4; - } - if (i & 0x0000000c) { - i >>= 2; - r += 2; - } - if (i & 0x00000002) { - r += 1; - } - return r; -} - -static INLINE int -nv04_surface_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; - case PIPE_FORMAT_R16_SNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_A8R8G8B8_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8; - case PIPE_FORMAT_Z24S8_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; - default: - return -1; - } -} - -static INLINE int -nv04_rect_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; - case PIPE_FORMAT_R5G6B5_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; - default: - return -1; - } -} - -static INLINE int -nv04_scaled_image_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A1R5G5B5_UNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5; - case PIPE_FORMAT_A8R8G8B8_UNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; - case PIPE_FORMAT_X8R8G8B8_UNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8; - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_R16_SNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; - default: - return -1; - } -} - -static INLINE unsigned -nv04_swizzle_bits(unsigned x, unsigned y) -{ - unsigned u = (x & 0x001) << 0 | - (x & 0x002) << 1 | - (x & 0x004) << 2 | - (x & 0x008) << 3 | - (x & 0x010) << 4 | - (x & 0x020) << 5 | - (x & 0x040) << 6 | - (x & 0x080) << 7 | - (x & 0x100) << 8 | - (x & 0x200) << 9 | - (x & 0x400) << 10 | - (x & 0x800) << 11; - - unsigned v = (y & 0x001) << 1 | - (y & 0x002) << 2 | - (y & 0x004) << 3 | - (y & 0x008) << 4 | - (y & 0x010) << 5 | - (y & 0x020) << 6 | - (y & 0x040) << 7 | - (y & 0x080) << 8 | - (y & 0x100) << 9 | - (y & 0x200) << 10 | - (y & 0x400) << 11 | - (y & 0x800) << 12; - return v | u; -} - -static void -nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct pipe_surface *dst = nv->surf_dst; - struct pipe_surface *src = nv->surf_src; - - const unsigned max_w = 1024; - const unsigned max_h = 1024; - const unsigned sub_w = w > max_w ? max_w : w; - const unsigned sub_h = h > max_h ? max_h : h; - unsigned cx = 0; - unsigned cy = 0; - - /* POT or GTFO */ - assert(!(w & (w - 1)) && !(h & (h - 1))); - - BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); - OUT_RELOCo(chan, nouveau_buffer(dst)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); - OUT_RING (chan, nv04_surface_format(dst->format) | - log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT | - log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); - - BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); - OUT_RELOCo(chan, nouveau_buffer(src)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); - OUT_RING (chan, nv->nvc->NvSwzSurf->handle); - - for (cy = 0; cy < h; cy += sub_h) { - for (cx = 0; cx < w; cx += sub_w) { - BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_OFFSET, 1); - OUT_RELOCl(chan, nouveau_buffer(dst)->bo, - dst->offset + nv04_swizzle_bits(cx, cy) * dst->block.size, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); - OUT_RING (chan, nv04_scaled_image_format(src->format)); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); - OUT_RING (chan, 0); - OUT_RING (chan, sub_h << 16 | sub_w); - OUT_RING (chan, 0); - OUT_RING (chan, sub_h << 16 | sub_w); - OUT_RING (chan, 1 << 20); - OUT_RING (chan, 1 << 20); - - BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); - OUT_RING (chan, sub_h << 16 | sub_w); - OUT_RING (chan, src->stride | - NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | - NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); - OUT_RELOCl(chan, nouveau_buffer(src)->bo, - src->offset + cy * src->stride + cx * src->block.size, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, 0); - } - } -} - -static void -nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct pipe_surface *dst = nv->surf_dst; - struct pipe_surface *src = nv->surf_src; - unsigned dst_offset, src_offset; - - dst_offset = dst->offset + (dy * dst->stride) + (dx * dst->block.size); - src_offset = src->offset + (sy * src->stride) + (sx * src->block.size); - - while (h) { - int count = (h > 2047) ? 2047 : h; - - BEGIN_RING(chan, nv->nvc->NvM2MF, - NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RELOCl(chan, nouveau_buffer(src)->bo, src_offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst_offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RING (chan, src->stride); - OUT_RING (chan, dst->stride); - OUT_RING (chan, w * src->block.size); - OUT_RING (chan, count); - OUT_RING (chan, 0x0101); - OUT_RING (chan, 0); - - h -= count; - src_offset += src->stride * count; - dst_offset += dst->stride * count; - } -} - -static void -nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, - unsigned sx, unsigned sy, unsigned w, unsigned h) -{ - struct nouveau_channel *chan = nv->nvc->channel; - - BEGIN_RING(chan, nv->nvc->NvImageBlit, 0x0300, 3); - OUT_RING (chan, (sy << 16) | sx); - OUT_RING (chan, (dy << 16) | dx); - OUT_RING (chan, ( h << 16) | w); -} - -static int -nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, - struct pipe_surface *src) -{ - struct nouveau_channel *chan = nv->nvc->channel; - int format; - - if (src->format != dst->format) - return 1; - - /* Setup transfer to swizzle the texture to vram if needed */ - /* FIXME/TODO: check proper limits of this operation */ - if (src->texture && dst->texture) { - unsigned int src_linear = src->texture->tex_usage & - NOUVEAU_TEXTURE_USAGE_LINEAR; - unsigned int dst_linear = dst->texture->tex_usage & - NOUVEAU_TEXTURE_USAGE_LINEAR; - if (src_linear ^ dst_linear) { - nv->surface_copy = nv04_surface_copy_swizzle; - nv->surf_dst = dst; - nv->surf_src = src; - return 0; - } - } - - /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback - * to NV_MEMORY_TO_MEMORY_FORMAT in this case. - */ - if ((src->offset & 63) || (dst->offset & 63)) { - BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF, - NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); - OUT_RELOCo(chan, nouveau_buffer(src)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst)->bo, - NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - nv->surface_copy = nv04_surface_copy_m2mf; - nv->surf_dst = dst; - nv->surf_src = src; - return 0; - - } - - if ((format = nv04_surface_format(dst->format)) < 0) { - NOUVEAU_ERR("Bad surface format 0x%x\n", dst->format); - return 1; - } - nv->surface_copy = nv04_surface_copy_blit; - - BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, - NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, nouveau_buffer(src)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, - NV04_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (chan, format); - OUT_RING (chan, (dst->stride << 16) | src->stride); - OUT_RELOCl(chan, nouveau_buffer(src)->bo, src->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - return 0; -} - -static void -nv04_surface_copy_done(struct nouveau_context *nv) -{ - FIRE_RING(nv->nvc->channel); -} - -static int -nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, - unsigned dx, unsigned dy, unsigned w, unsigned h, - unsigned value) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *surf2d = nv->nvc->NvCtxSurf2D; - struct nouveau_grobj *rect = nv->nvc->NvGdiRect; - int cs2d_format, gdirect_format; - - if ((cs2d_format = nv04_surface_format(dst->format)) < 0) { - NOUVEAU_ERR("Bad format = %d\n", dst->format); - return 1; - } - - if ((gdirect_format = nv04_rect_format(dst->format)) < 0) { - NOUVEAU_ERR("Bad format = %d\n", dst->format); - return 1; - } - - BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, nouveau_buffer(dst)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCo(chan, nouveau_buffer(dst)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (chan, cs2d_format); - OUT_RING (chan, (dst->stride << 16) | dst->stride); - OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, nouveau_buffer(dst)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); - OUT_RING (chan, gdirect_format); - BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); - OUT_RING (chan, value); - BEGIN_RING(chan, rect, - NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); - OUT_RING (chan, (dx << 16) | dy); - OUT_RING (chan, ( w << 16) | h); - - FIRE_RING(chan); - return 0; -} - -int -nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) -{ - struct nouveau_channel *chan = nvc->channel; - unsigned chipset = nvc->channel->device->chipset, class; - int ret; - - if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, 0x39, - &nvc->NvM2MF))) { - NOUVEAU_ERR("Error creating m2mf object: %d\n", ret); - return 1; - } - BEGIN_RING(chan, nvc->NvM2MF, - NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - - class = chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : - NV10_CONTEXT_SURFACES_2D; - if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvCtxSurf2D))) { - NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); - return 1; - } - BEGIN_RING(chan, nvc->NvCtxSurf2D, - NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RING (chan, nvc->channel->vram->handle); - OUT_RING (chan, nvc->channel->vram->handle); - - class = chipset < 0x10 ? NV04_IMAGE_BLIT : NV12_IMAGE_BLIT; - if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvImageBlit))) { - NOUVEAU_ERR("Error creating blit object: %d\n", ret); - return 1; - } - BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); - OUT_RING (chan, nvc->NvCtxSurf2D->handle); - BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); - OUT_RING (chan, NV04_IMAGE_BLIT_OPERATION_SRCCOPY); - - class = NV04_GDI_RECTANGLE_TEXT; - if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvGdiRect))) { - NOUVEAU_ERR("Error creating rect object: %d\n", ret); - return 1; - } - BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); - OUT_RING (chan, nvc->NvCtxSurf2D->handle); - BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); - OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); - BEGIN_RING(chan, nvc->NvGdiRect, - NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); - OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); - - switch (chipset & 0xf0) { - case 0x00: - case 0x10: - class = NV04_SWIZZLED_SURFACE; - break; - case 0x20: - class = NV20_SWIZZLED_SURFACE; - break; - case 0x30: - class = NV30_SWIZZLED_SURFACE; - break; - case 0x40: - case 0x60: - class = NV40_SWIZZLED_SURFACE; - break; - default: - /* Famous last words: this really can't happen.. */ - assert(0); - break; - } - - ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvSwzSurf); - if (ret) { - NOUVEAU_ERR("Error creating swizzled surface: %d\n", ret); - return 1; - } - - if (chipset < 0x10) { - class = NV04_SCALED_IMAGE_FROM_MEMORY; - } else - if (chipset < 0x40) { - class = NV10_SCALED_IMAGE_FROM_MEMORY; - } else { - class = NV40_SCALED_IMAGE_FROM_MEMORY; - } - - ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, - &nvc->NvSIFM); - if (ret) { - NOUVEAU_ERR("Error creating scaled image object: %d\n", ret); - return 1; - } - - return 0; -} - -int -nouveau_surface_init_nv04(struct nouveau_context *nv) -{ - nv->surface_copy_prep = nv04_surface_copy_prep; - nv->surface_copy = nv04_surface_copy_blit; - nv->surface_copy_done = nv04_surface_copy_done; - nv->surface_fill = nv04_surface_fill; - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c index 450c981ca4..58cb6f7265 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c @@ -17,6 +17,7 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, const drm_clip_rect_t *rect) { struct nouveau_context_dri *nv = dPriv->driContextPriv->driverPrivate; + struct pipe_context *pipe = nv->base.nvc->pctx[nv->base.pctx_id]; drm_clip_rect_t *pbox; int nbox, i; @@ -28,36 +29,18 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, pbox = dPriv->pClipRects; nbox = dPriv->numClipRects; - if (nv->base.surface_copy_prep) { - nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf); - 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; - - nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h); - } - } else { - struct pipe_context *pipe = nv->base.nvc->pctx[nv->base.pctx_id]; - - 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, FALSE, nv->base.frontbuffer, - dx, dy, surf, sx, sy, w, h); - } + 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, FALSE, nv->base.frontbuffer, + dx, dy, surf, sx, sy, w, h); } FIRE_RING(nv->base.nvc->channel); -- cgit v1.2.3 From 776d86606cd8b250802730410d5e55a41944cf0a Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 6 Feb 2009 14:37:35 -0500 Subject: g3dvl: Catch up to gallium changes, fix build. --- src/gallium/winsys/g3dvl/nouveau/Makefile | 4 +++- src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 22d925b643..2997f6b79c 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -11,6 +11,7 @@ CFLAGS += -g -Wall -Werror=implicit-function-declaration -fPIC \ -I${GALLIUMDIR}/winsys/drm/nouveau \ -I${DRMDIR}/include \ -I${DRMDIR}/include/drm \ + -I${DRMDIR}/include/nouveau \ -I${GALLIUMDIR}/drivers \ -I${GALLIUMDIR}/auxiliary \ -I${DRIDIR}/include @@ -23,13 +24,14 @@ LDFLAGS += -L${DRMDIR}/lib \ -L${GALLIUMDIR}/auxiliary/translate \ -L${GALLIUMDIR}/auxiliary/rtasm \ -L${GALLIUMDIR}/auxiliary/cso_cache \ + -L${GALLIUMDIR}/drivers/nv04 \ -L${GALLIUMDIR}/drivers/nv10 \ -L${GALLIUMDIR}/drivers/nv20 \ -L${GALLIUMDIR}/drivers/nv30 \ -L${GALLIUMDIR}/drivers/nv40 \ -L${GALLIUMDIR}/drivers/nv50 -LIBS += -lnouveaudrm -ldriclient -ldrm -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm +LIBS += -lnouveaudrm -ldriclient -ldrm_nouveau -ldrm -lnv04 -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm ############################################# diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c index 658dafd910..b7c74f8299 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c @@ -4,7 +4,7 @@ #include #include -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 12 #error nouveau_drm.h version does not match expected version #endif diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c index 16e6d5543c..864be37871 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c @@ -9,6 +9,7 @@ nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, const drm_clip_rect_t *rect) { struct nouveau_context_vl *nv = dri_drawable->private; + struct pipe_context *pipe = nv->base.nvc->pctx[nv->base.pctx_id]; drm_clip_rect_t *pbox; int nbox, i; @@ -20,7 +21,6 @@ nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, pbox = dri_drawable->cliprects; nbox = dri_drawable->num_cliprects; - nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf); for (i = 0; i < nbox; i++, pbox++) { int sx, sy, dx, dy, w, h; @@ -31,7 +31,8 @@ nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, w = pbox->x2 - pbox->x1; h = pbox->y2 - pbox->y1; - nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h); + pipe->surface_copy(pipe, FALSE, nv->base.frontbuffer, + dx, dy, surf, sx, sy, w, h); } FIRE_RING(nv->base.nvc->channel); -- cgit v1.2.3 From 80026428e3aa8f71ccd42d8d3b5e0a15c150dda2 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Fri, 6 Feb 2009 13:28:15 -0800 Subject: Rename winsys amd to radeon. --- src/gallium/winsys/drm/amd/Makefile | 32 --- src/gallium/winsys/drm/amd/SConscript | 29 -- src/gallium/winsys/drm/amd/amd_buffer.c | 239 ---------------- src/gallium/winsys/drm/amd/amd_buffer.h | 54 ---- src/gallium/winsys/drm/amd/amd_context.c | 306 --------------------- src/gallium/winsys/drm/amd/amd_context.h | 70 ----- src/gallium/winsys/drm/amd/amd_r300.c | 96 ------- src/gallium/winsys/drm/amd/amd_r300.h | 34 --- src/gallium/winsys/drm/amd/amd_screen.c | 288 ------------------- src/gallium/winsys/drm/amd/amd_screen.h | 41 --- src/gallium/winsys/drm/amd/amd_winsys_softpipe.c | 77 ------ src/gallium/winsys/drm/amd/amd_winsys_softpipe.h | 37 --- src/gallium/winsys/drm/radeon/Makefile | 32 +++ src/gallium/winsys/drm/radeon/SConscript | 29 ++ src/gallium/winsys/drm/radeon/radeon_buffer.c | 239 ++++++++++++++++ src/gallium/winsys/drm/radeon/radeon_buffer.h | 54 ++++ src/gallium/winsys/drm/radeon/radeon_context.c | 306 +++++++++++++++++++++ src/gallium/winsys/drm/radeon/radeon_context.h | 70 +++++ src/gallium/winsys/drm/radeon/radeon_r300.c | 96 +++++++ src/gallium/winsys/drm/radeon/radeon_r300.h | 34 +++ src/gallium/winsys/drm/radeon/radeon_screen.c | 288 +++++++++++++++++++ src/gallium/winsys/drm/radeon/radeon_screen.h | 41 +++ .../winsys/drm/radeon/radeon_winsys_softpipe.c | 77 ++++++ .../winsys/drm/radeon/radeon_winsys_softpipe.h | 37 +++ 24 files changed, 1303 insertions(+), 1303 deletions(-) delete mode 100644 src/gallium/winsys/drm/amd/Makefile delete mode 100644 src/gallium/winsys/drm/amd/SConscript delete mode 100644 src/gallium/winsys/drm/amd/amd_buffer.c delete mode 100644 src/gallium/winsys/drm/amd/amd_buffer.h delete mode 100644 src/gallium/winsys/drm/amd/amd_context.c delete mode 100644 src/gallium/winsys/drm/amd/amd_context.h delete mode 100644 src/gallium/winsys/drm/amd/amd_r300.c delete mode 100644 src/gallium/winsys/drm/amd/amd_r300.h delete mode 100644 src/gallium/winsys/drm/amd/amd_screen.c delete mode 100644 src/gallium/winsys/drm/amd/amd_screen.h delete mode 100644 src/gallium/winsys/drm/amd/amd_winsys_softpipe.c delete mode 100644 src/gallium/winsys/drm/amd/amd_winsys_softpipe.h create mode 100644 src/gallium/winsys/drm/radeon/Makefile create mode 100644 src/gallium/winsys/drm/radeon/SConscript create mode 100644 src/gallium/winsys/drm/radeon/radeon_buffer.c create mode 100644 src/gallium/winsys/drm/radeon/radeon_buffer.h create mode 100644 src/gallium/winsys/drm/radeon/radeon_context.c create mode 100644 src/gallium/winsys/drm/radeon/radeon_context.h create mode 100644 src/gallium/winsys/drm/radeon/radeon_r300.c create mode 100644 src/gallium/winsys/drm/radeon/radeon_r300.h create mode 100644 src/gallium/winsys/drm/radeon/radeon_screen.c create mode 100644 src/gallium/winsys/drm/radeon/radeon_screen.h create mode 100644 src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.c create mode 100644 src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/amd/Makefile b/src/gallium/winsys/drm/amd/Makefile deleted file mode 100644 index fb77873404..0000000000 --- a/src/gallium/winsys/drm/amd/Makefile +++ /dev/null @@ -1,32 +0,0 @@ - -TOP = ../../../../.. -include $(TOP)/configs/current - -LIBNAME = amd_dri.so - -MINIGLX_SOURCES = - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/r300/libr300.a - -DRIVER_SOURCES = \ - amd_buffer.c \ - amd_context.c \ - amd_r300.c \ - amd_screen.c \ - amd_winsys_softpipe.c - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - -DRIVER_DEFINES = -I../../../drivers/r300 - -include ../Makefile.template - -DRI_LIB_DEPS += -ldrm_radeon - -symlinks: diff --git a/src/gallium/winsys/drm/amd/SConscript b/src/gallium/winsys/drm/amd/SConscript deleted file mode 100644 index a4856da23c..0000000000 --- a/src/gallium/winsys/drm/amd/SConscript +++ /dev/null @@ -1,29 +0,0 @@ -Import('*') - -if 'mesa' in env['statetrackers']: - - env = drienv.Clone() - - DRIVER_SOURCES = [ - 'amd_buffer.c', - 'amd_context.c', - 'amd_screen.c', - 'amd_winsys_softpipe.c', - ] - - sources = \ - COMMON_GALLIUM_SOURCES + \ - DRIVER_SOURCES - - drivers = [ - softpipe, - r300 - ] - - # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions - env.SharedLibrary( - target ='amd_dri.so', - source = sources, - LIBS = drivers + mesa + auxiliaries + env['LIBS'], - ) - diff --git a/src/gallium/winsys/drm/amd/amd_buffer.c b/src/gallium/winsys/drm/amd/amd_buffer.c deleted file mode 100644 index 4b831c7fcc..0000000000 --- a/src/gallium/winsys/drm/amd/amd_buffer.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * 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 - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - */ -/* - * Authors: - * J茅r么me Glisse - */ -#include -#include "dri_util.h" -#include "state_tracker/st_public.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "amd_buffer.h" -#include "amd_screen.h" -#include "amd_context.h" -#include "radeon_bo.h" -#include "radeon_drm.h" - -static const char *amd_get_name(struct pipe_winsys *ws) -{ - return "AMD/DRI2"; -} - -static struct pipe_buffer *amd_buffer_create(struct pipe_winsys *ws, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct amd_pipe_winsys *amd_ws = (struct amd_pipe_winsys *)ws; - struct amd_pipe_buffer *amd_buffer; - uint32_t domain; - - amd_buffer = calloc(1, sizeof(*amd_buffer)); - if (amd_buffer == NULL) { - return NULL; - } - amd_buffer->base.refcount = 1; - amd_buffer->base.alignment = alignment; - amd_buffer->base.usage = usage; - amd_buffer->base.size = size; - - domain = 0; - - if (usage & PIPE_BUFFER_USAGE_PIXEL) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BUFFER_USAGE_VERTEX) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - - if (usage & PIPE_BUFFER_USAGE_INDEX) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - amd_buffer->bo = radeon_bo_open(amd_ws->amd_screen->bom, 0, - size, alignment, domain, 0); - if (amd_buffer->bo == NULL) { - free(amd_buffer); - } - return &amd_buffer->base; -} - -static struct pipe_buffer *amd_buffer_user_create(struct pipe_winsys *ws, - void *ptr, - unsigned bytes) -{ - struct amd_pipe_buffer *amd_buffer; - - amd_buffer = (struct amd_pipe_buffer*)amd_buffer_create(ws, 0, 0, bytes); - if (amd_buffer == NULL) { - return NULL; - } - radeon_bo_map(amd_buffer->bo, 1); - memcpy(amd_buffer->bo->ptr, ptr, bytes); - radeon_bo_unmap(amd_buffer->bo); - return &amd_buffer->base; -} - -static void amd_buffer_del(struct pipe_winsys *ws, struct pipe_buffer *buffer) -{ - struct amd_pipe_buffer *amd_buffer = (struct amd_pipe_buffer*)buffer; - - radeon_bo_unref(amd_buffer->bo); - free(amd_buffer); -} - -static void *amd_buffer_map(struct pipe_winsys *ws, - struct pipe_buffer *buffer, - unsigned flags) -{ - struct amd_pipe_buffer *amd_buffer = (struct amd_pipe_buffer*)buffer; - int write = 0; - - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) { - write = 1; - } - if (radeon_bo_map(amd_buffer->bo, write)) - return NULL; - return amd_buffer->bo->ptr; -} - -static void amd_buffer_unmap(struct pipe_winsys *ws, struct pipe_buffer *buffer) -{ - struct amd_pipe_buffer *amd_buffer = (struct amd_pipe_buffer*)buffer; - - radeon_bo_unmap(amd_buffer->bo); -} - -static void amd_fence_reference(struct pipe_winsys *ws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *pfence) -{ -} - -static int amd_fence_signalled(struct pipe_winsys *ws, - struct pipe_fence_handle *pfence, - unsigned flag) -{ - return 1; -} - -static int amd_fence_finish(struct pipe_winsys *ws, - struct pipe_fence_handle *pfence, - unsigned flag) -{ - return 0; -} - -static void amd_flush_frontbuffer(struct pipe_winsys *pipe_winsys, - struct pipe_surface *pipe_surface, - void *context_private) -{ - /* TODO: call dri2CopyRegion */ -} - -struct pipe_winsys *amd_pipe_winsys(struct amd_screen *amd_screen) -{ - struct amd_pipe_winsys *amd_ws; - - amd_ws = calloc(1, sizeof(struct amd_pipe_winsys)); - if (amd_ws == NULL) { - return NULL; - } - amd_ws->amd_screen = amd_screen; - - amd_ws->winsys.flush_frontbuffer = amd_flush_frontbuffer; - - amd_ws->winsys.buffer_create = amd_buffer_create; - amd_ws->winsys.buffer_destroy = amd_buffer_del; - amd_ws->winsys.user_buffer_create = amd_buffer_user_create; - amd_ws->winsys.buffer_map = amd_buffer_map; - amd_ws->winsys.buffer_unmap = amd_buffer_unmap; - - amd_ws->winsys.fence_reference = amd_fence_reference; - amd_ws->winsys.fence_signalled = amd_fence_signalled; - amd_ws->winsys.fence_finish = amd_fence_finish; - - amd_ws->winsys.get_name = amd_get_name; - - return &amd_ws->winsys; -} - -static struct pipe_buffer *amd_buffer_from_handle(struct amd_screen *amd_screen, - uint32_t handle) -{ - struct amd_pipe_buffer *amd_buffer; - struct radeon_bo *bo = NULL; - - bo = radeon_bo_open(amd_screen->bom, handle, 0, 0, 0, 0); - if (bo == NULL) { - return NULL; - } - amd_buffer = calloc(1, sizeof(struct amd_pipe_buffer)); - if (amd_buffer == NULL) { - radeon_bo_unref(bo); - return NULL; - } - amd_buffer->base.refcount = 1; - amd_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL; - amd_buffer->bo = bo; - return &amd_buffer->base; -} - -struct pipe_surface *amd_surface_from_handle(struct amd_context *amd_context, - uint32_t handle, - enum pipe_format format, - int w, int h, int pitch) -{ - struct pipe_screen *pipe_screen = amd_context->pipe_screen; - struct pipe_winsys *pipe_winsys = amd_context->pipe_winsys; - struct pipe_texture tmpl; - struct pipe_surface *ps; - struct pipe_texture *pt; - struct pipe_buffer *pb; - - pb = amd_buffer_from_handle(amd_context->amd_screen, handle); - if (pb == NULL) { - return NULL; - } - memset(&tmpl, 0, sizeof(tmpl)); - tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET; - tmpl.target = PIPE_TEXTURE_2D; - tmpl.width[0] = w; - tmpl.height[0] = h; - tmpl.depth[0] = 1; - tmpl.format = format; - pf_get_block(tmpl.format, &tmpl.block); - tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w); - tmpl.nblocksy[0] = pf_get_nblocksy(&tmpl.block, h); - - pt = pipe_screen->texture_blanket(pipe_screen, &tmpl, &pitch, pb); - if (pt == NULL) { - pipe_buffer_reference(pipe_screen, &pb, NULL); - } - ps = pipe_screen->get_tex_surface(pipe_screen, pt, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_WRITE); - return ps; -} diff --git a/src/gallium/winsys/drm/amd/amd_buffer.h b/src/gallium/winsys/drm/amd/amd_buffer.h deleted file mode 100644 index 238ca572ae..0000000000 --- a/src/gallium/winsys/drm/amd/amd_buffer.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - */ -/* - * Authors: - * J茅r么me Glisse - */ -#ifndef AMD_BUFFER_H -#define AMD_BUFFER_H - -#include "pipe/internal/p_winsys_screen.h" -#include "amd_screen.h" -#include "amd_context.h" -#include "radeon_bo.h" - -struct amd_pipe_buffer { - struct pipe_buffer base; - struct radeon_bo *bo; -}; - -struct amd_pipe_winsys { - struct pipe_winsys winsys; - struct amd_screen *amd_screen; -}; - -struct pipe_winsys *amd_pipe_winsys(struct amd_screen *amd_screen); -struct pipe_surface *amd_surface_from_handle(struct amd_context *amd_context, - uint32_t handle, - enum pipe_format format, - int w, int h, int pitch); - -#endif diff --git a/src/gallium/winsys/drm/amd/amd_context.c b/src/gallium/winsys/drm/amd/amd_context.c deleted file mode 100644 index e089cf6874..0000000000 --- a/src/gallium/winsys/drm/amd/amd_context.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * 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 - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - */ -/* - * Authors: - * J茅r么me Glisse - */ -#include -#include "dri_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" -#include "amd_screen.h" -#include "amd_context.h" -#include "amd_buffer.h" -#include "amd_winsys_softpipe.h" - -#define need_GL_ARB_fragment_program -#define need_GL_ARB_multisample -#define need_GL_ARB_point_parameters -#define need_GL_ARB_shader_objects -#define need_GL_ARB_texture_compression -#define need_GL_ARB_vertex_buffer_object -#define need_GL_ARB_vertex_program -#define need_GL_ARB_vertex_shader -#define need_GL_EXT_blend_color -#define need_GL_EXT_blend_equation_separate -#define need_GL_EXT_blend_func_separate -#define need_GL_EXT_blend_minmax -#define need_GL_EXT_cull_vertex -#define need_GL_EXT_compiled_vertex_array -#define need_GL_EXT_fog_coord -#define need_GL_EXT_framebuffer_object -#define need_GL_EXT_multi_draw_arrays -#define need_GL_EXT_secondary_color -#define need_GL_VERSION_2_0 -#define need_GL_VERSION_2_1 -#include "extension_helper.h" - -/** - * Extension strings exported by the amd driver. - */ -const struct dri_extension amd_card_extensions[] = { - {"GL_ARB_multitexture", NULL}, - {"GL_ARB_texture_border_clamp", NULL}, - {"GL_ARB_texture_rectangle", NULL}, - {"GL_ARB_pixel_buffer_object", NULL}, - {"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_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, - {"GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions}, - {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, - {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, - {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, - {"GL_EXT_blend_subtract", NULL}, - {"GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions}, - {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, - {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, - {"GL_EXT_packed_depth_stencil", NULL}, - {"GL_EXT_pixel_buffer_object", NULL}, - {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, - {"GL_EXT_stencil_wrap", NULL}, - {NULL, NULL} -}; - -static void amd_update_renderbuffers(__DRIcontext *dri_context, - __DRIdrawable *dri_drawable) -{ - struct amd_framebuffer *amd_fb; - struct amd_context *amd_context; - unsigned attachments[10]; - __DRIbuffer *buffers; - __DRIscreen *screen; - int i, count; - - amd_context = dri_context->driverPrivate; - screen = dri_drawable->driScreenPriv; - amd_fb = dri_drawable->driverPrivate; - for (count = 0, i = 0; count < 6; count++) { - if (amd_fb->attachments & (1 << count)) { - attachments[i++] = count; - } - } - - buffers = (*screen->dri2.loader->getBuffers)(dri_drawable, - &dri_drawable->w, - &dri_drawable->h, - attachments, - i, - &count, - dri_drawable->loaderPrivate); - if (buffers == NULL) { - return; - } - - /* set one cliprect to cover the whole dri_drawable */ - dri_drawable->x = 0; - dri_drawable->y = 0; - dri_drawable->backX = 0; - dri_drawable->backY = 0; - dri_drawable->numClipRects = 1; - dri_drawable->pClipRects[0].x1 = 0; - dri_drawable->pClipRects[0].y1 = 0; - dri_drawable->pClipRects[0].x2 = dri_drawable->w; - dri_drawable->pClipRects[0].y2 = dri_drawable->h; - dri_drawable->numBackClipRects = 1; - dri_drawable->pBackClipRects[0].x1 = 0; - dri_drawable->pBackClipRects[0].y1 = 0; - dri_drawable->pBackClipRects[0].x2 = dri_drawable->w; - dri_drawable->pBackClipRects[0].y2 = dri_drawable->h; - - for (i = 0; i < count; i++) { - struct pipe_surface *ps; - enum pipe_format format = 0; - int index = 0; - - switch (buffers[i].attachment) { - case __DRI_BUFFER_FRONT_LEFT: - index = ST_SURFACE_FRONT_LEFT; - switch (buffers[i].cpp) { - case 4: - format = PIPE_FORMAT_A8R8G8B8_UNORM; - break; - case 2: - format = PIPE_FORMAT_R5G6B5_UNORM; - break; - default: - /* FIXME: error */ - return; - } - break; - case __DRI_BUFFER_BACK_LEFT: - index = ST_SURFACE_BACK_LEFT; - switch (buffers[i].cpp) { - case 4: - format = PIPE_FORMAT_A8R8G8B8_UNORM; - break; - case 2: - format = PIPE_FORMAT_R5G6B5_UNORM; - break; - default: - /* FIXME: error */ - return; - } - break; - case __DRI_BUFFER_STENCIL: - case __DRI_BUFFER_DEPTH: - index = ST_SURFACE_DEPTH; - switch (buffers[i].cpp) { - case 4: - format = PIPE_FORMAT_Z24S8_UNORM; - break; - case 2: - format = PIPE_FORMAT_Z16_UNORM; - break; - default: - /* FIXME: error */ - return; - } - break; - case __DRI_BUFFER_ACCUM: - default: - fprintf(stderr, - "unhandled buffer attach event, attacment type %d\n", - buffers[i].attachment); - return; - } - - ps = amd_surface_from_handle(amd_context, - buffers[i].name, - format, - dri_drawable->w, - dri_drawable->h, - buffers[i].pitch); - assert(ps); - st_set_framebuffer_surface(amd_fb->st_framebuffer, index, ps); - } - st_resize_framebuffer(amd_fb->st_framebuffer, - dri_drawable->w, - dri_drawable->h); -} - -GLboolean amd_context_create(const __GLcontextModes *visual, - __DRIcontextPrivate *dri_context, - void *shared_context) -{ - __DRIscreenPrivate *dri_screen; - struct amd_context *amd_context; - struct amd_screen *amd_screen; - struct pipe_context *pipe; - struct st_context *shared_st_context = NULL; - - dri_context->driverPrivate = NULL; - amd_context = calloc(1, sizeof(struct amd_context)); - if (amd_context == NULL) { - return GL_FALSE; - } - - if (shared_context) { - shared_st_context = ((struct amd_context*)shared_context)->st_context; - } - - dri_screen = dri_context->driScreenPriv; - amd_screen = dri_screen->private; - amd_context->dri_screen = dri_screen; - amd_context->amd_screen = amd_screen; - amd_context->drm_fd = dri_screen->fd; - - amd_context->pipe_winsys = amd_pipe_winsys(amd_screen); - if (amd_context->pipe_winsys == NULL) { - free(amd_context); - return GL_FALSE; - } - - if (!getenv("AMD_SOFTPIPE")) { - fprintf(stderr, "Creating r300 context...\n"); - pipe = - r300_create_context(NULL, - amd_context->pipe_winsys, - amd_create_r300_winsys(amd_context->drm_fd)); - amd_context->pipe_screen = pipe->screen; - } else { - pipe = amd_create_softpipe(amd_context); - } - amd_context->st_context = st_create_context(pipe, visual, - shared_st_context); - driInitExtensions(amd_context->st_context->ctx, - amd_card_extensions, GL_TRUE); - dri_context->driverPrivate = amd_context; - return GL_TRUE; -} - -void amd_context_destroy(__DRIcontextPrivate *dri_context) -{ - struct amd_context *amd_context; - - amd_context = dri_context->driverPrivate; - st_finish(amd_context->st_context); - st_destroy_context(amd_context->st_context); - free(amd_context); -} - -GLboolean amd_context_bind(__DRIcontextPrivate *dri_context, - __DRIdrawablePrivate *dri_drawable, - __DRIdrawablePrivate *dri_readable) -{ - struct amd_framebuffer *drawable; - struct amd_framebuffer *readable; - struct amd_context *amd_context; - - if (dri_context == NULL) { - st_make_current(NULL, NULL, NULL); - return GL_TRUE; - } - - amd_context = dri_context->driverPrivate; - drawable = dri_drawable->driverPrivate; - readable = dri_readable->driverPrivate; - st_make_current(amd_context->st_context, - drawable->st_framebuffer, - readable->st_framebuffer); - - amd_update_renderbuffers(dri_context, dri_drawable); - if (dri_drawable != dri_readable) { - amd_update_renderbuffers(dri_context, dri_readable); - } - return GL_TRUE; -} - -GLboolean amd_context_unbind(__DRIcontextPrivate *dri_context) -{ - struct amd_context *amd_context; - - amd_context = dri_context->driverPrivate; - st_flush(amd_context->st_context, PIPE_FLUSH_RENDER_CACHE, NULL); - return GL_TRUE; -} diff --git a/src/gallium/winsys/drm/amd/amd_context.h b/src/gallium/winsys/drm/amd/amd_context.h deleted file mode 100644 index 12557c40c4..0000000000 --- a/src/gallium/winsys/drm/amd/amd_context.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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 - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - */ -/* - * Authors: - * J茅r么me Glisse - */ -#ifndef AMD_CONTEXT_H -#define AMD_CONTEXT_H - -#include "dri_util.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" -#include "amd_screen.h" - -#include "amd_r300.h" - -struct amd_framebuffer { - struct st_framebuffer *st_framebuffer; - unsigned attachments; -}; - -struct amd_context { - /* st */ - struct st_context *st_context; - /* pipe */ - struct pipe_screen *pipe_screen; - struct pipe_winsys *pipe_winsys; - /* DRI */ - __DRIscreenPrivate *dri_screen; - __DRIdrawablePrivate *dri_drawable; - __DRIdrawablePrivate *dri_readable; - /* DRM */ - int drm_fd; - /* AMD */ - struct amd_screen *amd_screen; -}; - -GLboolean amd_context_create(const __GLcontextModes*, - __DRIcontextPrivate*, - void*); -void amd_context_destroy(__DRIcontextPrivate*); -GLboolean amd_context_bind(__DRIcontextPrivate*, - __DRIdrawablePrivate*, - __DRIdrawablePrivate*); -GLboolean amd_context_unbind(__DRIcontextPrivate*); - -#endif diff --git a/src/gallium/winsys/drm/amd/amd_r300.c b/src/gallium/winsys/drm/amd/amd_r300.c deleted file mode 100644 index 04295e8281..0000000000 --- a/src/gallium/winsys/drm/amd/amd_r300.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2008 Corbin Simpson - * - * 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 - * on 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 - * THE AUTHOR(S) AND/OR THEIR 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 "amd_r300.h" - -static boolean amd_r300_check_cs(struct radeon_cs* cs, int size) -{ - /* XXX check size here, lazy ass! */ - return TRUE; -} - -static void amd_r300_write_cs_reloc(struct radeon_cs* cs, - struct pipe_buffer* pbuffer, - uint32_t rd, - uint32_t wd, - uint32_t flags) -{ - radeon_cs_write_reloc(cs, ((struct amd_pipe_buffer*)pbuffer)->bo, rd, wd, flags); -} - -static void amd_r300_flush_cs(struct radeon_cs* cs) -{ - radeon_cs_emit(cs); - radeon_cs_erase(cs); -} - -/* Helper function to do the ioctls needed for setup and init. */ -static void do_ioctls(struct r300_winsys* winsys, int fd) -{ - drm_radeon_getparam_t gp; - uint32_t target; - int retval; - - /* XXX is this cast safe? */ - gp.value = (int*)⌖ - - /* First, get PCI ID */ - gp.param = RADEON_PARAM_DEVICE_ID; - retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); - if (retval) { - fprintf(stderr, "%s: Failed to get PCI ID, error number %d", - __FUNCTION__, retval); - exit(1); - } - winsys->pci_id = target; - - /* Then, get the number of pixel pipes */ - gp.param = RADEON_PARAM_NUM_GB_PIPES; - retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); - if (retval) { - fprintf(stderr, "%s: Failed to get GB pipe count, error number %d", - __FUNCTION__, retval); - exit(1); - } - winsys->gb_pipes = target; - -} - -struct r300_winsys* amd_create_r300_winsys(int fd) -{ - struct r300_winsys* winsys = calloc(1, sizeof(struct r300_winsys)); - - do_ioctls(winsys, fd); - - struct radeon_cs_manager* csm = radeon_cs_manager_gem_ctor(fd); - - winsys->cs = radeon_cs_create(csm, 1024 * 64 / 4); - - winsys->check_cs = amd_r300_check_cs; - winsys->begin_cs = radeon_cs_begin; - winsys->write_cs_dword = radeon_cs_write_dword; - winsys->write_cs_reloc = amd_r300_write_cs_reloc; - winsys->end_cs = radeon_cs_end; - winsys->flush_cs = amd_r300_flush_cs; - - return winsys; -} diff --git a/src/gallium/winsys/drm/amd/amd_r300.h b/src/gallium/winsys/drm/amd/amd_r300.h deleted file mode 100644 index d80c23594c..0000000000 --- a/src/gallium/winsys/drm/amd/amd_r300.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2008 Corbin Simpson - * - * 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 - * on 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 - * THE AUTHOR(S) AND/OR THEIR 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. */ - -/* XXX WTF is this! I shouldn't have to include those first three! FUCK! */ -#include -#include -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_cs.h" - -#include "r300_winsys.h" - -#include "amd_buffer.h" - -struct r300_winsys* amd_create_r300_winsys(int fd); diff --git a/src/gallium/winsys/drm/amd/amd_screen.c b/src/gallium/winsys/drm/amd/amd_screen.c deleted file mode 100644 index d62b47f36d..0000000000 --- a/src/gallium/winsys/drm/amd/amd_screen.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * 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 - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - */ -/* - * Authors: - * J茅r么me Glisse - */ -#include -#include "pipe/p_screen.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" -#include "utils.h" -#include "xf86drm.h" -#include "drm.h" -#include "dri_util.h" -#include "amd_screen.h" -#include "amd_context.h" -#include "amd_buffer.h" -#include "radeon_bo.h" -#include "radeon_bo_gem.h" -#include "radeon_drm.h" - -extern const struct dri_extension amd_card_extensions[]; - -static const __DRIextension *amd_screen_extensions[] = { - &driReadDrawableExtension, - &driCopySubBufferExtension.base, - &driSwapControlExtension.base, - &driFrameTrackingExtension.base, - &driMediaStreamCounterExtension.base, - NULL -}; - -static __DRIconfig **amd_fill_in_modes(unsigned pixel_bits, - unsigned depth_bits, - GLboolean have_back_buffer) -{ - __DRIconfig **configs; - unsigned depth_buffer_factor; - unsigned back_buffer_factor; - unsigned num_modes; - GLenum fb_format; - GLenum fb_type; - uint8_t depth_bits_array[3]; - uint8_t stencil_bits_array[3]; - uint8_t msaa_samples_array[1]; - /* TODO: pageflipping ? */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML - }; - - stencil_bits_array[0] = 0; - stencil_bits_array[1] = 0; - if (depth_bits == 24) { - stencil_bits_array[2] = 8; - num_modes = 3; - } - - depth_bits_array[0] = 0; - depth_bits_array[1] = depth_bits; - depth_bits_array[2] = depth_bits; - depth_buffer_factor = (depth_bits == 24) ? 3 : 2; - - back_buffer_factor = (have_back_buffer) ? 3 : 1; - - msaa_samples_array[0] = 0; - - 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 = (__DRIconfig **)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", - __FILE__, __LINE__); - return NULL; - } - return configs; -} - -static void amd_screen_destroy(__DRIscreenPrivate *dri_screen) -{ - struct amd_screen *amd_screen = (struct amd_screen*)dri_screen->private; - - radeon_bo_manager_gem_dtor(amd_screen->bom); - dri_screen = NULL; - free(amd_screen); -} - -static const __DRIconfig **amd_screen_init(__DRIscreenPrivate *dri_screen) -{ - struct amd_screen *amd_screen; - - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is - * called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions(NULL, amd_card_extensions, GL_FALSE); - - amd_screen = calloc(1, sizeof(struct amd_screen)); - if (amd_screen == NULL) { - fprintf(stderr, "\nERROR! Allocating private area failed\n"); - return NULL; - } - dri_screen->private = (void*)amd_screen; - dri_screen->extensions = amd_screen_extensions; - amd_screen->dri_screen = dri_screen; - - amd_screen->bom = radeon_bo_manager_gem_ctor(dri_screen->fd); - if (amd_screen->bom == NULL) { - amd_screen_destroy(dri_screen); - return NULL; - } - - return driConcatConfigs(amd_fill_in_modes(16, 16, 1), - amd_fill_in_modes(32, 24, 1)); -} - -static boolean amd_buffer_create(__DRIscreenPrivate *dri_screen, - __DRIdrawablePrivate *dri_drawable, - const __GLcontextModes *visual, - boolean is_pixmap) -{ - if (is_pixmap) { - /* TODO: implement ? */ - return GL_FALSE; - } else { - enum pipe_format color_format, depth_format, stencil_format; - struct amd_framebuffer *amd_fb; - - amd_fb = calloc(1, sizeof(struct amd_framebuffer)); - if (amd_fb == NULL) { - return GL_FALSE; - } - - switch (visual->redBits) { - case 5: - color_format = PIPE_FORMAT_R5G6B5_UNORM; - break; - default: - color_format = PIPE_FORMAT_A8R8G8B8_UNORM; - break; - } - - switch (visual->depthBits) { - case 24: - depth_format = PIPE_FORMAT_S8Z24_UNORM; - break; - case 16: - depth_format = PIPE_FORMAT_Z16_UNORM; - break; - default: - depth_format = PIPE_FORMAT_NONE; - break; - } - - switch (visual->stencilBits) { - case 8: - /* force depth format */ - depth_format = PIPE_FORMAT_S8Z24_UNORM; - stencil_format = PIPE_FORMAT_S8Z24_UNORM; - break; - default: - stencil_format = PIPE_FORMAT_NONE; - break; - } - - amd_fb->st_framebuffer = st_create_framebuffer(visual, - color_format, - depth_format, - stencil_format, - dri_drawable->w, - dri_drawable->h, - (void*)amd_fb); - if (amd_fb->st_framebuffer == NULL) { - free(amd_fb); - return GL_FALSE; - } - dri_drawable->driverPrivate = (void *) amd_fb; - - amd_fb->attachments = (1 << __DRI_BUFFER_FRONT_LEFT); - if (visual->doubleBufferMode) { - amd_fb->attachments |= (1 << __DRI_BUFFER_BACK_LEFT); - } - if (visual->depthBits || visual->stencilBits) { - amd_fb->attachments |= (1 << __DRI_BUFFER_DEPTH); - } - - return GL_TRUE; - } -} - -static void amd_buffer_destroy(__DRIdrawablePrivate * dri_drawable) -{ - struct amd_framebuffer *amd_fb; - - amd_fb = dri_drawable->driverPrivate; - assert(amd_fb->st_framebuffer); - st_unreference_framebuffer(amd_fb->st_framebuffer); - free(amd_fb); -} - -static void amd_swap_buffers(__DRIdrawablePrivate *dri_drawable) -{ - struct amd_framebuffer *amd_fb; - struct pipe_surface *back_surf = NULL; - - amd_fb = dri_drawable->driverPrivate; - assert(amd_fb); - assert(amd_fb->st_framebuffer); - - st_get_framebuffer_surface(amd_fb->st_framebuffer, - ST_SURFACE_BACK_LEFT, - &back_surf); - if (back_surf) { - st_notify_swapbuffers(amd_fb->st_framebuffer); - /* TODO: do we want to do anythings ? */ - st_notify_swapbuffers_complete(amd_fb->st_framebuffer); - } -} - -/** - * Called via glXCopySubBufferMESA() to copy a subrect of the back - * buffer to the front buffer/screen. - */ -static void amd_copy_sub_buffer(__DRIdrawablePrivate *dri_drawable, - int x, int y, int w, int h) -{ - /* TODO: ... */ -} - -const struct __DriverAPIRec driDriverAPI = { - .InitScreen = NULL, - .DestroyScreen = amd_screen_destroy, - .CreateContext = amd_context_create, - .DestroyContext = amd_context_destroy, - .CreateBuffer = amd_buffer_create, - .DestroyBuffer = amd_buffer_destroy, - .SwapBuffers = amd_swap_buffers, - .MakeCurrent = amd_context_bind, - .UnbindContext = amd_context_unbind, - .CopySubBuffer = amd_copy_sub_buffer, - .InitScreen2 = amd_screen_init, -}; diff --git a/src/gallium/winsys/drm/amd/amd_screen.h b/src/gallium/winsys/drm/amd/amd_screen.h deleted file mode 100644 index 2617393f2e..0000000000 --- a/src/gallium/winsys/drm/amd/amd_screen.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - */ -/* - * Authors: - * J茅r么me Glisse - */ -#ifndef AMD_SCREEN_H -#define AMD_SCREEN_H - -#include "dri_util.h" -#include "radeon_bo.h" - -struct amd_screen { - __DRIscreenPrivate *dri_screen; - struct radeon_bo_manager *bom; -}; - -#endif diff --git a/src/gallium/winsys/drm/amd/amd_winsys_softpipe.c b/src/gallium/winsys/drm/amd/amd_winsys_softpipe.c deleted file mode 100644 index b9b2a0e8b8..0000000000 --- a/src/gallium/winsys/drm/amd/amd_winsys_softpipe.c +++ /dev/null @@ -1,77 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ -#include -#include "imports.h" -#include "pipe/p_defines.h" -#include "pipe/p_format.h" -#include "softpipe/sp_winsys.h" -#include "amd_context.h" -#include "amd_winsys_softpipe.h" - -struct amd_softpipe_winsys { - struct softpipe_winsys sp_winsys; - struct amd_context *amd_context; -}; - -/** - * Return list of surface formats supported by this driver. - */ -static boolean amd_is_format_supported(struct softpipe_winsys *sws, uint format) -{ - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return TRUE; - default: - break; - }; - return FALSE; -} - -struct pipe_context *amd_create_softpipe(struct amd_context *amd_context) -{ - struct amd_softpipe_winsys *amd_sp_ws; - struct pipe_screen *pipe_screen; - - pipe_screen = softpipe_create_screen(amd_context->pipe_winsys); - - amd_sp_ws = CALLOC_STRUCT(amd_softpipe_winsys); - if (amd_sp_ws == NULL) { - return NULL; - } - amd_context->pipe_screen = pipe_screen; - amd_sp_ws->amd_context = amd_context; - amd_sp_ws->sp_winsys.is_format_supported = amd_is_format_supported; - return softpipe_create(pipe_screen, - amd_context->pipe_winsys, - &amd_sp_ws->sp_winsys); -} diff --git a/src/gallium/winsys/drm/amd/amd_winsys_softpipe.h b/src/gallium/winsys/drm/amd/amd_winsys_softpipe.h deleted file mode 100644 index e5b68cf8a5..0000000000 --- a/src/gallium/winsys/drm/amd/amd_winsys_softpipe.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 - * 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 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 - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - */ -/* - * Authors: - * J茅r么me Glisse - */ -#ifndef AMD_WINSYS_SOFTPIPE_H -#define AMD_WINSYS_SOFTPIPE_H - -#include "amd_context.h" - -struct pipe_context *amd_create_softpipe(struct amd_context *amd_context); - -#endif diff --git a/src/gallium/winsys/drm/radeon/Makefile b/src/gallium/winsys/drm/radeon/Makefile new file mode 100644 index 0000000000..dca1e3233a --- /dev/null +++ b/src/gallium/winsys/drm/radeon/Makefile @@ -0,0 +1,32 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = radeon_dri.so + +MINIGLX_SOURCES = + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/r300/libr300.a + +DRIVER_SOURCES = \ + radeon_buffer.c \ + radeon_context.c \ + radeon_r300.c \ + radeon_screen.c \ + radeon_winsys_softpipe.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +DRIVER_DEFINES = -I../../../drivers/r300 + +include ../Makefile.template + +DRI_LIB_DEPS += -ldrm_radeon + +symlinks: diff --git a/src/gallium/winsys/drm/radeon/SConscript b/src/gallium/winsys/drm/radeon/SConscript new file mode 100644 index 0000000000..2435211a32 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/SConscript @@ -0,0 +1,29 @@ +Import('*') + +if 'mesa' in env['statetrackers']: + + env = drienv.Clone() + + DRIVER_SOURCES = [ + 'radeon_buffer.c', + 'radeon_context.c', + 'radeon_screen.c', + 'radeon_winsys_softpipe.c', + ] + + sources = \ + COMMON_GALLIUM_SOURCES + \ + DRIVER_SOURCES + + drivers = [ + softpipe, + r300 + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='radeon_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], + ) + diff --git a/src/gallium/winsys/drm/radeon/radeon_buffer.c b/src/gallium/winsys/drm/radeon/radeon_buffer.c new file mode 100644 index 0000000000..259a505c0a --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_buffer.c @@ -0,0 +1,239 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#include +#include "dri_util.h" +#include "state_tracker/st_public.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "radeon_buffer.h" +#include "radeon_screen.h" +#include "radeon_context.h" +#include "radeon_bo.h" +#include "radeon_drm.h" + +static const char *radeon_get_name(struct pipe_winsys *ws) +{ + return "RADEON/DRI2"; +} + +static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct radeon_pipe_winsys *radeon_ws = (struct radeon_pipe_winsys *)ws; + struct radeon_pipe_buffer *radeon_buffer; + uint32_t domain; + + radeon_buffer = calloc(1, sizeof(*radeon_buffer)); + if (radeon_buffer == NULL) { + return NULL; + } + radeon_buffer->base.refcount = 1; + radeon_buffer->base.alignment = alignment; + radeon_buffer->base.usage = usage; + radeon_buffer->base.size = size; + + domain = 0; + + if (usage & PIPE_BUFFER_USAGE_PIXEL) { + domain |= RADEON_GEM_DOMAIN_VRAM; + } + if (usage & PIPE_BUFFER_USAGE_VERTEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + + if (usage & PIPE_BUFFER_USAGE_INDEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + radeon_buffer->bo = radeon_bo_open(radeon_ws->radeon_screen->bom, 0, + size, alignment, domain, 0); + if (radeon_buffer->bo == NULL) { + free(radeon_buffer); + } + return &radeon_buffer->base; +} + +static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws, + void *ptr, + unsigned bytes) +{ + struct radeon_pipe_buffer *radeon_buffer; + + radeon_buffer = (struct radeon_pipe_buffer*)radeon_buffer_create(ws, 0, 0, bytes); + if (radeon_buffer == NULL) { + return NULL; + } + radeon_bo_map(radeon_buffer->bo, 1); + memcpy(radeon_buffer->bo->ptr, ptr, bytes); + radeon_bo_unmap(radeon_buffer->bo); + return &radeon_buffer->base; +} + +static void radeon_buffer_del(struct pipe_winsys *ws, struct pipe_buffer *buffer) +{ + struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; + + radeon_bo_unref(radeon_buffer->bo); + free(radeon_buffer); +} + +static void *radeon_buffer_map(struct pipe_winsys *ws, + struct pipe_buffer *buffer, + unsigned flags) +{ + struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; + int write = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) { + write = 1; + } + if (radeon_bo_map(radeon_buffer->bo, write)) + return NULL; + return radeon_buffer->bo->ptr; +} + +static void radeon_buffer_unmap(struct pipe_winsys *ws, struct pipe_buffer *buffer) +{ + struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; + + radeon_bo_unmap(radeon_buffer->bo); +} + +static void radeon_fence_reference(struct pipe_winsys *ws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *pfence) +{ +} + +static int radeon_fence_signalled(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, + unsigned flag) +{ + return 1; +} + +static int radeon_fence_finish(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, + unsigned flag) +{ + return 0; +} + +static void radeon_flush_frontbuffer(struct pipe_winsys *pipe_winsys, + struct pipe_surface *pipe_surface, + void *context_private) +{ + /* TODO: call dri2CopyRegion */ +} + +struct pipe_winsys *radeon_pipe_winsys(struct radeon_screen *radeon_screen) +{ + struct radeon_pipe_winsys *radeon_ws; + + radeon_ws = calloc(1, sizeof(struct radeon_pipe_winsys)); + if (radeon_ws == NULL) { + return NULL; + } + radeon_ws->radeon_screen = radeon_screen; + + radeon_ws->winsys.flush_frontbuffer = radeon_flush_frontbuffer; + + radeon_ws->winsys.buffer_create = radeon_buffer_create; + radeon_ws->winsys.buffer_destroy = radeon_buffer_del; + radeon_ws->winsys.user_buffer_create = radeon_buffer_user_create; + radeon_ws->winsys.buffer_map = radeon_buffer_map; + radeon_ws->winsys.buffer_unmap = radeon_buffer_unmap; + + radeon_ws->winsys.fence_reference = radeon_fence_reference; + radeon_ws->winsys.fence_signalled = radeon_fence_signalled; + radeon_ws->winsys.fence_finish = radeon_fence_finish; + + radeon_ws->winsys.get_name = radeon_get_name; + + return &radeon_ws->winsys; +} + +static struct pipe_buffer *radeon_buffer_from_handle(struct radeon_screen *radeon_screen, + uint32_t handle) +{ + struct radeon_pipe_buffer *radeon_buffer; + struct radeon_bo *bo = NULL; + + bo = radeon_bo_open(radeon_screen->bom, handle, 0, 0, 0, 0); + if (bo == NULL) { + return NULL; + } + radeon_buffer = calloc(1, sizeof(struct radeon_pipe_buffer)); + if (radeon_buffer == NULL) { + radeon_bo_unref(bo); + return NULL; + } + radeon_buffer->base.refcount = 1; + radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL; + radeon_buffer->bo = bo; + return &radeon_buffer->base; +} + +struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, + uint32_t handle, + enum pipe_format format, + int w, int h, int pitch) +{ + struct pipe_screen *pipe_screen = radeon_context->pipe_screen; + struct pipe_winsys *pipe_winsys = radeon_context->pipe_winsys; + struct pipe_texture tmpl; + struct pipe_surface *ps; + struct pipe_texture *pt; + struct pipe_buffer *pb; + + pb = radeon_buffer_from_handle(radeon_context->radeon_screen, handle); + if (pb == NULL) { + return NULL; + } + memset(&tmpl, 0, sizeof(tmpl)); + tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + tmpl.target = PIPE_TEXTURE_2D; + tmpl.width[0] = w; + tmpl.height[0] = h; + tmpl.depth[0] = 1; + tmpl.format = format; + pf_get_block(tmpl.format, &tmpl.block); + tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w); + tmpl.nblocksy[0] = pf_get_nblocksy(&tmpl.block, h); + + pt = pipe_screen->texture_blanket(pipe_screen, &tmpl, &pitch, pb); + if (pt == NULL) { + pipe_buffer_reference(pipe_screen, &pb, NULL); + } + ps = pipe_screen->get_tex_surface(pipe_screen, pt, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + return ps; +} diff --git a/src/gallium/winsys/drm/radeon/radeon_buffer.h b/src/gallium/winsys/drm/radeon/radeon_buffer.h new file mode 100644 index 0000000000..c626c20229 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_buffer.h @@ -0,0 +1,54 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#ifndef RADEON_BUFFER_H +#define RADEON_BUFFER_H + +#include "pipe/internal/p_winsys_screen.h" +#include "radeon_screen.h" +#include "radeon_context.h" +#include "radeon_bo.h" + +struct radeon_pipe_buffer { + struct pipe_buffer base; + struct radeon_bo *bo; +}; + +struct radeon_pipe_winsys { + struct pipe_winsys winsys; + struct radeon_screen *radeon_screen; +}; + +struct pipe_winsys *radeon_pipe_winsys(struct radeon_screen *radeon_screen); +struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, + uint32_t handle, + enum pipe_format format, + int w, int h, int pitch); + +#endif diff --git a/src/gallium/winsys/drm/radeon/radeon_context.c b/src/gallium/winsys/drm/radeon/radeon_context.c new file mode 100644 index 0000000000..a9d1577634 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_context.c @@ -0,0 +1,306 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#include +#include "dri_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "radeon_screen.h" +#include "radeon_context.h" +#include "radeon_buffer.h" +#include "radeon_winsys_softpipe.h" + +#define need_GL_ARB_fragment_program +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_shader_objects +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_vertex_shader +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_compiled_vertex_array +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_VERSION_2_0 +#define need_GL_VERSION_2_1 +#include "extension_helper.h" + +/** + * Extension strings exported by the radeon driver. + */ +const struct dri_extension radeon_card_extensions[] = { + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"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_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {NULL, NULL} +}; + +static void radeon_update_renderbuffers(__DRIcontext *dri_context, + __DRIdrawable *dri_drawable) +{ + struct radeon_framebuffer *radeon_fb; + struct radeon_context *radeon_context; + unsigned attachments[10]; + __DRIbuffer *buffers; + __DRIscreen *screen; + int i, count; + + radeon_context = dri_context->driverPrivate; + screen = dri_drawable->driScreenPriv; + radeon_fb = dri_drawable->driverPrivate; + for (count = 0, i = 0; count < 6; count++) { + if (radeon_fb->attachments & (1 << count)) { + attachments[i++] = count; + } + } + + buffers = (*screen->dri2.loader->getBuffers)(dri_drawable, + &dri_drawable->w, + &dri_drawable->h, + attachments, + i, + &count, + dri_drawable->loaderPrivate); + if (buffers == NULL) { + return; + } + + /* set one cliprect to cover the whole dri_drawable */ + dri_drawable->x = 0; + dri_drawable->y = 0; + dri_drawable->backX = 0; + dri_drawable->backY = 0; + dri_drawable->numClipRects = 1; + dri_drawable->pClipRects[0].x1 = 0; + dri_drawable->pClipRects[0].y1 = 0; + dri_drawable->pClipRects[0].x2 = dri_drawable->w; + dri_drawable->pClipRects[0].y2 = dri_drawable->h; + dri_drawable->numBackClipRects = 1; + dri_drawable->pBackClipRects[0].x1 = 0; + dri_drawable->pBackClipRects[0].y1 = 0; + dri_drawable->pBackClipRects[0].x2 = dri_drawable->w; + dri_drawable->pBackClipRects[0].y2 = dri_drawable->h; + + for (i = 0; i < count; i++) { + struct pipe_surface *ps; + enum pipe_format format = 0; + int index = 0; + + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + index = ST_SURFACE_FRONT_LEFT; + switch (buffers[i].cpp) { + case 4: + format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case 2: + format = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + /* FIXME: error */ + return; + } + break; + case __DRI_BUFFER_BACK_LEFT: + index = ST_SURFACE_BACK_LEFT; + switch (buffers[i].cpp) { + case 4: + format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case 2: + format = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + /* FIXME: error */ + return; + } + break; + case __DRI_BUFFER_STENCIL: + case __DRI_BUFFER_DEPTH: + index = ST_SURFACE_DEPTH; + switch (buffers[i].cpp) { + case 4: + format = PIPE_FORMAT_Z24S8_UNORM; + break; + case 2: + format = PIPE_FORMAT_Z16_UNORM; + break; + default: + /* FIXME: error */ + return; + } + break; + case __DRI_BUFFER_ACCUM: + default: + fprintf(stderr, + "unhandled buffer attach event, attacment type %d\n", + buffers[i].attachment); + return; + } + + ps = radeon_surface_from_handle(radeon_context, + buffers[i].name, + format, + dri_drawable->w, + dri_drawable->h, + buffers[i].pitch); + assert(ps); + st_set_framebuffer_surface(radeon_fb->st_framebuffer, index, ps); + } + st_resize_framebuffer(radeon_fb->st_framebuffer, + dri_drawable->w, + dri_drawable->h); +} + +GLboolean radeon_context_create(const __GLcontextModes *visual, + __DRIcontextPrivate *dri_context, + void *shared_context) +{ + __DRIscreenPrivate *dri_screen; + struct radeon_context *radeon_context; + struct radeon_screen *radeon_screen; + struct pipe_context *pipe; + struct st_context *shared_st_context = NULL; + + dri_context->driverPrivate = NULL; + radeon_context = calloc(1, sizeof(struct radeon_context)); + if (radeon_context == NULL) { + return GL_FALSE; + } + + if (shared_context) { + shared_st_context = ((struct radeon_context*)shared_context)->st_context; + } + + dri_screen = dri_context->driScreenPriv; + radeon_screen = dri_screen->private; + radeon_context->dri_screen = dri_screen; + radeon_context->radeon_screen = radeon_screen; + radeon_context->drm_fd = dri_screen->fd; + + radeon_context->pipe_winsys = radeon_pipe_winsys(radeon_screen); + if (radeon_context->pipe_winsys == NULL) { + free(radeon_context); + return GL_FALSE; + } + + if (!getenv("RADEON_SOFTPIPE")) { + fprintf(stderr, "Creating r300 context...\n"); + pipe = + r300_create_context(NULL, + radeon_context->pipe_winsys, + radeon_create_r300_winsys(radeon_context->drm_fd)); + radeon_context->pipe_screen = pipe->screen; + } else { + pipe = radeon_create_softpipe(radeon_context); + } + radeon_context->st_context = st_create_context(pipe, visual, + shared_st_context); + driInitExtensions(radeon_context->st_context->ctx, + radeon_card_extensions, GL_TRUE); + dri_context->driverPrivate = radeon_context; + return GL_TRUE; +} + +void radeon_context_destroy(__DRIcontextPrivate *dri_context) +{ + struct radeon_context *radeon_context; + + radeon_context = dri_context->driverPrivate; + st_finish(radeon_context->st_context); + st_destroy_context(radeon_context->st_context); + free(radeon_context); +} + +GLboolean radeon_context_bind(__DRIcontextPrivate *dri_context, + __DRIdrawablePrivate *dri_drawable, + __DRIdrawablePrivate *dri_readable) +{ + struct radeon_framebuffer *drawable; + struct radeon_framebuffer *readable; + struct radeon_context *radeon_context; + + if (dri_context == NULL) { + st_make_current(NULL, NULL, NULL); + return GL_TRUE; + } + + radeon_context = dri_context->driverPrivate; + drawable = dri_drawable->driverPrivate; + readable = dri_readable->driverPrivate; + st_make_current(radeon_context->st_context, + drawable->st_framebuffer, + readable->st_framebuffer); + + radeon_update_renderbuffers(dri_context, dri_drawable); + if (dri_drawable != dri_readable) { + radeon_update_renderbuffers(dri_context, dri_readable); + } + return GL_TRUE; +} + +GLboolean radeon_context_unbind(__DRIcontextPrivate *dri_context) +{ + struct radeon_context *radeon_context; + + radeon_context = dri_context->driverPrivate; + st_flush(radeon_context->st_context, PIPE_FLUSH_RENDER_CACHE, NULL); + return GL_TRUE; +} diff --git a/src/gallium/winsys/drm/radeon/radeon_context.h b/src/gallium/winsys/drm/radeon/radeon_context.h new file mode 100644 index 0000000000..d7222b4469 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_context.h @@ -0,0 +1,70 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#ifndef RADEON_CONTEXT_H +#define RADEON_CONTEXT_H + +#include "dri_util.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "radeon_screen.h" + +#include "radeon_r300.h" + +struct radeon_framebuffer { + struct st_framebuffer *st_framebuffer; + unsigned attachments; +}; + +struct radeon_context { + /* st */ + struct st_context *st_context; + /* pipe */ + struct pipe_screen *pipe_screen; + struct pipe_winsys *pipe_winsys; + /* DRI */ + __DRIscreenPrivate *dri_screen; + __DRIdrawablePrivate *dri_drawable; + __DRIdrawablePrivate *dri_readable; + /* DRM */ + int drm_fd; + /* RADEON */ + struct radeon_screen *radeon_screen; +}; + +GLboolean radeon_context_create(const __GLcontextModes*, + __DRIcontextPrivate*, + void*); +void radeon_context_destroy(__DRIcontextPrivate*); +GLboolean radeon_context_bind(__DRIcontextPrivate*, + __DRIdrawablePrivate*, + __DRIdrawablePrivate*); +GLboolean radeon_context_unbind(__DRIcontextPrivate*); + +#endif diff --git a/src/gallium/winsys/drm/radeon/radeon_r300.c b/src/gallium/winsys/drm/radeon/radeon_r300.c new file mode 100644 index 0000000000..8fe2375e34 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_r300.c @@ -0,0 +1,96 @@ +/* + * Copyright 2008 Corbin Simpson + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "radeon_r300.h" + +static boolean radeon_r300_check_cs(struct radeon_cs* cs, int size) +{ + /* XXX check size here, lazy ass! */ + return TRUE; +} + +static void radeon_r300_write_cs_reloc(struct radeon_cs* cs, + struct pipe_buffer* pbuffer, + uint32_t rd, + uint32_t wd, + uint32_t flags) +{ + radeon_cs_write_reloc(cs, ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags); +} + +static void radeon_r300_flush_cs(struct radeon_cs* cs) +{ + radeon_cs_emit(cs); + radeon_cs_erase(cs); +} + +/* Helper function to do the ioctls needed for setup and init. */ +static void do_ioctls(struct r300_winsys* winsys, int fd) +{ + drm_radeon_getparam_t gp; + uint32_t target; + int retval; + + /* XXX is this cast safe? */ + gp.value = (int*)⌖ + + /* First, get PCI ID */ + gp.param = RADEON_PARAM_DEVICE_ID; + retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); + if (retval) { + fprintf(stderr, "%s: Failed to get PCI ID, error number %d", + __FUNCTION__, retval); + exit(1); + } + winsys->pci_id = target; + + /* Then, get the number of pixel pipes */ + gp.param = RADEON_PARAM_NUM_GB_PIPES; + retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); + if (retval) { + fprintf(stderr, "%s: Failed to get GB pipe count, error number %d", + __FUNCTION__, retval); + exit(1); + } + winsys->gb_pipes = target; + +} + +struct r300_winsys* radeon_create_r300_winsys(int fd) +{ + struct r300_winsys* winsys = calloc(1, sizeof(struct r300_winsys)); + + do_ioctls(winsys, fd); + + struct radeon_cs_manager* csm = radeon_cs_manager_gem_ctor(fd); + + winsys->cs = radeon_cs_create(csm, 1024 * 64 / 4); + + winsys->check_cs = radeon_r300_check_cs; + winsys->begin_cs = radeon_cs_begin; + winsys->write_cs_dword = radeon_cs_write_dword; + winsys->write_cs_reloc = radeon_r300_write_cs_reloc; + winsys->end_cs = radeon_cs_end; + winsys->flush_cs = radeon_r300_flush_cs; + + return winsys; +} diff --git a/src/gallium/winsys/drm/radeon/radeon_r300.h b/src/gallium/winsys/drm/radeon/radeon_r300.h new file mode 100644 index 0000000000..8ed95a3a9b --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_r300.h @@ -0,0 +1,34 @@ +/* + * Copyright 2008 Corbin Simpson + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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. */ + +/* XXX WTF is this! I shouldn't have to include those first three! FUCK! */ +#include +#include +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_cs.h" + +#include "r300_winsys.h" + +#include "radeon_buffer.h" + +struct r300_winsys* radeon_create_r300_winsys(int fd); diff --git a/src/gallium/winsys/drm/radeon/radeon_screen.c b/src/gallium/winsys/drm/radeon/radeon_screen.c new file mode 100644 index 0000000000..e31caff0bf --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_screen.c @@ -0,0 +1,288 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#include +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "utils.h" +#include "xf86drm.h" +#include "drm.h" +#include "dri_util.h" +#include "radeon_screen.h" +#include "radeon_context.h" +#include "radeon_buffer.h" +#include "radeon_bo.h" +#include "radeon_bo_gem.h" +#include "radeon_drm.h" + +extern const struct dri_extension radeon_card_extensions[]; + +static const __DRIextension *radeon_screen_extensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + NULL +}; + +static __DRIconfig **radeon_fill_in_modes(unsigned pixel_bits, + unsigned depth_bits, + GLboolean have_back_buffer) +{ + __DRIconfig **configs; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + unsigned num_modes; + GLenum fb_format; + GLenum fb_type; + uint8_t depth_bits_array[3]; + uint8_t stencil_bits_array[3]; + uint8_t msaa_samples_array[1]; + /* TODO: pageflipping ? */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + stencil_bits_array[0] = 0; + stencil_bits_array[1] = 0; + if (depth_bits == 24) { + stencil_bits_array[2] = 8; + num_modes = 3; + } + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + depth_bits_array[2] = depth_bits; + depth_buffer_factor = (depth_bits == 24) ? 3 : 2; + + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + msaa_samples_array[0] = 0; + + 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 = (__DRIconfig **)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", + __FILE__, __LINE__); + return NULL; + } + return configs; +} + +static void radeon_screen_destroy(__DRIscreenPrivate *dri_screen) +{ + struct radeon_screen *radeon_screen = (struct radeon_screen*)dri_screen->private; + + radeon_bo_manager_gem_dtor(radeon_screen->bom); + dri_screen = NULL; + free(radeon_screen); +} + +static const __DRIconfig **radeon_screen_init(__DRIscreenPrivate *dri_screen) +{ + struct radeon_screen *radeon_screen; + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, radeon_card_extensions, GL_FALSE); + + radeon_screen = calloc(1, sizeof(struct radeon_screen)); + if (radeon_screen == NULL) { + fprintf(stderr, "\nERROR! Allocating private area failed\n"); + return NULL; + } + dri_screen->private = (void*)radeon_screen; + dri_screen->extensions = radeon_screen_extensions; + radeon_screen->dri_screen = dri_screen; + + radeon_screen->bom = radeon_bo_manager_gem_ctor(dri_screen->fd); + if (radeon_screen->bom == NULL) { + radeon_screen_destroy(dri_screen); + return NULL; + } + + return driConcatConfigs(radeon_fill_in_modes(16, 16, 1), + radeon_fill_in_modes(32, 24, 1)); +} + +static boolean radeon_buffer_create(__DRIscreenPrivate *dri_screen, + __DRIdrawablePrivate *dri_drawable, + const __GLcontextModes *visual, + boolean is_pixmap) +{ + if (is_pixmap) { + /* TODO: implement ? */ + return GL_FALSE; + } else { + enum pipe_format color_format, depth_format, stencil_format; + struct radeon_framebuffer *radeon_fb; + + radeon_fb = calloc(1, sizeof(struct radeon_framebuffer)); + if (radeon_fb == NULL) { + return GL_FALSE; + } + + switch (visual->redBits) { + case 5: + color_format = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + color_format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + } + + switch (visual->depthBits) { + case 24: + depth_format = PIPE_FORMAT_S8Z24_UNORM; + break; + case 16: + depth_format = PIPE_FORMAT_Z16_UNORM; + break; + default: + depth_format = PIPE_FORMAT_NONE; + break; + } + + switch (visual->stencilBits) { + case 8: + /* force depth format */ + depth_format = PIPE_FORMAT_S8Z24_UNORM; + stencil_format = PIPE_FORMAT_S8Z24_UNORM; + break; + default: + stencil_format = PIPE_FORMAT_NONE; + break; + } + + radeon_fb->st_framebuffer = st_create_framebuffer(visual, + color_format, + depth_format, + stencil_format, + dri_drawable->w, + dri_drawable->h, + (void*)radeon_fb); + if (radeon_fb->st_framebuffer == NULL) { + free(radeon_fb); + return GL_FALSE; + } + dri_drawable->driverPrivate = (void *) radeon_fb; + + radeon_fb->attachments = (1 << __DRI_BUFFER_FRONT_LEFT); + if (visual->doubleBufferMode) { + radeon_fb->attachments |= (1 << __DRI_BUFFER_BACK_LEFT); + } + if (visual->depthBits || visual->stencilBits) { + radeon_fb->attachments |= (1 << __DRI_BUFFER_DEPTH); + } + + return GL_TRUE; + } +} + +static void radeon_buffer_destroy(__DRIdrawablePrivate * dri_drawable) +{ + struct radeon_framebuffer *radeon_fb; + + radeon_fb = dri_drawable->driverPrivate; + assert(radeon_fb->st_framebuffer); + st_unreference_framebuffer(radeon_fb->st_framebuffer); + free(radeon_fb); +} + +static void radeon_swap_buffers(__DRIdrawablePrivate *dri_drawable) +{ + struct radeon_framebuffer *radeon_fb; + struct pipe_surface *back_surf = NULL; + + radeon_fb = dri_drawable->driverPrivate; + assert(radeon_fb); + assert(radeon_fb->st_framebuffer); + + st_get_framebuffer_surface(radeon_fb->st_framebuffer, + ST_SURFACE_BACK_LEFT, + &back_surf); + if (back_surf) { + st_notify_swapbuffers(radeon_fb->st_framebuffer); + /* TODO: do we want to do anythings ? */ + st_notify_swapbuffers_complete(radeon_fb->st_framebuffer); + } +} + +/** + * Called via glXCopySubBufferMESA() to copy a subrect of the back + * buffer to the front buffer/screen. + */ +static void radeon_copy_sub_buffer(__DRIdrawablePrivate *dri_drawable, + int x, int y, int w, int h) +{ + /* TODO: ... */ +} + +const struct __DriverAPIRec driDriverAPI = { + .InitScreen = NULL, + .DestroyScreen = radeon_screen_destroy, + .CreateContext = radeon_context_create, + .DestroyContext = radeon_context_destroy, + .CreateBuffer = radeon_buffer_create, + .DestroyBuffer = radeon_buffer_destroy, + .SwapBuffers = radeon_swap_buffers, + .MakeCurrent = radeon_context_bind, + .UnbindContext = radeon_context_unbind, + .CopySubBuffer = radeon_copy_sub_buffer, + .InitScreen2 = radeon_screen_init, +}; diff --git a/src/gallium/winsys/drm/radeon/radeon_screen.h b/src/gallium/winsys/drm/radeon/radeon_screen.h new file mode 100644 index 0000000000..01b7fa6531 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_screen.h @@ -0,0 +1,41 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#ifndef RADEON_SCREEN_H +#define RADEON_SCREEN_H + +#include "dri_util.h" +#include "radeon_bo.h" + +struct radeon_screen { + __DRIscreenPrivate *dri_screen; + struct radeon_bo_manager *bom; +}; + +#endif diff --git a/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.c b/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.c new file mode 100644 index 0000000000..8402e1fa5a --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.c @@ -0,0 +1,77 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ +#include +#include "imports.h" +#include "pipe/p_defines.h" +#include "pipe/p_format.h" +#include "softpipe/sp_winsys.h" +#include "radeon_context.h" +#include "radeon_winsys_softpipe.h" + +struct radeon_softpipe_winsys { + struct softpipe_winsys sp_winsys; + struct radeon_context *radeon_context; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean radeon_is_format_supported(struct softpipe_winsys *sws, uint format) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + }; + return FALSE; +} + +struct pipe_context *radeon_create_softpipe(struct radeon_context *radeon_context) +{ + struct radeon_softpipe_winsys *radeon_sp_ws; + struct pipe_screen *pipe_screen; + + pipe_screen = softpipe_create_screen(radeon_context->pipe_winsys); + + radeon_sp_ws = CALLOC_STRUCT(radeon_softpipe_winsys); + if (radeon_sp_ws == NULL) { + return NULL; + } + radeon_context->pipe_screen = pipe_screen; + radeon_sp_ws->radeon_context = radeon_context; + radeon_sp_ws->sp_winsys.is_format_supported = radeon_is_format_supported; + return softpipe_create(pipe_screen, + radeon_context->pipe_winsys, + &radeon_sp_ws->sp_winsys); +} diff --git a/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.h b/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.h new file mode 100644 index 0000000000..519eab769c --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.h @@ -0,0 +1,37 @@ +/* + * 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 + * 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 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 + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * J茅r么me Glisse + */ +#ifndef RADEON_WINSYS_SOFTPIPE_H +#define RADEON_WINSYS_SOFTPIPE_H + +#include "radeon_context.h" + +struct pipe_context *radeon_create_softpipe(struct radeon_context *radeon_context); + +#endif -- cgit v1.2.3 From b59117a697ac168da9dacb922d491449fe591264 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 7 Feb 2009 13:02:27 -0700 Subject: cell: compile fix: no-op xlib_create_brw_screen() for Cell build --- src/gallium/winsys/xlib/xlib_brw_screen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c index 51740a9af6..8e1bfab2f5 100644 --- a/src/gallium/winsys/xlib/xlib_brw_screen.c +++ b/src/gallium/winsys/xlib/xlib_brw_screen.c @@ -325,6 +325,7 @@ xlib_create_brw_winsys( void ) static struct pipe_screen * xlib_create_brw_screen( void ) { +#ifndef GALLIUM_CELL struct pipe_winsys *winsys; struct pipe_screen *screen; @@ -342,6 +343,7 @@ fail: if (winsys) winsys->destroy( winsys ); +#endif return NULL; } -- cgit v1.2.3 From 2438161823630a6e647c105ad92cf2b0cd740d00 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 9 Feb 2009 10:37:38 -0700 Subject: mesa: build/use libmesagallium.a for gallium builds This contains the core mesa code but excludes things not needed for gallium such as tnl/, swrast/, swrast_setup/, etc. --- src/gallium/winsys/drm/Makefile.template | 4 ++-- src/gallium/winsys/egl_xlib/Makefile | 2 +- src/gallium/winsys/xlib/Makefile | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template index 211f4d875e..6756640c4e 100644 --- a/src/gallium/winsys/drm/Makefile.template +++ b/src/gallium/winsys/drm/Makefile.template @@ -1,9 +1,9 @@ # -*-makefile-*- MESA_MODULES = \ - $(TOP)/src/mesa/libmesa.a \ + $(TOP)/src/mesa/libmesagallium.a \ $(GALLIUM_AUXILIARIES) - + COMMON_GALLIUM_SOURCES = \ $(TOP)/src/mesa/drivers/dri/common/utils.c \ $(TOP)/src/mesa/drivers/dri/common/vblank.c \ diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile index 76f1b56da4..02ac47caa4 100644 --- a/src/gallium/winsys/egl_xlib/Makefile +++ b/src/gallium/winsys/egl_xlib/Makefile @@ -34,7 +34,7 @@ LIBS = \ # mesa code, as done for ES 1.x, 2.x, OpenVG, etc) UNUSED_LIBS = \ $(TOP)/src/mesa/libglapi.a \ - $(TOP)/src/mesa/libmesa.a \ + $(TOP)/src/mesa/libmesagallium.a \ LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1 diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 8c2892d49b..9d70f3cb9c 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -47,7 +47,7 @@ LIBS = \ $(GALLIUM_DRIVERS) \ $(TOP)/src/gallium/state_trackers/glx/xlib/libxlib.a \ $(TOP)/src/mesa/libglapi.a \ - $(TOP)/src/mesa/libmesa.a \ + $(TOP)/src/mesa/libmesagallium.a \ $(GALLIUM_AUXILIARIES) \ $(CELL_SPU_LIB) \ -- cgit v1.2.3 From 43e6272ae5c03f663cfdd98f35b0b0028bc5d252 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 10 Feb 2009 16:23:02 +0100 Subject: gallium: Introduce new subdirs build variables (based on gallium-xorg-driver/commit 270ce504052d415870a25ab59818b2309eb8ac13) --- src/gallium/winsys/drm/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/Makefile b/src/gallium/winsys/drm/Makefile index f466ce6c3c..d2af5705f0 100644 --- a/src/gallium/winsys/drm/Makefile +++ b/src/gallium/winsys/drm/Makefile @@ -1,10 +1,10 @@ -# src/mesa/drivers/dri/Makefile +# src/gallium/winsys/drm/Makefile TOP = ../../../.. include $(TOP)/configs/current - +SUBDIRS = $(GALLIUM_WINSYS_DRM_DIRS) default: $(TOP)/$(LIB_DIR) subdirs @@ -14,7 +14,7 @@ $(TOP)/$(LIB_DIR): subdirs: - @for dir in $(DRI_DIRS) ; do \ + @for dir in $(SUBDIRS) ; do \ if [ -d $$dir ] ; then \ (cd $$dir && $(MAKE)) || exit 1 ; \ fi \ @@ -22,7 +22,7 @@ subdirs: install: - @for dir in $(DRI_DIRS) ; do \ + @for dir in $(SUBDIRS) ; do \ if [ -d $$dir ] ; then \ (cd $$dir && $(MAKE) install) || exit 1 ; \ fi \ @@ -30,7 +30,7 @@ install: clean: - @for dir in $(DRI_DIRS) ; do \ + @for dir in $(SUBDIRS) ; do \ if [ -d $$dir ] ; then \ (cd $$dir && $(MAKE) clean) ; \ fi \ -- cgit v1.2.3 From 94665aa648f8b9015f9eabdddad092b006faf70a Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 10 Feb 2009 16:16:15 +0100 Subject: gallium: Install DRI drivers into lib/gallium --- src/gallium/winsys/drm/Makefile | 6 +++--- src/gallium/winsys/drm/Makefile.template | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/Makefile b/src/gallium/winsys/drm/Makefile index d2af5705f0..a84fcd8418 100644 --- a/src/gallium/winsys/drm/Makefile +++ b/src/gallium/winsys/drm/Makefile @@ -6,11 +6,11 @@ include $(TOP)/configs/current SUBDIRS = $(GALLIUM_WINSYS_DRM_DIRS) -default: $(TOP)/$(LIB_DIR) subdirs +default: $(TOP)/$(LIB_DIR)/gallium subdirs -$(TOP)/$(LIB_DIR): - -mkdir $(TOP)/$(LIB_DIR) +$(TOP)/$(LIB_DIR)/gallium: + -mkdir -p $(TOP)/$(LIB_DIR)/gallium subdirs: diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template index 6756640c4e..cccf8abdfd 100644 --- a/src/gallium/winsys/drm/Makefile.template +++ b/src/gallium/winsys/drm/Makefile.template @@ -79,7 +79,7 @@ SHARED_INCLUDES = \ ##### TARGETS ##### -default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR)/$(LIBNAME_EGL) +default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME_EGL) $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template @@ -93,11 +93,11 @@ $(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS) $(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \ --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive $(DRIVER_EXTRAS) -$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) - $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) +$(TOP)/$(LIB_DIR)/gallium/$(LIBNAME): $(LIBNAME) + $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR)/gallium -$(TOP)/$(LIB_DIR)/$(LIBNAME_EGL): $(LIBNAME_EGL) - $(INSTALL) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR) +$(TOP)/$(LIB_DIR)/gallium/$(LIBNAME_EGL): $(LIBNAME_EGL) + $(INSTALL) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR)/gallium depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) rm -f depend -- cgit v1.2.3 From 1789dc8015d75b996a546a94f88d8cdaa3c7e8c4 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 10 Feb 2009 16:17:32 +0100 Subject: gallium: Don't rebuild common drm code --- src/gallium/winsys/drm/intel/gem/Makefile.template | 6 +++--- src/gallium/winsys/drm/nouveau/common/Makefile.template | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/drm/intel/gem/Makefile.template b/src/gallium/winsys/drm/intel/gem/Makefile.template index 557070ae02..b60e978894 100644 --- a/src/gallium/winsys/drm/intel/gem/Makefile.template +++ b/src/gallium/winsys/drm/intel/gem/Makefile.template @@ -36,11 +36,11 @@ INCLUDES = \ ##### TARGETS ##### -default: depend symlinks $(LIBNAME) +default: depend symlinks lib$(LIBNAME).a -$(LIBNAME): $(OBJECTS) Makefile Makefile.template - $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) +lib$(LIBNAME).a: $(OBJECTS) Makefile Makefile.template + $(TOP)/bin/mklib -o $(LIBNAME) -static $(OBJECTS) $(DRIVER_LIBS) depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) diff --git a/src/gallium/winsys/drm/nouveau/common/Makefile.template b/src/gallium/winsys/drm/nouveau/common/Makefile.template index e40836e0a8..f0d098bb1c 100644 --- a/src/gallium/winsys/drm/nouveau/common/Makefile.template +++ b/src/gallium/winsys/drm/nouveau/common/Makefile.template @@ -31,11 +31,11 @@ INCLUDES = \ ##### TARGETS ##### -default: depend symlinks $(LIBNAME) +default: depend symlinks lib$(LIBNAME).a -$(LIBNAME): $(OBJECTS) Makefile Makefile.template - $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) +lib$(LIBNAME).a: $(OBJECTS) Makefile Makefile.template + $(TOP)/bin/mklib -o $(LIBNAME) -static $(OBJECTS) $(DRIVER_LIBS) depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) -- cgit v1.2.3 From 767b1acbb757186bde30973394f256ab7498a075 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 10 Feb 2009 17:43:25 +0100 Subject: mesa: Build both software rasterizers for debug But put the gallium one in lib/gallium --- src/gallium/winsys/xlib/Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 9d70f3cb9c..bb187cc14a 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -62,15 +62,17 @@ LIBS = \ -default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) +default: $(TOP)/$(LIB_DIR)/gallium $(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME) +$(TOP)/$(LIB_DIR)/gallium: + @ mkdir -p $(TOP)/$(LIB_DIR)/gallium # Make the libGL.so library -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) Makefile +$(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) Makefile $(TOP)/bin/mklib -o $(GL_LIB) \ -linker "$(CC)" \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ - -install $(TOP)/$(LIB_DIR) \ + -install $(TOP)/$(LIB_DIR)/gallium \ $(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \ --start-group $(LIBS) --end-group $(GL_LIB_DEPS) -- cgit v1.2.3