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)
44 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 [moved from src/gallium/winsys/drm/nouveau/nouveau_bo.c with 100% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_channel.c [moved from src/gallium/winsys/drm/nouveau/nouveau_channel.c with 95% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_context.c [moved from src/gallium/winsys/drm/nouveau/nouveau_context.c with 65% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_context.h [moved from src/gallium/winsys/drm/nouveau/nouveau_context.h with 67% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_device.c [moved from src/gallium/winsys/drm/nouveau/nouveau_device.c with 97% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_dma.c [moved from src/gallium/winsys/drm/nouveau/nouveau_dma.c with 100% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_dma.h [moved from src/gallium/winsys/drm/nouveau/nouveau_dma.h with 100% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_dri.h [moved from src/gallium/winsys/drm/nouveau/nouveau_dri.h with 100% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h [moved from src/gallium/winsys/drm/nouveau/nouveau_drmif.h with 100% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_fence.c [moved from src/gallium/winsys/drm/nouveau/nouveau_fence.c with 100% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c [moved from src/gallium/winsys/drm/nouveau/nouveau_grobj.c with 95% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_local.h [moved from src/gallium/winsys/drm/nouveau/nouveau_local.h with 99% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_lock.c [moved from src/gallium/winsys/drm/nouveau/nouveau_lock.c with 68% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c [moved from src/gallium/winsys/drm/nouveau/nouveau_notifier.c with 100% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c [moved from src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c with 98% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_resource.c [moved from src/gallium/winsys/drm/nouveau/nouveau_resource.c with 95% similarity]
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 [moved from src/gallium/winsys/drm/nouveau/nouveau_winsys.c with 100% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c [moved from src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c with 75% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h [moved from src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h with 80% similarity]
src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c [moved from src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c with 81% similarity]
src/gallium/winsys/drm/nouveau/common/nv04_surface.c [moved from src/gallium/winsys/drm/nouveau/nv04_surface.c with 100% similarity]
src/gallium/winsys/drm/nouveau/common/nv50_surface.c [moved from src/gallium/winsys/drm/nouveau/nv50_surface.c with 100% similarity]
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 [moved from src/gallium/winsys/drm/nouveau/nouveau_screen.c with 88% similarity]
src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c [moved from src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c with 52% similarity]
src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h [moved from src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h with 100% similarity]
src/gallium/winsys/drm/nouveau/nouveau_screen.h [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_vl.c [moved from src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c with 67% similarity]
src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.h [moved from src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h with 54% similarity]
src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c

index fcea899..c5a73b2 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 81562ca..b573532 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
@@ -23,7 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-
+#include <util/u_memory.h>
 #include "nouveau_drmif.h"
 #include "nouveau_dma.h"
 
@@ -38,7 +38,7 @@ nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma,
        if (!nvdev || !chan || *chan)
            return -EINVAL;
 
-       nvchan = calloc(1, sizeof(struct nouveau_channel_priv));
+       nvchan = CALLOC_STRUCT(nouveau_channel_priv);
        if (!nvchan)
                return -ENOMEM;
        nvchan->base.device = dev;
@@ -48,7 +48,7 @@ nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma,
        ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
                                  &nvchan->drm, sizeof(nvchan->drm));
        if (ret) {
-               free(nvchan);
+               FREE(nvchan);
                return ret;
        }
 
@@ -111,18 +111,16 @@ nouveau_channel_free(struct nouveau_channel **chan)
        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);
+       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);
+       FREE(nvchan);
 }
-
-
@@ -1,28 +1,13 @@
-#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 <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
-
 static void
 nouveau_channel_context_destroy(struct nouveau_channel_context *nvc)
 {
@@ -87,24 +72,17 @@ nouveau_channel_context_create(struct nouveau_device *dev)
        return nvc;
 }
 
-GLboolean
-nouveau_context_create(const __GLcontextModes *glVis,
-                      __DRIcontextPrivate *driContextPriv,
-                      void *sharedContextPrivate)
+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)
 {
-       __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:
@@ -121,27 +99,18 @@ nouveau_context_create(const __GLcontextModes *glVis,
                break;
        default:
                NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset);
-               return GL_FALSE;
+               return 1;
        }
 
-       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;
+               nvdev->ctx  = hHWContext;
+               nvdev->lock = 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.
@@ -185,12 +154,8 @@ nouveau_context_create(const __GLcontextModes *glVis,
         * a single process.
         */
        nvc = nv_screen->nvc;
-       if (!nvc && st_share) {
-               struct nouveau_context *snv = st_share->pipe->priv;
-               if (snv) {
-                       nvc = snv->nvc;
-               }
-       }
+       if (!nvc && nv_share)
+               nvc = nv_share->nvc;
 
        /*XXX: temporary - disable multi-context/single-channel on pre-NV4x */
        switch (dev->chipset & 0xf0) {
@@ -211,7 +176,7 @@ nouveau_context_create(const __GLcontextModes *glVis,
                nvc = nouveau_channel_context_create(dev);
                if (!nvc) {
                        NOUVEAU_ERR("Failed initialising GPU context\n");
-                       return GL_FALSE;
+                       return 1;
                }
                nv_screen->nvc = nvc;
        }
@@ -241,11 +206,11 @@ nouveau_context_create(const __GLcontextModes *glVis,
        case 0x80:
        case 0x90:
                if (nouveau_surface_init_nv50(nv))
-                       return GL_FALSE;
+                       return 1;
                break;
        default:
                if (nouveau_surface_init_nv04(nv))
-                       return GL_FALSE;
+                       return 1;
                break;
        }
 
@@ -268,26 +233,22 @@ nouveau_context_create(const __GLcontextModes *glVis,
                pipe = nouveau_create_softpipe(nv);
                if (!pipe) {
                        NOUVEAU_ERR("Error creating pipe, bailing\n");
-                       return GL_FALSE;
+                       return 1;
                }
        }
 
        pipe->priv = nv;
-       nv->st = st_create_context(pipe, glVis, st_share);
-       return GL_TRUE;
+
+       return 0;
 }
 
 void
-nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
+nouveau_context_cleanup(struct nouveau_context *nv)
 {
-       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) {
@@ -295,52 +256,7 @@ nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
                        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;
+       
+       /* XXX: Who cleans up the pipe? */
 }
 
@@ -1,17 +1,10 @@
 #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;
@@ -41,16 +34,7 @@ struct nouveau_channel_context {
 };
 
 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;
+       int locked;
        struct nouveau_screen *nv_screen;
        struct pipe_surface *frontbuffer;
 
@@ -76,26 +60,11 @@ struct nouveau_context {
                            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 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 *);
@@ -110,4 +79,8 @@ 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
@@ -23,7 +23,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
-
+#include <util/u_memory.h>
 #include "nouveau_drmif.h"
 
 int
@@ -36,7 +36,7 @@ nouveau_device_open_existing(struct nouveau_device **dev, int close,
        if (!dev || *dev)
            return -EINVAL;
 
-       nvdev = calloc(1, sizeof(*nvdev));
+       nvdev = CALLOC_STRUCT(nouveau_device_priv);
        if (!nvdev)
            return -ENOMEM;
        nvdev->fd = fd;
@@ -112,7 +112,7 @@ nouveau_device_close(struct nouveau_device **dev)
                drmDestroyContext(nvdev->fd, nvdev->ctx);
                drmClose(nvdev->fd);
        }
-       free(nvdev);
+       FREE(nvdev);
 }
 
 int
@@ -22,7 +22,7 @@
 
 #include <stdlib.h>
 #include <errno.h>
-
+#include <util/u_memory.h>
 #include "nouveau_drmif.h"
 
 int
@@ -37,7 +37,7 @@ nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle,
        if (!nvdev || !grobj || *grobj)
                return -EINVAL;
 
-       nvgrobj = calloc(1, sizeof(*nvgrobj));
+       nvgrobj = CALLOC_STRUCT(nouveau_grobj_priv);
        if (!nvgrobj)
                return -ENOMEM;
        nvgrobj->base.channel = chan;
@@ -67,7 +67,7 @@ nouveau_grobj_ref(struct nouveau_channel *chan, uint32_t handle,
        if (!chan || !grobj || *grobj)
                return -EINVAL;
 
-       nvgrobj = calloc(1, sizeof(struct nouveau_grobj_priv));
+       nvgrobj = CALLOC_STRUCT(nouveau_grobj_priv);
        if (!nvgrobj)
                return -ENOMEM;
        nvgrobj->base.channel = chan;
@@ -102,6 +102,6 @@ nouveau_grobj_free(struct nouveau_grobj **grobj)
                drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE,
                                &f, sizeof(f)); 
        }
-       free(nvgrobj);
+       FREE(nvgrobj);
 }
 
@@ -5,8 +5,6 @@
 #include "nouveau_winsys_pipe.h"
 #include <stdio.h>
 
-struct pipe_buffer;
-
 /* Debug output */
 #define NOUVEAU_MSG(fmt, args...) do {                                         \
        fprintf(stdout, "nouveau: "fmt, ##args);                               \
  * 
  **************************************************************************/
 
-#include "main/glheader.h"
-#include "glapi/glthread.h"
-#include <GL/internal/glcore.h>
-
+#include <pipe/p_thread.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);
-}
+pipe_static_mutex(lockMutex);
 
 /* Lock the hardware and validate our state.
  */
@@ -64,20 +41,21 @@ LOCK_HARDWARE(struct nouveau_context *nv)
        struct nouveau_device_priv *nvdev = nouveau_device(dev);
        char __ret=0;
 
-       _glthread_LOCK_MUTEX(lockMutex);
        assert(!nv->locked);
-       
+       pipe_mutex_lock(lockMutex);
+
        DRM_CAS(nvdev->lock, nvdev->ctx,
                (DRM_LOCK_HELD | nvdev->ctx), __ret);
-       
-       if (__ret)
-               nouveau_contended_lock(nv, 0);
-       nv->locked = GL_TRUE;
-}
 
+       if (__ret) {
+               drmGetLock(nvdev->fd, nvdev->ctx, 0);
+               nouveau_contended_lock(nv);
+       }
+       nv->locked = 1;
+}
 
-  /* Unlock the hardware using the global current context 
  */
+/* Unlock the hardware using the global current context 
+ */
 void
 UNLOCK_HARDWARE(struct nouveau_context *nv)
 {
@@ -86,9 +64,9 @@ UNLOCK_HARDWARE(struct nouveau_context *nv)
        struct nouveau_device_priv *nvdev = nouveau_device(dev);
 
        assert(nv->locked);
-       nv->locked = GL_FALSE;
+       nv->locked = 0;
 
        DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx);
 
-       _glthread_UNLOCK_MUTEX(lockMutex);
+       pipe_mutex_unlock(lockMutex);
 } 
@@ -23,7 +23,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <assert.h>
-
+#include <util/u_memory.h>
 #include "nouveau_drmif.h"
 #include "nouveau_dma.h"
 
@@ -97,9 +97,9 @@ nouveau_pushbuf_init(struct nouveau_channel *chan)
        nouveau_pushbuf_space(chan, 0);
        chan->pushbuf = &nvchan->pb.base;
 
-       nvchan->pb.buffers = calloc(NOUVEAU_PUSHBUF_MAX_BUFFERS,
+       nvchan->pb.buffers = CALLOC(NOUVEAU_PUSHBUF_MAX_BUFFERS,
                                    sizeof(struct nouveau_pushbuf_bo));
-       nvchan->pb.relocs = calloc(NOUVEAU_PUSHBUF_MAX_RELOCS,
+       nvchan->pb.relocs = CALLOC(NOUVEAU_PUSHBUF_MAX_RELOCS,
                                   sizeof(struct nouveau_pushbuf_reloc));
        return 0;
 }
@@ -268,4 +268,3 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr,
                *(uint32_t *)ptr = nouveau_pushbuf_calc_reloc(bo, r);
        return 0;
 }
-
@@ -22,7 +22,7 @@
 
 #include <stdlib.h>
 #include <errno.h>
-
+#include <util/u_memory.h>
 #include "nouveau_drmif.h"
 #include "nouveau_local.h"
 
@@ -32,7 +32,7 @@ nouveau_resource_init(struct nouveau_resource **heap,
 {
        struct nouveau_resource *r;
 
-       r = calloc(1, sizeof(struct nouveau_resource));
+       r = CALLOC_STRUCT(nouveau_resource);
        if (!r)
                return 1;
 
@@ -53,7 +53,7 @@ nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv,
 
        while (heap) {
                if (!heap->in_use && heap->size >= size) {
-                       r = calloc(1, sizeof(struct nouveau_resource));
+                       r = CALLOC_STRUCT(nouveau_resource);
                        if (!r)
                                return 1;
 
@@ -73,7 +73,7 @@ nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv,
                        *res = r;
                        return 0;
                }
-                       
+
                heap = heap->next;
        }
 
@@ -110,7 +110,7 @@ nouveau_resource_free(struct nouveau_resource **res)
                if (r->next)
                        r->next->prev = r->prev;
                r->prev->size += r->size;
-               free(r);
+               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
@@ -1,50 +1,23 @@
-#include "pipe/p_winsys.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_inlines.h"
-
-#include "util/u_memory.h"
-
+#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)
+static uint32_t
+nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
 {
-       struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
-       struct nouveau_context *nv = nvpws->nv;
        struct nouveau_device *dev = nv->nv_screen->device;
-       struct nouveau_pipe_buffer *nvbuf;
-       uint32_t flags;
-
-       nvbuf = calloc(1, sizeof(*nvbuf));
-       if (!nvbuf)
-               return NULL;
-       nvbuf->base.refcount = 1;
-       nvbuf->base.alignment = alignment;
-       nvbuf->base.usage = usage;
-       nvbuf->base.size = size;
-
-       flags = NOUVEAU_BO_LOCAL;
+       uint32_t flags = NOUVEAU_BO_LOCAL;
 
        if (usage & PIPE_BUFFER_USAGE_PIXEL) {
                if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
@@ -75,8 +48,31 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
                        flags |= NOUVEAU_BO_GART;
        }
 
+       return flags;
+}
+
+static struct pipe_buffer *
+nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
+                      unsigned usage, unsigned size)
+{
+       struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
+       struct nouveau_context *nv = nvpws->nv;
+       struct nouveau_device *dev = nv->nv_screen->device;
+       struct nouveau_pipe_buffer *nvbuf;
+       uint32_t flags;
+
+       nvbuf = CALLOC_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);
+               FREE(nvbuf);
                return NULL;
        }
 
@@ -90,14 +86,14 @@ nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
        struct nouveau_device *dev = nvpws->nv->nv_screen->device;
        struct nouveau_pipe_buffer *nvbuf;
 
-       nvbuf = calloc(1, sizeof(*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);
+               FREE(nvbuf);
                return NULL;
        }
 
@@ -110,7 +106,7 @@ nouveau_pipe_bo_del(struct pipe_winsys *ws, struct pipe_buffer *buf)
        struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf);
 
        nouveau_bo_del(&nvbuf->bo);
-       free(nvbuf);
+       FREE(nvbuf);
 }
 
 static void *
@@ -125,6 +121,26 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
        if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
                map_flags |= NOUVEAU_BO_WR;
 
+       /* 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;
@@ -176,6 +192,12 @@ nouveau_pipe_fence_finish(struct pipe_winsys *ws,
        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)
 {
@@ -201,7 +223,7 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv)
        pws->fence_finish = nouveau_pipe_fence_finish;
 
        pws->get_name = nouveau_get_name;
+       pws->destroy = nouveau_destroy;
 
        return &nvpws->pws;
 }
-
@@ -31,4 +31,9 @@ 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
  * 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 <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"
 
@@ -48,7 +48,7 @@ struct nouveau_softpipe_winsys {
  */
 static boolean
 nouveau_is_format_supported(struct softpipe_winsys *sws,
-                                               enum pipe_format format)
+                            enum pipe_format format)
 {
        switch (format) {
        case PIPE_FORMAT_A8R8G8B8_UNORM:
@@ -68,19 +68,34 @@ 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)
+       if (!nvsws) {
+               ws->destroy(ws);
+               pscreen->destroy(pscreen);
                return NULL;
+       }
 
        nvsws->sws.is_format_supported = nouveau_is_format_supported;
        nvsws->nv = nv;
 
-       return softpipe_create(pscreen, ws, &nvsws->sws);
+       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/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
@@ -1,16 +1,15 @@
-#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 <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
@@ -183,13 +182,12 @@ static const __DRIconfig **
 nouveau_screen_create(__DRIscreenPrivate *psp)
 {
        struct nouveau_dri *nv_dri = psp->pDevPriv;
-       struct nouveau_screen *nv_screen;
+       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 };
-       int ret;
 
        if (!driCheckDriDdxDrmVersions2("nouveau",
                                        &psp->dri_version, &dri_expected,
@@ -209,28 +207,23 @@ nouveau_screen_create(__DRIscreenPrivate *psp)
 
        if (psp->devPrivSize != sizeof(struct nouveau_dri)) {
                NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n");
-               return GL_FALSE;
+               return NULL;
        }
 
-       nv_screen = CALLOC_STRUCT(nouveau_screen);
+       nv_screen = CALLOC_STRUCT(nouveau_screen_dri);
        if (!nv_screen)
-               return GL_FALSE;
-       nv_screen->driScrnPriv = psp;
-       psp->private = (void *)nv_screen;
+               return NULL;
 
        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;
+       if (nouveau_screen_init(nv_dri, psp->fd, &nv_screen->base)) {
+               FREE(nv_screen);
+               return NULL;
        }
 
-       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;
+       nv_screen->driScrnPriv = psp;
+       psp->private = (void *)nv_screen;
 
        return (const __DRIconfig **)
                nouveau_fill_in_modes(psp, nv_dri->bpp,
@@ -241,9 +234,10 @@ nouveau_screen_create(__DRIscreenPrivate *psp)
 static void
 nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv)
 {
-       struct nouveau_screen *nv_screen = driScrnPriv->private;
+       struct nouveau_screen_dri *nv_screen = driScrnPriv->private;
 
        driScrnPriv->private = NULL;
+       nouveau_screen_cleanup(&nv_screen->base);
        FREE(nv_screen);
 }
 
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
@@ -1,34 +1,34 @@
-#include "main/glheader.h"
-#include "glapi/glthread.h"
+#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 <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 "../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 *nv = dPriv->driContextPriv->driverPrivate;
+       struct nouveau_context_dri *nv = dPriv->driContextPriv->driverPrivate;
        drm_clip_rect_t *pbox;
        int nbox, i;
 
-       LOCK_HARDWARE(nv);
+       LOCK_HARDWARE(&nv->base);
        if (!dPriv->numClipRects) {
-               UNLOCK_HARDWARE(nv);
+               UNLOCK_HARDWARE(&nv->base);
                return;
        }
        pbox = dPriv->pClipRects;
        nbox = dPriv->numClipRects;
 
-       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;
 
@@ -39,11 +39,11 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, 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);
+       FIRE_RING(nv->base.nvc->channel);
+       UNLOCK_HARDWARE(&nv->base);
 
        if (nv->last_stamp != dPriv->lastStamp) {
                struct nouveau_framebuffer *nvfb = dPriv->driverPrivate;
@@ -84,3 +84,29 @@ nouveau_swap_buffers(__DRIdrawablePrivate *dPriv)
        }
 }
 
+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/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
index ff43327..22d925b 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
@@ -1,11 +1,8 @@
-#include "pipe/p_context.h"
-#include "util/u_memory.h"
-#include "nouveau_context.h"
+#include "nouveau_screen_vl.h"
+#include <util/u_memory.h>
 #include <nouveau_drm.h>
-#include "nouveau_dri.h"
-#include "nouveau_local.h"
-#include "nouveau_screen.h"
-#include "nouveau_swapbuffers.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
@@ -50,34 +47,33 @@ int nouveau_check_dri_drm_ddx(dri_version_t *dri, dri_version_t *drm, dri_versio
 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;
+       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);
+       nv_screen = CALLOC_STRUCT(nouveau_screen_vl);
+
        if (!nv_screen)
                return 1;
-       nv_screen->dri_screen = dri_screen;
-       dri_screen->private = (void*)nv_screen;
+
+       if (nouveau_screen_init(nv_dri, dri_screen->fd, &nv_screen->base))
+       {
+               FREE(nv_screen);
+               return 1;
+       }
 
        /*
        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;
+       nv_screen->dri_screen = dri_screen;
+       dri_screen->private = (void*)nv_screen;
 
        return 0;
 }
@@ -85,7 +81,8 @@ nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf)
 void
 nouveau_screen_destroy(dri_screen_t *dri_screen)
 {
-       struct nouveau_screen *nv_screen = dri_screen->private;
+       struct nouveau_screen_vl *nv_screen = dri_screen->private;
 
+       nouveau_screen_cleanup(&nv_screen->base);
        FREE(nv_screen);
 }
@@ -1,19 +1,16 @@
-#ifndef __NOUVEAU_SCREEN_H__
-#define __NOUVEAU_SCREEN_H__
+#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 {
+struct nouveau_screen_vl
+{
+       struct nouveau_screen           base;
        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;*/
 };
 
@@ -21,4 +18,3 @@ int nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_frame
 void nouveau_screen_destroy(dri_screen_t *dri_screen);
 
 #endif
-
index 7916c80..16e6d55 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);
+}