nouveau: Factor out common winsys bits into libnouveaudrm.a
authorYounes Manton <younes.m@gmail.com>
Sat, 10 Jan 2009 18:30:29 +0000 (13:30 -0500)
committerYounes Manton <younes.m@gmail.com>
Sat, 10 Jan 2009 18:52:07 +0000 (13:52 -0500)
71 files changed:
src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c
src/gallium/winsys/drm/nouveau/Makefile
src/gallium/winsys/drm/nouveau/common/Makefile [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/Makefile.template [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_bo.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_channel.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_context.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_context.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_device.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_dma.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_dma.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_dri.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_fence.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_local.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_lock.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_resource.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_screen.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_screen.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nv04_surface.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/common/nv50_surface.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/Makefile [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/nouveau_bo.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_channel.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_context.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_context.h [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_device.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_dma.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_dma.h [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_dri.h [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_drmif.h [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_fence.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_grobj.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_local.h [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_lock.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_notifier.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_resource.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_screen.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_screen.h [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_winsys.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h [deleted file]
src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c [deleted file]
src/gallium/winsys/drm/nouveau/nv04_surface.c [deleted file]
src/gallium/winsys/drm/nouveau/nv50_surface.c [deleted file]
src/gallium/winsys/g3dvl/nouveau/Makefile
src/gallium/winsys/g3dvl/nouveau/nouveau_context.c [deleted file]
src/gallium/winsys/g3dvl/nouveau/nouveau_context.h [deleted file]
src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.c [new file with mode: 0644]
src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.h [new file with mode: 0644]
src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c [deleted file]
src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h [deleted file]
src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c [new file with mode: 0644]
src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.h [new file with mode: 0644]
src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c

index fcea899ef9ca21952e60d71fbec08865e5e3ceec..c5a73b2bf2a5d6fab1f43ecd54421df582297a03 100644 (file)
@@ -17,7 +17,7 @@
 #include "vl_types.h"
 #include "vl_defs.h"
 
-const unsigned int DEFAULT_BUF_ALIGNMENT = 256;
+const unsigned int DEFAULT_BUF_ALIGNMENT = 1;
 
 enum vlMacroBlockTypeEx
 {
@@ -394,7 +394,7 @@ static inline int vlGrabMacroBlock
                (vb)[5].cr_tc.x = (zb)[2].x + (hx);     (vb)[5].cr_tc.y = (zb)[2].y + (hy);                                     \
        }
 
-static inline int vlGrabMacroBlockVB
+static inline int vlGenMacroblockVerts
 (
        struct vlR16SnormBufferedMC *mc,
        struct vlMpeg2MacroBlock *macroblock,
@@ -618,7 +618,7 @@ static int vlFlush
                {
                        enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]);
 
-                       vlGrabMacroBlockVB(mc, &mc->macroblocks[i], offset[mb_type_ex], ycbcr_vb, ref_vb);
+                       vlGenMacroblockVerts(mc, &mc->macroblocks[i], offset[mb_type_ex], ycbcr_vb, ref_vb);
 
                        offset[mb_type_ex]++;
                }
@@ -627,7 +627,7 @@ static int vlFlush
                for (i = 0; i < 2; ++i)
                        mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs.ref[i].buffer);
        }
-       
+
        for (i = 0; i < 3; ++i)
        {
                pipe_surface_unmap(mc->tex_surface[i]);
@@ -757,7 +757,7 @@ static int vlFlush
        }
 
        pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &mc->buffered_surface->render_fence);
-       pipe->screen->tex_surface_release(pipe->screen, mc->render_target.cbufs[0]);
+       pipe->screen->tex_surface_release(pipe->screen, &mc->render_target.cbufs[0]);
 
        for (i = 0; i < 3; ++i)
                mc->zero_block[i].x = -1.0f;
index 81562ca78d3224b6c46a5fb2d8f429f5a32be29a..b5735329ec7ea8711971a60a1d6e512f86dd1f36 100644 (file)
@@ -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 (file)
index 0000000..06f5589
--- /dev/null
@@ -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 (file)
index 0000000..e40836e
--- /dev/null
@@ -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 (file)
index 0000000..76b98be
--- /dev/null
@@ -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 <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+#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 (file)
index 0000000..b729813
--- /dev/null
@@ -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 <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <util/u_memory.h>
+#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 (file)
index 0000000..2f24504
--- /dev/null
@@ -0,0 +1,262 @@
+#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"
+
+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 (file)
index 0000000..b1bdb01
--- /dev/null
@@ -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 (file)
index 0000000..92b57b8
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <util/u_memory.h>
+#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 (file)
index 0000000..f8a8ba0
--- /dev/null
@@ -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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+
+#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 (file)
index 0000000..cfa6d26
--- /dev/null
@@ -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 <string.h>
+#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 (file)
index 0000000..1207c2d
--- /dev/null
@@ -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 (file)
index 0000000..5f72800
--- /dev/null
@@ -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 <stdint.h>
+#include <xf86drm.h>
+#include <nouveau_drm.h>
+
+#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 (file)
index 0000000..e7b0b4f
--- /dev/null
@@ -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 <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+#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 (file)
index 0000000..fb430a2
--- /dev/null
@@ -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 <stdlib.h>
+#include <errno.h>
+#include <util/u_memory.h>
+#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 (file)
index 0000000..877c7a8
--- /dev/null
@@ -0,0 +1,115 @@
+#ifndef __NOUVEAU_LOCAL_H__
+#define __NOUVEAU_LOCAL_H__
+
+#include "pipe/p_compiler.h"
+#include "nouveau_winsys_pipe.h"
+#include <stdio.h>
+
+/* 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 (file)
index 0000000..e8cf051
--- /dev/null
@@ -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 <pipe/p_thread.h>
+#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 (file)
index 0000000..01e8f38
--- /dev/null
@@ -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 <stdlib.h>
+#include <errno.h>
+
+#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 (file)
index 0000000..7c094eb
--- /dev/null
@@ -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 <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <util/u_memory.h>
+#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 (file)
index 0000000..766fd27
--- /dev/null
@@ -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 <stdlib.h>
+#include <errno.h>
+#include <util/u_memory.h>
+#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 (file)
index 0000000..422fbf0
--- /dev/null
@@ -0,0 +1,31 @@
+#include <util/u_memory.h>
+#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 (file)
index 0000000..3e68e21
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef __NOUVEAU_SCREEN_H__
+#define __NOUVEAU_SCREEN_H__
+
+#include <stdint.h>
+
+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 (file)
index 0000000..364340e
--- /dev/null
@@ -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 (file)
index 0000000..6895137
--- /dev/null
@@ -0,0 +1,229 @@
+#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_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 (file)
index 0000000..14c7286
--- /dev/null
@@ -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 (file)
index 0000000..04def60
--- /dev/null
@@ -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 <keithw-at-tungstengraphics-dot-com>
+ */
+
+#include <pipe/p_winsys.h>
+#include <pipe/p_screen.h>
+#include <pipe/p_defines.h>
+#include <pipe/p_format.h>
+#include <softpipe/sp_winsys.h>
+#include <util/u_memory.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;
+       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 (file)
index 0000000..e9a8a2a
--- /dev/null
@@ -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 (file)
index 0000000..c8ab7f6
--- /dev/null
@@ -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 (file)
index 0000000..e129e42
--- /dev/null
@@ -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 (file)
index 0000000..006978b
--- /dev/null
@@ -0,0 +1,124 @@
+#include <main/glheader.h>
+#include <glapi/glthread.h>
+#include <GL/internal/glcore.h>
+#include <utils.h>
+
+#include <state_tracker/st_public.h>
+#include <state_tracker/st_context.h>
+#include <pipe/p_defines.h>
+#include <pipe/p_context.h>
+#include <pipe/p_screen.h>
+
+#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 (file)
index 0000000..8257790
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef __NOUVEAU_CONTEXT_DRI_H__
+#define __NOUVEAU_CONTEXT_DRI_H__
+
+#include <dri_util.h>
+#include <xmlconfig.h>
+#include <nouveau/nouveau_winsys.h>
+#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 (file)
index 0000000..1d7c923
--- /dev/null
@@ -0,0 +1,259 @@
+#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_drm.h>
+#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 (file)
index 0000000..1498087
--- /dev/null
@@ -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 (file)
index 0000000..38461b2
--- /dev/null
@@ -0,0 +1,112 @@
+#include <main/glheader.h>
+#include <glapi/glthread.h>
+#include <GL/internal/glcore.h>
+
+#include <pipe/p_context.h>
+#include <state_tracker/st_public.h>
+#include <state_tracker/st_context.h>
+#include <state_tracker/st_cb_fbo.h>
+
+#include "../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 (file)
index 0000000..825d3da
--- /dev/null
@@ -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 (file)
index 76b98be..0000000
+++ /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 <stdint.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-
-#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 (file)
index b7127f8..0000000
+++ /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 <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#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 (file)
index 74413c4..0000000
+++ /dev/null
@@ -1,346 +0,0 @@
-#include "main/glheader.h"
-#include "glapi/glthread.h"
-#include <GL/internal/glcore.h>
-#include "utils.h"
-
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
-#include "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 (file)
index 77e2147..0000000
+++ /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 (file)
index 0b452fc..0000000
+++ /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 <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#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 (file)
index f8a8ba0..0000000
+++ /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 <stdint.h>
-#include <assert.h>
-#include <errno.h>
-
-#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 (file)
index cfa6d26..0000000
+++ /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 <string.h>
-#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 (file)
index 1207c2d..0000000
+++ /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 (file)
index 5f72800..0000000
+++ /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 <stdint.h>
-#include <xf86drm.h>
-#include <nouveau_drm.h>
-
-#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 (file)
index e7b0b4f..0000000
+++ /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 <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-
-#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 (file)
index 5152389..0000000
+++ /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 <stdlib.h>
-#include <errno.h>
-
-#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 (file)
index e878a40..0000000
+++ /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 <stdio.h>
-
-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 (file)
index 9adb9ac..0000000
+++ /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 <GL/internal/glcore.h>
-
-#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 (file)
index 01e8f38..0000000
+++ /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 <stdlib.h>
-#include <errno.h>
-
-#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 (file)
index 815046b..0000000
+++ /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 <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-
-#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 (file)
index 3bbcb5c..0000000
+++ /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 <stdlib.h>
-#include <errno.h>
-
-#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 (file)
index c6d0c53..0000000
+++ /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 (file)
index 388d6be..0000000
+++ /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 (file)
index 70e0104..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-#include "main/glheader.h"
-#include "glapi/glthread.h"
-#include <GL/internal/glcore.h>
-
-#include "pipe/p_context.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_cb_fbo.h"
-
-#include "nouveau_context.h"
-#include "nouveau_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 (file)
index 825d3da..0000000
+++ /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 (file)
index 364340e..0000000
+++ /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 (file)
index fe10479..0000000
+++ /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 (file)
index 6a03ac0..0000000
+++ /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 (file)
index 68aade8..0000000
+++ /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 <keithw-at-tungstengraphics-dot-com>
- */
-
-#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 (file)
index e9a8a2a..0000000
+++ /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 (file)
index c8ab7f6..0000000
+++ /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;
-}
-
index ff43327778a8fc4c20a2d23649fea6b14d534f95..22d925b643669988d5ec4257a60e7910274f01cf 100644 (file)
@@ -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 (file)
index 06a61fc..0000000
+++ /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 (file)
index 395a3ab..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef __NOUVEAU_CONTEXT_H__
-#define __NOUVEAU_CONTEXT_H__
-
-/*#include "xmlconfig.h"*/
-
-#include <driclient.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 {
-       /* 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 (file)
index 0000000..dfc4905
--- /dev/null
@@ -0,0 +1,172 @@
+#include "nouveau_context_vl.h"
+#include <pipe/p_defines.h>
+#include <pipe/p_context.h>
+#include <pipe/p_screen.h>
+#include <util/u_memory.h>
+#include <common/nouveau_dri.h>
+#include <common/nouveau_local.h>
+#include <common/nouveau_winsys_pipe.h>
+#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 (file)
index 0000000..1115c31
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef __NOUVEAU_CONTEXT_VL_H__
+#define __NOUVEAU_CONTEXT_VL_H__
+
+#include <driclient.h>
+#include <nouveau/nouveau_winsys.h>
+#include <common/nouveau_context.h>
+
+/*#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 (file)
index f80d000..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#include "pipe/p_context.h"
-#include "util/u_memory.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_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 (file)
index 8a58bb7..0000000
+++ /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 (file)
index 0000000..658dafd
--- /dev/null
@@ -0,0 +1,88 @@
+#include "nouveau_screen_vl.h"
+#include <util/u_memory.h>
+#include <nouveau_drm.h>
+#include <common/nouveau_dri.h>
+#include <common/nouveau_local.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_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 (file)
index 0000000..0c1ceca
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __NOUVEAU_SCREEN_VL_H__
+#define __NOUVEAU_SCREEN_VL_H__
+
+#include <driclient.h>
+#include <common/nouveau_screen.h>
+
+/* 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
index 7916c8061519b5c61bbd6846975b7610b384e844..16e6d5543cbc04b95f39c36b4c4ccce5abc859c1 100644 (file)
@@ -1,26 +1,26 @@
-#include "pipe/p_context.h"
-#include "nouveau_context.h"
-#include "nouveau_local.h"
-#include "nouveau_screen.h"
+#include <driclient.h>
+#include <common/nouveau_local.h>
+#include <common/nouveau_screen.h>
+#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);
+}