nouveau: rewrite winsys in terms of drm_api, support dri2 state tracker
authorBen Skeggs <bskeggs@redhat.com>
Tue, 17 Mar 2009 22:22:35 +0000 (08:22 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 17 Mar 2009 23:44:40 +0000 (09:44 +1000)
drm_api is a set of hooks used by the dri2 state tracker, this wraps our
dri1 code around the same set of hooks.

Currently the dri2 build will produce nouveau_dri2.so which you'll need
to install as nouveau_dri.so if you wish to try it.  The dri2 state
tracker doesn't make it easy for a driver to support both paths in the
same binary.

34 files changed:
src/gallium/drivers/nouveau/nouveau_winsys.h
src/gallium/winsys/drm/nouveau/Makefile
src/gallium/winsys/drm/nouveau/common/Makefile [deleted file]
src/gallium/winsys/drm/nouveau/common/nouveau_context.c [deleted file]
src/gallium/winsys/drm/nouveau/common/nouveau_context.h [deleted file]
src/gallium/winsys/drm/nouveau/common/nouveau_dri.h [deleted file]
src/gallium/winsys/drm/nouveau/common/nouveau_local.h [deleted file]
src/gallium/winsys/drm/nouveau/common/nouveau_lock.c [deleted file]
src/gallium/winsys/drm/nouveau/common/nouveau_screen.c [deleted file]
src/gallium/winsys/drm/nouveau/common/nouveau_screen.h [deleted file]
src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c [deleted file]
src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c [deleted file]
src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h [deleted file]
src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c [deleted file]
src/gallium/winsys/drm/nouveau/dri/Makefile
src/gallium/winsys/drm/nouveau/dri/nouveau_context.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_context.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c [deleted file]
src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h [deleted file]
src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c [deleted file]
src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h [deleted file]
src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c
src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h
src/gallium/winsys/drm/nouveau/dri2/Makefile [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/drm/Makefile [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h [new file with mode: 0644]

index 4fcadbae3f91a73a69e9b95403386e4b62e13f5d..ff7dd1c51c8fc5bcbe98ab60a47b769c07143f30 100644 (file)
@@ -24,7 +24,7 @@
 #define NOUVEAU_BUFFER_USAGE_TRANSFER (1 << 18)
 
 struct nouveau_winsys {
-       struct nouveau_context *nv;
+       struct pipe_winsys *ws;
 
        struct nouveau_channel *channel;
 
index 652cf7146cb854d4c0da5e4c218865e53f3203f4..f8c81358544bd312bc65233814d6c45fa02087f5 100644 (file)
@@ -2,7 +2,7 @@
 TOP = ../../../../..
 include $(TOP)/configs/current
 
-SUBDIRS = common dri
+SUBDIRS = drm dri dri2
 
 default install clean:
        @for dir in $(SUBDIRS) ; do \
diff --git a/src/gallium/winsys/drm/nouveau/common/Makefile b/src/gallium/winsys/drm/nouveau/common/Makefile
deleted file mode 100644 (file)
index f675f7c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-TOP = ../../../../../..
-include $(TOP)/configs/current
-
-LIBNAME = nouveaudrm
-
-C_SOURCES = \
-        nouveau_context.c \
-       nouveau_lock.c \
-       nouveau_screen.c \
-       nouveau_winsys.c \
-       nouveau_winsys_pipe.c \
-       nouveau_winsys_softpipe.c
-
-LIBRARY_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I)
-
-LIBRARY_DEFINES = $(shell pkg-config libdrm --cflags-only-other \
-               && pkg-config libdrm --atleast-version=2.3.1 \
-               && pkg-config libdrm_nouveau --exact-version=0.5 \
-               && pkg-config libdrm_nouveau --cflags-only-other \
-               && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
-
-include ../../../../Makefile.template
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c
deleted file mode 100644 (file)
index fbe57ea..0000000
+++ /dev/null
@@ -1,206 +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"
-
-static void
-nouveau_channel_context_destroy(struct nouveau_channel_context *nvc)
-{
-       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 = 0x77000000;
-       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 0x00:
-               /* NV04 */
-       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;
-       }
-
-       /* 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;
-               pipe_reference_init(&nvc->reference, 1);
-       }
-
-       pipe_reference((struct pipe_reference**)&nv->nvc, &nvc->reference);
-
-       /* Find a free slot for a pipe context, allocate a new one if needed */
-       nv->pctx_id = -1;
-       for (i = 0; i < nvc->nr_pctx; i++) {
-               if (nvc->pctx[i] == NULL) {
-                       nv->pctx_id = i;
-                       break;
-               }
-       }
-
-       if (nv->pctx_id < 0) {
-               nv->pctx_id = nvc->nr_pctx++;
-               nvc->pctx =
-                       realloc(nvc->pctx,
-                               sizeof(struct pipe_context *) * nvc->nr_pctx);
-       }
-
-       /* Create pipe */
-       if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) {
-               struct pipe_screen *pscreen;
-
-               pipe = nouveau_pipe_create(nv);
-               if (!pipe) {
-                       NOUVEAU_ERR("Couldn't create hw pipe\n");
-                       return 1;
-               }
-               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;
-               }
-       }
-
-       {
-               struct pipe_texture *fb_tex;
-               struct pipe_surface *fb_surf;
-               struct nouveau_pipe_buffer *fb_buf;
-               enum pipe_format format;
-
-               fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer));
-               pipe_reference_init(&fb_buf->base.reference, 1);
-               fb_buf->base.usage = PIPE_BUFFER_USAGE_PIXEL;
-
-               nouveau_bo_handle_ref(dev, nv_screen->front_offset, &fb_buf->bo);
-
-               if (nv_screen->front_cpp == 4)
-                       format = PIPE_FORMAT_A8R8G8B8_UNORM;
-               else
-                       format = PIPE_FORMAT_R5G6B5_UNORM;
-
-               fb_surf = nouveau_surface_buffer_ref(nv, &fb_buf->base, format,
-                                                    nv_screen->front_pitch /
-                                                    nv_screen->front_cpp,
-                                                    nv_screen->front_height,
-                                                    nv_screen->front_pitch,
-                                                    &fb_tex);
-
-               nv->frontbuffer = fb_surf;
-               nv->frontbuffer_texture = fb_tex;
-       }
-
-       pipe->priv = nv;
-       return 0;
-}
-
-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 (pipe_reference((struct pipe_reference**)&nv->nvc, NULL)) {
-                       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
deleted file mode 100644 (file)
index ba8fc3a..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef __NOUVEAU_CONTEXT_H__
-#define __NOUVEAU_CONTEXT_H__
-
-#include "nouveau/nouveau_winsys.h"
-#include "nouveau_drmif.h"
-#include "nouveau_device.h"
-#include "nouveau_channel.h"
-#include "nouveau_pushbuf.h"
-#include "nouveau_bo.h"
-#include "nouveau_grobj.h"
-#include "nouveau_notifier.h"
-#include "nouveau_class.h"
-#include "nouveau_local.h"
-
-struct nouveau_channel_context {
-       struct pipe_reference reference;
-       struct pipe_screen *pscreen;
-
-       unsigned cur_pctx;
-       unsigned nr_pctx;
-       struct pipe_context **pctx;
-
-       struct nouveau_channel  *channel;
-       unsigned next_handle;
-};
-
-struct nouveau_context {
-       int locked;
-       struct nouveau_screen *nv_screen;
-       struct pipe_surface *frontbuffer;
-       struct pipe_texture *frontbuffer_texture;
-
-       struct {
-               int hw_vertex_buffer;
-               int hw_index_buffer;
-       } cap;
-
-       /* Hardware context */
-       struct nouveau_channel_context *nvc;
-       int pctx_id;
-};
-
-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 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_dri.h b/src/gallium/winsys/drm/nouveau/common/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/common/nouveau_local.h b/src/gallium/winsys/drm/nouveau/common/nouveau_local.h
deleted file mode 100644 (file)
index 11175bc..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#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)
-
-#endif
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_lock.c b/src/gallium/winsys/drm/nouveau/common/nouveau_lock.c
deleted file mode 100644 (file)
index e8cf051..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include <pipe/p_thread.h>
-#include "nouveau_context.h"
-#include "nouveau_screen.h"
-
-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_screen.c b/src/gallium/winsys/drm/nouveau/common/nouveau_screen.c
deleted file mode 100644 (file)
index 422fbf0..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#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
deleted file mode 100644 (file)
index 3e68e21..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#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
deleted file mode 100644 (file)
index 52c3b02..0000000
+++ /dev/null
@@ -1,146 +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;
-
-       BEGIN_RING(chan, *grobj, 0x0000, 1);
-       OUT_RING  (chan, (*grobj)->handle);
-       (*grobj)->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT;
-       return 0;
-}
-
-static int
-nouveau_pipe_push_reloc(struct nouveau_winsys *nvws, void *ptr,
-                       struct pipe_buffer *buf, uint32_t data,
-                       uint32_t flags, uint32_t vor, uint32_t tor)
-{
-       struct nouveau_bo *bo = nouveau_pipe_buffer(buf)->bo;
-
-       return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, bo,
-                                         data, flags, vor, tor);
-}
-
-static int
-nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size,
-                       struct pipe_fence_handle **fence)
-{
-       if (fence)
-               *fence = NULL;
-
-       return nouveau_pushbuf_flush(nvws->channel, size);
-}
-
-static struct nouveau_bo *
-nouveau_pipe_get_bo(struct pipe_buffer *pb)
-{
-       return nouveau_pipe_buffer(pb)->bo;
-}
-
-struct 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 0x00:
-               hws_create = nv04_screen_create;
-               hw_create = nv04_create;
-               break;
-       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->get_bo            = nouveau_pipe_get_bo;
-
-       ws = nouveau_create_pipe_winsys(nv);
-
-       if (!nvc->pscreen) {
-               nvc->pscreen = hws_create(ws, nvws);
-               if (!nvc->pscreen) {
-                       NOUVEAU_ERR("Couldn't create hw screen\n");
-                       return NULL;
-               }
-       }
-       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
deleted file mode 100644 (file)
index 24bbd45..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-#include "pipe/internal/p_winsys_screen.h"
-#include <pipe/p_defines.h>
-#include <pipe/p_inlines.h>
-#include <util/u_memory.h>
-#include "nouveau_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 & NOUVEAU_BUFFER_USAGE_TRANSFER)
-               flags |= NOUVEAU_BO_GART;
-
-       if (usage & PIPE_BUFFER_USAGE_PIXEL) {
-               if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
-                       flags |= NOUVEAU_BO_GART;
-               if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE))
-                       flags |= NOUVEAU_BO_VRAM;
-
-               switch (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;
-       pipe_reference_init(&nvbuf->base.reference, 1);
-       nvbuf->base.alignment = alignment;
-       nvbuf->base.usage = usage;
-       nvbuf->base.size = size;
-
-       flags = nouveau_flags_from_usage(nv, usage);
-
-       if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
-               FREE(nvbuf);
-               return NULL;
-       }
-
-       return &nvbuf->base;
-}
-
-static struct pipe_buffer *
-nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
-       struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
-       struct nouveau_device *dev = nvpws->nv->nv_screen->device;
-       struct nouveau_pipe_buffer *nvbuf;
-
-       nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
-       if (!nvbuf)
-               return NULL;
-       pipe_reference_init(&nvbuf->base.reference, 1);
-       nvbuf->base.size = bytes;
-
-       if (nouveau_bo_user(dev, ptr, bytes, &nvbuf->bo)) {
-               FREE(nvbuf);
-               return NULL;
-       }
-
-       return &nvbuf->base;
-}
-
-static void
-nouveau_pipe_bo_del(struct pipe_buffer *buf)
-{
-       struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);
-
-       nouveau_bo_ref(NULL, &nvbuf->bo);
-       FREE(nvbuf);
-}
-
-static void *
-nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
-                   unsigned flags)
-{
-       struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);
-       uint32_t map_flags = 0;
-
-        if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
-           /* Remove this when this code is modified to support DONTBLOCK 
-            */
-           return NULL;
-        }
-
-       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 0
-       if (flags & PIPE_BUFFER_USAGE_DISCARD &&
-           !(flags & PIPE_BUFFER_USAGE_CPU_READ) &&
-           nouveau_bo_busy(nvbuf->bo, map_flags)) {
-               struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
-               struct nouveau_context *nv = nvpws->nv;
-               struct nouveau_device *dev = nv->nv_screen->device;
-               struct nouveau_bo *rename;
-               uint32_t flags = nouveau_flags_from_usage(nv, buf->usage);
-
-               if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) {
-                       nouveau_bo_ref(NULL, &nvbuf->bo);
-                       nvbuf->bo = rename;
-               }
-       }
-#endif
-
-       if (nouveau_bo_map(nvbuf->bo, map_flags))
-               return NULL;
-       return nvbuf->bo->map;
-}
-
-static void
-nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
-       struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);
-
-       nouveau_bo_unmap(nvbuf->bo);
-}
-
-static void
-nouveau_pipe_fence_reference(struct pipe_winsys *ws,
-                            struct pipe_fence_handle **ptr,
-                            struct pipe_fence_handle *pfence)
-{
-       *ptr = pfence;
-}
-
-static int
-nouveau_pipe_fence_signalled(struct pipe_winsys *ws,
-                            struct pipe_fence_handle *pfence, unsigned flag)
-{
-       return 0;
-}
-
-static int
-nouveau_pipe_fence_finish(struct pipe_winsys *ws,
-                         struct pipe_fence_handle *pfence, unsigned flag)
-{
-       return 0;
-}
-
-struct pipe_surface *
-nouveau_surface_buffer_ref(struct nouveau_context *nv, struct pipe_buffer *pb,
-                          enum pipe_format format, int w, int h,
-                          unsigned pitch, struct pipe_texture **ppt)
-{
-       struct pipe_screen *pscreen = nv->nvc->pscreen;
-       struct pipe_texture tmpl, *pt;
-       struct pipe_surface *ps;
-
-       memset(&tmpl, 0, sizeof(tmpl));
-       tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
-                        NOUVEAU_TEXTURE_USAGE_LINEAR;
-       tmpl.target = PIPE_TEXTURE_2D;
-       tmpl.width[0] = w;
-       tmpl.height[0] = h;
-       tmpl.depth[0] = 1;
-       tmpl.format = format;
-       pf_get_block(tmpl.format, &tmpl.block);
-       tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w);
-       tmpl.nblocksy[0] = pf_get_nblocksy(&tmpl.block, h);
-
-       pt = pscreen->texture_blanket(pscreen, &tmpl, &pitch, pb);
-       if (!pt)
-               return NULL;
-
-       ps = pscreen->get_tex_surface(pscreen, pt, 0, 0, 0,
-                                     PIPE_BUFFER_USAGE_GPU_WRITE);
-
-       *ppt = pt;
-       return ps;
-}
-
-static void
-nouveau_destroy(struct pipe_winsys *pws)
-{
-       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
deleted file mode 100644 (file)
index 1eb8043..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef NOUVEAU_PIPE_WINSYS_H
-#define NOUVEAU_PIPE_WINSYS_H
-
-#include "pipe/p_context.h"
-#include "pipe/internal/p_winsys_screen.h"
-#include "nouveau_context.h"
-
-struct nouveau_pipe_buffer {
-       struct pipe_buffer base;
-       struct nouveau_bo *bo;
-};
-
-static INLINE struct nouveau_pipe_buffer *
-nouveau_pipe_buffer(struct pipe_buffer *buf)
-{
-       return (struct nouveau_pipe_buffer *)buf;
-}
-
-struct nouveau_pipe_winsys {
-       struct pipe_winsys 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);
-
-struct pipe_surface *
-nouveau_surface_buffer_ref(struct nouveau_context *nv, struct pipe_buffer *pb,
-                          enum pipe_format format, int w, int h,
-                          unsigned pitch, struct pipe_texture **ppt);
-
-#endif
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c
deleted file mode 100644 (file)
index 396e4f2..0000000
+++ /dev/null
@@ -1,101 +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 "pipe/internal/p_winsys_screen.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;
-}
-
index a73e8d5cb4b0d3dc757c40c9203c1f8e79deabd5..f7db6201fea55f283d0a8235566a7180c2dcc31e 100644 (file)
@@ -6,7 +6,7 @@ LIBNAME = nouveau_dri.so
 MINIGLX_SOURCES =
 
 PIPE_DRIVERS = \
-       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+       $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
        $(TOP)/src/gallium/drivers/nv04/libnv04.a \
        $(TOP)/src/gallium/drivers/nv10/libnv10.a \
        $(TOP)/src/gallium/drivers/nv20/libnv20.a \
@@ -15,10 +15,10 @@ PIPE_DRIVERS = \
        $(TOP)/src/gallium/drivers/nv50/libnv50.a
        
 DRIVER_SOURCES = \
-       nouveau_context_dri.c \
-       nouveau_screen_dri.c \
+       nouveau_context.c \
+       nouveau_screen.c \
        nouveau_swapbuffers.c \
-       ../common/libnouveaudrm.a
+       nouveau_lock.c
 
 C_SOURCES = \
        $(COMMON_GALLIUM_SOURCES) \
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c
new file mode 100644 (file)
index 0000000..deb6ffc
--- /dev/null
@@ -0,0 +1,118 @@
+#include <main/glheader.h>
+#include <glapi/glthread.h>
+#include <GL/internal/glcore.h>
+#include <utils.h>
+
+#include <state_tracker/st_public.h>
+#include <state_tracker/st_context.h>
+#include <state_tracker/drm_api.h>
+#include <pipe/p_defines.h>
+#include <pipe/p_context.h>
+#include <pipe/p_screen.h>
+
+#include "nouveau_context.h"
+#include "nouveau_screen.h"
+
+#include "nouveau_drmif.h"
+
+GLboolean
+nouveau_context_create(const __GLcontextModes *glVis,
+                      __DRIcontextPrivate *driContextPriv,
+                      void *sharedContextPrivate)
+{
+       __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv;
+       struct nouveau_screen  *nv_screen = driScrnPriv->private;
+       struct nouveau_context *nv;
+       struct pipe_context *pipe;
+       struct st_context *st_share = NULL;
+
+       if (sharedContextPrivate)
+               st_share = ((struct nouveau_context *)sharedContextPrivate)->st;
+
+       nv = CALLOC_STRUCT(nouveau_context);
+       if (!nv)
+               return GL_FALSE;
+
+       {
+               struct nouveau_device_priv *nvdev =
+                       nouveau_device(nv_screen->device);
+
+               nvdev->ctx  = driContextPriv->hHWContext;
+               nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock;
+       }
+
+       pipe = drm_api_hooks.create_context(nv_screen->pscreen);
+       if (!pipe) {
+               FREE(nv);
+               return GL_FALSE;
+       }
+       pipe->priv = nv;
+
+       driContextPriv->driverPrivate = nv;
+       nv->dri_screen = driScrnPriv;
+
+       driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache,
+                           nv->dri_screen->myNum, "nouveau");
+
+       nv->st = st_create_context(pipe, glVis, st_share);
+       return GL_TRUE;
+}
+
+void
+nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
+{
+       struct nouveau_context *nv = driContextPriv->driverPrivate;
+
+       assert(nv);
+
+       st_finish(nv->st);
+       st_destroy_context(nv->st);
+
+       FREE(nv);
+}
+
+GLboolean
+nouveau_context_bind(__DRIcontextPrivate *driContextPriv,
+                    __DRIdrawablePrivate *driDrawPriv,
+                    __DRIdrawablePrivate *driReadPriv)
+{
+       struct nouveau_context *nv;
+       struct nouveau_framebuffer *draw, *read;
+
+       if (!driContextPriv) {
+               st_make_current(NULL, NULL, NULL);
+               return GL_TRUE;
+       }
+
+       nv = driContextPriv->driverPrivate;
+       draw = driDrawPriv->driverPrivate;
+       read = driReadPriv->driverPrivate;
+
+       st_make_current(nv->st, draw->stfb, read->stfb);
+
+       if ((nv->dri_drawable != driDrawPriv) ||
+           (nv->last_stamp != driDrawPriv->lastStamp)) {
+               nv->dri_drawable = driDrawPriv;
+               st_resize_framebuffer(draw->stfb, driDrawPriv->w,
+                                     driDrawPriv->h);
+               nv->last_stamp = driDrawPriv->lastStamp;
+       }
+
+       if (driDrawPriv != driReadPriv) {
+               st_resize_framebuffer(read->stfb, driReadPriv->w,
+                                     driReadPriv->h);
+       }
+
+       return GL_TRUE;
+}
+
+GLboolean
+nouveau_context_unbind(__DRIcontextPrivate *driContextPriv)
+{
+       struct nouveau_context *nv = driContextPriv->driverPrivate;
+       (void)nv;
+
+       st_flush(nv->st, 0, NULL);
+       return GL_TRUE;
+}
+
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h
new file mode 100644 (file)
index 0000000..2779b09
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef __NOUVEAU_CONTEXT_DRI_H__
+#define __NOUVEAU_CONTEXT_DRI_H__
+
+#include <dri_util.h>
+#include <xmlconfig.h>
+
+#include "nouveau/nouveau_winsys.h"
+
+#define NOUVEAU_ERR(fmt, args...) debug_printf("%s: "fmt, __func__, ##args)
+
+struct nouveau_framebuffer {
+       struct st_framebuffer *stfb;
+};
+
+struct nouveau_context {
+       struct st_context *st;
+
+       /* DRI stuff */
+       __DRIscreenPrivate    *dri_screen;
+       __DRIdrawablePrivate  *dri_drawable;
+       unsigned int           last_stamp;
+       driOptionCache         dri_option_cache;
+       drm_context_t          drm_context;
+       drmLock                drm_lock;
+       int                    locked;
+};
+
+extern GLboolean nouveau_context_create(const __GLcontextModes *,
+                                       __DRIcontextPrivate *, void *);
+extern void nouveau_context_destroy(__DRIcontextPrivate *);
+extern GLboolean nouveau_context_bind(__DRIcontextPrivate *,
+                                     __DRIdrawablePrivate *draw,
+                                     __DRIdrawablePrivate *read);
+extern GLboolean nouveau_context_unbind(__DRIcontextPrivate *);
+
+extern void nouveau_contended_lock(struct nouveau_context *nv);
+extern void LOCK_HARDWARE(struct nouveau_context *nv);
+extern void UNLOCK_HARDWARE(struct nouveau_context *nv);
+
+#ifdef DEBUG
+extern int __nouveau_debug;
+
+#define DEBUG_BO (1 << 0)
+
+#define DBG(flag, ...) do {                   \
+       if (__nouveau_debug & (DEBUG_##flag)) \
+               NOUVEAU_ERR(__VA_ARGS__);     \
+} while(0)
+#else
+#define DBG(flag, ...)
+#endif
+
+#endif
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c
deleted file mode 100644 (file)
index aacfe98..0000000
+++ /dev/null
@@ -1,124 +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 "../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->base, &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
deleted file mode 100644 (file)
index 64cf326..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#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"
-
-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_dri.h b/src/gallium/winsys/drm/nouveau/dri/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/dri/nouveau_lock.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c
new file mode 100644 (file)
index 0000000..92f5bd0
--- /dev/null
@@ -0,0 +1,73 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include <pipe/p_thread.h>
+#include "nouveau_context.h"
+#include "nouveau_screen.h"
+#include "nouveau_drmif.h"
+
+pipe_static_mutex(lockMutex);
+
+/* Lock the hardware and validate our state.
+ */
+void
+LOCK_HARDWARE(struct nouveau_context *nv)
+{
+       struct nouveau_screen *nv_screen = nv->dri_screen->private;
+       struct nouveau_device *dev = nv_screen->device;
+       struct nouveau_device_priv *nvdev = nouveau_device(dev);
+       char __ret=0;
+
+       assert(!nv->locked);
+       pipe_mutex_lock(lockMutex);
+
+       DRM_CAS(nvdev->lock, nvdev->ctx,
+               (DRM_LOCK_HELD | nvdev->ctx), __ret);
+
+       if (__ret) {
+               drmGetLock(nvdev->fd, nvdev->ctx, 0);
+               nouveau_contended_lock(nv);
+       }
+       nv->locked = 1;
+}
+
+/* Unlock the hardware using the global current context 
+ */
+void
+UNLOCK_HARDWARE(struct nouveau_context *nv)
+{
+       struct nouveau_screen *nv_screen = nv->dri_screen->private;
+       struct nouveau_device *dev = nv_screen->device;
+       struct nouveau_device_priv *nvdev = nouveau_device(dev);
+
+       assert(nv->locked);
+       nv->locked = 0;
+
+       DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx);
+
+       pipe_mutex_unlock(lockMutex);
+} 
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c
new file mode 100644 (file)
index 0000000..c4cbbc2
--- /dev/null
@@ -0,0 +1,329 @@
+#include <utils.h>
+#include <vblank.h>
+#include <xmlpool.h>
+
+#include <pipe/p_context.h>
+#include <state_tracker/st_public.h>
+#include <state_tracker/st_cb_fbo.h>
+#include <state_tracker/drm_api.h>
+
+#include "nouveau_context.h"
+#include "nouveau_screen.h"
+#include "nouveau_swapbuffers.h"
+#include "nouveau_dri.h"
+
+#include "nouveau_drm.h"
+#include "nouveau_drmif.h"
+
+#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 12
+#error nouveau_drm.h version does not match expected version
+#endif
+
+/* Extension stuff, enabling of extensions handled by Gallium's GL state
+ * tracker.  But, we still need to define the entry points we want.
+ */
+#define need_GL_ARB_fragment_program
+#define need_GL_ARB_multisample
+#define need_GL_ARB_occlusion_query
+#define need_GL_ARB_point_parameters
+#define need_GL_ARB_shader_objects
+#define need_GL_ARB_texture_compression
+#define need_GL_ARB_vertex_program
+#define need_GL_ARB_vertex_shader
+#define need_GL_ARB_vertex_buffer_object
+#define need_GL_EXT_compiled_vertex_array
+#define need_GL_EXT_fog_coord
+#define need_GL_EXT_secondary_color
+#define need_GL_EXT_framebuffer_object
+#define need_GL_VERSION_2_0
+#define need_GL_VERSION_2_1
+#include "extension_helper.h"
+
+const struct dri_extension card_extensions[] =
+{
+       { "GL_ARB_multisample", GL_ARB_multisample_functions },
+       { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions },
+       { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },
+       { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions },
+       { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions },
+       { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions },
+       { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
+       { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
+       { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions },
+       { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
+       { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions },
+       { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
+       { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
+       { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
+       { NULL, 0 }
+};
+
+PUBLIC const char __driConfigOptions[] =
+DRI_CONF_BEGIN
+DRI_CONF_END;
+static const GLuint __driNConfigOptions = 0;
+
+extern const struct dri_extension common_extensions[];
+extern const struct dri_extension nv40_extensions[];
+
+static GLboolean
+nouveau_create_buffer(__DRIscreenPrivate * driScrnPriv,
+                     __DRIdrawablePrivate * driDrawPriv,
+                     const __GLcontextModes *glVis, GLboolean pixmapBuffer)
+{
+       struct nouveau_framebuffer *nvfb;
+       enum pipe_format colour, depth, stencil;
+
+       if (pixmapBuffer)
+               return GL_FALSE;
+
+       nvfb = CALLOC_STRUCT(nouveau_framebuffer);
+       if (!nvfb)
+               return GL_FALSE;
+
+       if (glVis->redBits == 5)
+               colour = PIPE_FORMAT_R5G6B5_UNORM;
+       else
+               colour = PIPE_FORMAT_A8R8G8B8_UNORM;
+
+       if (glVis->depthBits == 16)
+               depth = PIPE_FORMAT_Z16_UNORM;
+       else if (glVis->depthBits == 24)
+               depth = PIPE_FORMAT_Z24S8_UNORM;
+       else
+               depth = PIPE_FORMAT_NONE;
+
+       if (glVis->stencilBits == 8)
+               stencil = PIPE_FORMAT_Z24S8_UNORM;
+       else
+               stencil = PIPE_FORMAT_NONE;
+
+       nvfb->stfb = st_create_framebuffer(glVis, colour, depth, stencil,
+                                          driDrawPriv->w, driDrawPriv->h,
+                                          (void*)nvfb);
+       if (!nvfb->stfb) {
+               free(nvfb);
+               return  GL_FALSE;
+       }
+
+       driDrawPriv->driverPrivate = (void *)nvfb;
+       return GL_TRUE;
+}
+
+static void
+nouveau_destroy_buffer(__DRIdrawablePrivate * driDrawPriv)
+{
+       struct nouveau_framebuffer *nvfb;
+       
+       nvfb = (struct nouveau_framebuffer *)driDrawPriv->driverPrivate;
+       st_unreference_framebuffer(nvfb->stfb);
+       free(nvfb);
+}
+
+static __DRIconfig **
+nouveau_fill_in_modes(__DRIscreenPrivate *psp,
+                     unsigned pixel_bits, unsigned depth_bits,
+                     unsigned stencil_bits, GLboolean have_back_buffer)
+{
+       __DRIconfig **configs;
+       unsigned depth_buffer_factor;
+       unsigned back_buffer_factor;
+       GLenum fb_format;
+       GLenum fb_type;
+
+       static const GLenum back_buffer_modes[] = {
+               GLX_NONE, GLX_SWAP_UNDEFINED_OML,
+       };
+
+       uint8_t depth_bits_array[3];
+       uint8_t stencil_bits_array[3];
+       uint8_t msaa_samples_array[1];
+
+       depth_bits_array[0] = 0;
+       depth_bits_array[1] = depth_bits;
+       depth_bits_array[2] = depth_bits;
+
+       /* Just like with the accumulation buffer, always provide some modes
+        * with a stencil buffer.  It will be a sw fallback, but some apps won't
+        * care about that.
+        */
+       stencil_bits_array[0] = 0;
+       stencil_bits_array[1] = 0;
+       if (depth_bits == 24)
+               stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
+       stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits;
+
+       msaa_samples_array[0] = 0;
+
+       depth_buffer_factor =
+               ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
+       back_buffer_factor = (have_back_buffer) ? 3 : 1;
+
+       if (pixel_bits == 16) {
+               fb_format = GL_RGB;
+               fb_type = GL_UNSIGNED_SHORT_5_6_5;
+       }
+       else {
+               fb_format = GL_BGRA;
+               fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+       }
+
+       configs = driCreateConfigs(fb_format, fb_type,
+                                  depth_bits_array, stencil_bits_array,
+                                  depth_buffer_factor, back_buffer_modes,
+                                  back_buffer_factor, msaa_samples_array, 1);
+       if (configs == NULL) {
+        fprintf(stderr, "[%s:%u] Error creating FBConfig!\n",
+                        __func__, __LINE__);
+               return NULL;
+       }
+
+       return configs;
+}
+
+static struct pipe_surface *
+dri_surface_from_handle(struct pipe_screen *screen,
+                        unsigned handle,
+                        enum pipe_format format,
+                        unsigned width,
+                        unsigned height,
+                        unsigned pitch)
+{
+   struct pipe_surface *surface = NULL;
+   struct pipe_texture *texture = NULL;
+   struct pipe_texture templat;
+   struct pipe_buffer *buf = NULL;
+
+   buf = drm_api_hooks.buffer_from_handle(screen, "front buffer", handle);
+   if (!buf)
+      return NULL;
+
+   memset(&templat, 0, sizeof(templat));
+   templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
+   templat.target = PIPE_TEXTURE_2D;
+   templat.last_level = 0;
+   templat.depth[0] = 1;
+   templat.format = format;
+   templat.width[0] = width;
+   templat.height[0] = height;
+   pf_get_block(templat.format, &templat.block);
+
+   texture = screen->texture_blanket(screen,
+                                     &templat,
+                                     &pitch,
+                                     buf);
+
+   /* we don't need the buffer from this point on */
+   pipe_buffer_reference(&buf, NULL);
+
+   if (!texture)
+      return NULL;
+
+   surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
+                                     PIPE_BUFFER_USAGE_GPU_READ |
+                                     PIPE_BUFFER_USAGE_GPU_WRITE);
+
+   /* we don't need the texture from this point on */
+   pipe_texture_reference(&texture, NULL);
+   return surface;
+}
+
+static const __DRIconfig **
+nouveau_screen_create(__DRIscreenPrivate *psp)
+{
+       struct nouveau_dri *nv_dri = psp->pDevPriv;
+       struct nouveau_screen *nv_screen;
+       static const __DRIversion ddx_expected =
+               { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
+       static const __DRIversion dri_expected = { 4, 0, 0 };
+       static const __DRIversion drm_expected =
+               { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
+
+       if (!driCheckDriDdxDrmVersions2("nouveau",
+                                       &psp->dri_version, &dri_expected,
+                                       &psp->ddx_version, &ddx_expected,
+                                       &psp->drm_version, &drm_expected)) {
+               return NULL;
+       }
+
+       if (drm_expected.patch != psp->drm_version.patch) {
+               fprintf(stderr, "Incompatible DRM patch level.\n"
+                               "Expected: %d\n" "Current : %d\n",
+                       drm_expected.patch, psp->drm_version.patch);
+               return NULL;
+       }
+
+       driInitExtensions(NULL, card_extensions, GL_FALSE);
+
+       if (psp->devPrivSize != sizeof(struct nouveau_dri)) {
+               NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n");
+               return NULL;
+       }
+
+       nv_screen = CALLOC_STRUCT(nouveau_screen);
+       if (!nv_screen)
+               return NULL;
+
+       nouveau_device_open_existing(&nv_screen->device, 0, psp->fd, 0);
+
+       nv_screen->pscreen = drm_api_hooks.create_screen(psp->fd, 0);
+       if (!nv_screen->pscreen) {
+               FREE(nv_screen);
+               return NULL;
+       }
+       nv_screen->pscreen->flush_frontbuffer = nouveau_flush_frontbuffer;
+
+       {
+               enum pipe_format format;
+
+               if (nv_dri->bpp == 16)
+                       format = PIPE_FORMAT_R5G6B5_UNORM;
+               else
+                       format = PIPE_FORMAT_A8R8G8B8_UNORM;
+
+               nv_screen->fb = dri_surface_from_handle(nv_screen->pscreen,
+                                                       nv_dri->front_offset,
+                                                       format,
+                                                       nv_dri->width,
+                                                       nv_dri->height,
+                                                       nv_dri->front_pitch *
+                                                       nv_dri->bpp / 8);
+       }
+                                               
+       driParseOptionInfo(&nv_screen->option_cache,
+                          __driConfigOptions, __driNConfigOptions);
+
+       nv_screen->driScrnPriv = psp;
+       psp->private = (void *)nv_screen;
+
+       return (const __DRIconfig **)
+               nouveau_fill_in_modes(psp, nv_dri->bpp,
+                                     (nv_dri->bpp == 16) ? 16 : 24,
+                                     (nv_dri->bpp == 16) ? 0 : 8, 1);
+}
+
+static void
+nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv)
+{
+       struct nouveau_screen *nv_screen = driScrnPriv->private;
+
+       driScrnPriv->private = NULL;
+       FREE(nv_screen);
+}
+
+const struct __DriverAPIRec
+driDriverAPI = {
+       .InitScreen     = nouveau_screen_create,
+       .DestroyScreen  = nouveau_screen_destroy,
+       .CreateContext  = nouveau_context_create,
+       .DestroyContext = nouveau_context_destroy,
+       .CreateBuffer   = nouveau_create_buffer,
+       .DestroyBuffer  = nouveau_destroy_buffer,
+       .SwapBuffers    = nouveau_swap_buffers,
+       .MakeCurrent    = nouveau_context_bind,
+       .UnbindContext  = nouveau_context_unbind,
+       .CopySubBuffer  = nouveau_copy_sub_buffer,
+
+       .InitScreen2    = NULL, /* one day, I promise! */
+};
+
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h
new file mode 100644 (file)
index 0000000..ac078f3
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef __NOUVEAU_SCREEN_DRI_H__
+#define __NOUVEAU_SCREEN_DRI_H__
+
+#include "xmlconfig.h"
+
+struct nouveau_screen {
+       __DRIscreenPrivate *driScrnPriv;
+       driOptionCache      option_cache;
+
+       struct nouveau_device *device;
+
+       struct pipe_screen *pscreen;
+       struct pipe_surface *fb;
+};
+
+#endif
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c
deleted file mode 100644 (file)
index 964a902..0000000
+++ /dev/null
@@ -1,259 +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_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 != 12
-#error nouveau_drm.h version does not match expected version
-#endif
-
-/* Extension stuff, enabling of extensions handled by Gallium's GL state
- * tracker.  But, we still need to define the entry points we want.
- */
-#define need_GL_ARB_fragment_program
-#define need_GL_ARB_multisample
-#define need_GL_ARB_occlusion_query
-#define need_GL_ARB_point_parameters
-#define need_GL_ARB_shader_objects
-#define need_GL_ARB_texture_compression
-#define need_GL_ARB_vertex_program
-#define need_GL_ARB_vertex_shader
-#define need_GL_ARB_vertex_buffer_object
-#define need_GL_EXT_compiled_vertex_array
-#define need_GL_EXT_fog_coord
-#define need_GL_EXT_secondary_color
-#define need_GL_EXT_framebuffer_object
-#define need_GL_VERSION_2_0
-#define need_GL_VERSION_2_1
-#include "extension_helper.h"
-
-const struct dri_extension card_extensions[] =
-{
-       { "GL_ARB_multisample", GL_ARB_multisample_functions },
-       { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions },
-       { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },
-       { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions },
-       { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions },
-       { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions },
-       { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
-       { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
-       { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions },
-       { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
-       { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions },
-       { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
-       { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
-       { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
-       { NULL, 0 }
-};
-
-PUBLIC const char __driConfigOptions[] =
-DRI_CONF_BEGIN
-DRI_CONF_END;
-static const GLuint __driNConfigOptions = 0;
-
-extern const struct dri_extension common_extensions[];
-extern const struct dri_extension nv40_extensions[];
-
-static GLboolean
-nouveau_create_buffer(__DRIscreenPrivate * driScrnPriv,
-                     __DRIdrawablePrivate * driDrawPriv,
-                     const __GLcontextModes *glVis, GLboolean pixmapBuffer)
-{
-       struct nouveau_framebuffer *nvfb;
-       enum pipe_format colour, depth, stencil;
-
-       if (pixmapBuffer)
-               return GL_FALSE;
-
-       nvfb = CALLOC_STRUCT(nouveau_framebuffer);
-       if (!nvfb)
-               return GL_FALSE;
-
-       if (glVis->redBits == 5)
-               colour = PIPE_FORMAT_R5G6B5_UNORM;
-       else
-               colour = PIPE_FORMAT_A8R8G8B8_UNORM;
-
-       if (glVis->depthBits == 16)
-               depth = PIPE_FORMAT_Z16_UNORM;
-       else if (glVis->depthBits == 24)
-               depth = PIPE_FORMAT_Z24S8_UNORM;
-       else
-               depth = PIPE_FORMAT_NONE;
-
-       if (glVis->stencilBits == 8)
-               stencil = PIPE_FORMAT_Z24S8_UNORM;
-       else
-               stencil = PIPE_FORMAT_NONE;
-
-       nvfb->stfb = st_create_framebuffer(glVis, colour, depth, stencil,
-                                          driDrawPriv->w, driDrawPriv->h,
-                                          (void*)nvfb);
-       if (!nvfb->stfb) {
-               free(nvfb);
-               return  GL_FALSE;
-       }
-
-       driDrawPriv->driverPrivate = (void *)nvfb;
-       return GL_TRUE;
-}
-
-static void
-nouveau_destroy_buffer(__DRIdrawablePrivate * driDrawPriv)
-{
-       struct nouveau_framebuffer *nvfb;
-       
-       nvfb = (struct nouveau_framebuffer *)driDrawPriv->driverPrivate;
-       st_unreference_framebuffer(nvfb->stfb);
-       free(nvfb);
-}
-
-static __DRIconfig **
-nouveau_fill_in_modes(__DRIscreenPrivate *psp,
-                     unsigned pixel_bits, unsigned depth_bits,
-                     unsigned stencil_bits, GLboolean have_back_buffer)
-{
-       __DRIconfig **configs;
-       unsigned depth_buffer_factor;
-       unsigned back_buffer_factor;
-       GLenum fb_format;
-       GLenum fb_type;
-
-       static const GLenum back_buffer_modes[] = {
-               GLX_NONE, GLX_SWAP_UNDEFINED_OML,
-       };
-
-       uint8_t depth_bits_array[3];
-       uint8_t stencil_bits_array[3];
-       uint8_t msaa_samples_array[1];
-
-       depth_bits_array[0] = 0;
-       depth_bits_array[1] = depth_bits;
-       depth_bits_array[2] = depth_bits;
-
-       /* Just like with the accumulation buffer, always provide some modes
-        * with a stencil buffer.  It will be a sw fallback, but some apps won't
-        * care about that.
-        */
-       stencil_bits_array[0] = 0;
-       stencil_bits_array[1] = 0;
-       if (depth_bits == 24)
-               stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
-       stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits;
-
-       msaa_samples_array[0] = 0;
-
-       depth_buffer_factor =
-               ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
-       back_buffer_factor = (have_back_buffer) ? 3 : 1;
-
-       if (pixel_bits == 16) {
-               fb_format = GL_RGB;
-               fb_type = GL_UNSIGNED_SHORT_5_6_5;
-       }
-       else {
-               fb_format = GL_BGRA;
-               fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-       }
-
-       configs = driCreateConfigs(fb_format, fb_type,
-                                  depth_bits_array, stencil_bits_array,
-                                  depth_buffer_factor, back_buffer_modes,
-                                  back_buffer_factor, msaa_samples_array, 1);
-       if (configs == NULL) {
-        fprintf(stderr, "[%s:%u] Error creating FBConfig!\n",
-                        __func__, __LINE__);
-               return NULL;
-       }
-
-       return configs;
-}
-
-static 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
deleted file mode 100644 (file)
index 1498087..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#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
index 3cac722b4a82a94b9293c034c289eac568dad463..9c841a0b2d086b467b730e6e7db3eaba3bc22cb5 100644 (file)
@@ -7,23 +7,25 @@
 #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_context.h"
+#include "nouveau_screen.h"
 #include "nouveau_swapbuffers.h"
 
+#include "nouveau_pushbuf.h"
+
 void
 nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
                    const drm_clip_rect_t *rect)
 {
-       struct nouveau_context_dri *nv = dPriv->driContextPriv->driverPrivate;
-       struct pipe_context *pipe = nv->base.nvc->pctx[nv->base.pctx_id];
+       struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate;
+       struct nouveau_screen *nv_screen = nv->dri_screen->private;
+       struct pipe_context *pipe = nv->st->pipe;
        drm_clip_rect_t *pbox;
        int nbox, i;
 
-       LOCK_HARDWARE(&nv->base);
+       LOCK_HARDWARE(nv);
        if (!dPriv->numClipRects) {
-               UNLOCK_HARDWARE(&nv->base);
+               UNLOCK_HARDWARE(nv);
                return;
        }
        pbox = dPriv->pClipRects;
@@ -39,12 +41,12 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
                w  = pbox->x2 - pbox->x1;
                h  = pbox->y2 - pbox->y1;
 
-               pipe->surface_copy(pipe, nv->base.frontbuffer,
-                                  dx, dy, surf, sx, sy, w, h);
+               pipe->surface_copy(pipe, nv_screen->fb, dx, dy, surf,
+                                  sx, sy, w, h);
        }
 
-       FIRE_RING(nv->base.nvc->channel);
-       UNLOCK_HARDWARE(&nv->base);
+       pipe->flush(pipe, 0, NULL);
+       UNLOCK_HARDWARE(nv);
 
        if (nv->last_stamp != dPriv->lastStamp) {
                struct nouveau_framebuffer *nvfb = dPriv->driverPrivate;
@@ -86,19 +88,19 @@ nouveau_swap_buffers(__DRIdrawablePrivate *dPriv)
 }
 
 void
-nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
+nouveau_flush_frontbuffer(struct pipe_screen *pscreen, struct pipe_surface *ps,
                          void *context_private)
 {
-       struct nouveau_context_dri *nv = context_private;
+       struct nouveau_context *nv = context_private;
        __DRIdrawablePrivate *dPriv = nv->dri_drawable;
 
-       nouveau_copy_buffer(dPriv, surf, NULL);
+       nouveau_copy_buffer(dPriv, ps, NULL);
 }
 
 void
 nouveau_contended_lock(struct nouveau_context *nv)
 {
-       struct nouveau_context_dri *nv_sub = (struct nouveau_context_dri*)nv;
+       struct nouveau_context *nv_sub = (struct nouveau_context*)nv;
        __DRIdrawablePrivate *dPriv = nv_sub->dri_drawable;
        __DRIscreenPrivate *sPriv = nv_sub->dri_screen;
 
index 825d3da6da539b979d2577f5b823e75ba95d938e..4ca9cc228313af78be2a5913ab42b82350b5c1ac 100644 (file)
@@ -1,10 +1,11 @@
 #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 *);
+void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *,
+                        const drm_clip_rect_t *);
+void nouveau_copy_sub_buffer(__DRIdrawablePrivate *, int x, int y, int w, int h);
+void nouveau_swap_buffers(__DRIdrawablePrivate *);
+void nouveau_flush_frontbuffer(struct pipe_screen *, struct pipe_surface *,
+                              void *context_private);
 
 #endif
diff --git a/src/gallium/winsys/drm/nouveau/dri2/Makefile b/src/gallium/winsys/drm/nouveau/dri2/Makefile
new file mode 100644 (file)
index 0000000..728870d
--- /dev/null
@@ -0,0 +1,26 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = nouveau_dri2.so
+
+PIPE_DRIVERS = \
+       $(TOP)/src/gallium/state_trackers/dri2/libdri2drm.a \
+       $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
+       $(TOP)/src/gallium/drivers/nv04/libnv04.a \
+       $(TOP)/src/gallium/drivers/nv10/libnv10.a \
+       $(TOP)/src/gallium/drivers/nv20/libnv20.a \
+       $(TOP)/src/gallium/drivers/nv30/libnv30.a \
+       $(TOP)/src/gallium/drivers/nv40/libnv40.a \
+       $(TOP)/src/gallium/drivers/nv50/libnv50.a
+
+DRIVER_SOURCES =
+
+C_SOURCES = \
+       $(COMMON_GALLIUM_SOURCES) \
+       $(DRIVER_SOURCES)
+
+include ../../Makefile.template
+
+DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs)
+
+symlinks:
diff --git a/src/gallium/winsys/drm/nouveau/drm/Makefile b/src/gallium/winsys/drm/nouveau/drm/Makefile
new file mode 100644 (file)
index 0000000..2da78d8
--- /dev/null
@@ -0,0 +1,13 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = nouveaudrm
+
+C_SOURCES = nouveau_drm_api.c \
+           nouveau_winsys_pipe.c \
+           nouveau_winsys.c
+
+LIBRARY_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I)
+LIBRARY_DEFINES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-other)
+
+include ../../../../Makefile.template
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
new file mode 100644 (file)
index 0000000..c0127e8
--- /dev/null
@@ -0,0 +1,194 @@
+#include "util/u_memory.h"
+
+#include "nouveau_drm_api.h"
+#include "nouveau_winsys_pipe.h"
+
+#include "nouveau_drmif.h"
+#include "nouveau_channel.h"
+#include "nouveau_bo.h"
+
+static struct pipe_screen *
+nouveau_drm_create_screen(int fd, int pciid)
+{
+       struct pipe_winsys *ws;
+       struct nouveau_winsys *nvws;
+       struct nouveau_device *dev = NULL;
+       struct pipe_screen *(*init)(struct pipe_winsys *,
+                                   struct nouveau_winsys *);
+       int ret;
+
+       ret = nouveau_device_open_existing(&dev, 0, fd, 0);
+       if (ret)
+               return NULL;
+
+       switch (dev->chipset & 0xf0) {
+       case 0x00:
+               init = nv04_screen_create;
+               break;
+       case 0x10:
+               init = nv10_screen_create;
+               break;
+       case 0x20:
+               init = nv20_screen_create;
+               break;
+       case 0x30:
+               init = nv30_screen_create;
+               break;
+       case 0x40:
+       case 0x60:
+               init = nv40_screen_create;
+               break;
+       case 0x80:
+       case 0x90:
+       case 0xa0:
+               init = nv50_screen_create;
+               break;
+       default:
+               debug_printf("%s: unknown chipset nv%02x\n", __func__,
+                            dev->chipset);
+               return NULL;
+       }
+
+       ws = nouveau_pipe_winsys_new(dev);
+       if (!ws) {
+               nouveau_device_close(&dev);
+               return NULL;
+       }
+
+       nvws = nouveau_winsys_new(ws);
+       if (!nvws) {
+               ws->destroy(ws);
+               return NULL;
+       }
+
+       nouveau_pipe_winsys(ws)->pscreen = init(ws, nvws);
+       if (!nouveau_pipe_winsys(ws)->pscreen) {
+               ws->destroy(ws);
+               return NULL;
+       }
+
+       return nouveau_pipe_winsys(ws)->pscreen;
+}
+
+static struct pipe_context *
+nouveau_drm_create_context(struct pipe_screen *pscreen)
+{
+       struct nouveau_pipe_winsys *nvpws = nouveau_screen(pscreen);
+       struct pipe_context *(*init)(struct pipe_screen *, unsigned);
+       unsigned chipset = nvpws->channel->device->chipset;
+       int i;
+
+       switch (chipset & 0xf0) {
+       case 0x00:
+               init = nv04_create;
+               break;
+       case 0x10:
+               init = nv10_create;
+               break;
+       case 0x20:
+               init = nv20_create;
+               break;
+       case 0x30:
+               init = nv30_create;
+               break;
+       case 0x40:
+       case 0x60:
+               init = nv40_create;
+               break;
+       case 0x80:
+       case 0x90:
+       case 0xa0:
+               init = nv50_create;
+               break;
+       default:
+               debug_printf("%s: unknown chipset nv%02x\n", __func__, chipset);
+               return NULL;
+       }
+
+       /* Find a free slot for a pipe context, allocate a new one if needed */
+       for (i = 0; i < nvpws->nr_pctx; i++) {
+               if (nvpws->pctx[i] == NULL)
+                       break;
+       }
+
+       if (i == nvpws->nr_pctx) {
+               nvpws->nr_pctx++;
+               nvpws->pctx = realloc(nvpws->pctx,
+                                     sizeof(*nvpws->pctx) * nvpws->nr_pctx);
+       }
+
+       nvpws->pctx[i] = init(pscreen, i);
+       return nvpws->pctx[i];
+}
+
+static boolean
+nouveau_drm_pb_from_pt(struct pipe_texture *pt, struct pipe_buffer **ppb,
+                      unsigned *stride)
+{
+       return false;
+}
+
+static struct pipe_buffer *
+nouveau_drm_pb_from_handle(struct pipe_screen *pscreen, const char *name,
+                          unsigned handle)
+{
+       struct nouveau_pipe_winsys *nvpws = nouveau_screen(pscreen);
+       struct nouveau_device *dev = nvpws->channel->device;
+       struct nouveau_pipe_buffer *nvpb;
+       int ret;
+
+       nvpb = CALLOC_STRUCT(nouveau_pipe_buffer);
+       if (!nvpb)
+               return NULL;
+
+       ret = nouveau_bo_handle_ref(dev, handle, &nvpb->bo);
+       if (ret) {
+               debug_printf("%s: ref name 0x%08x failed with %d\n",
+                            __func__, handle, ret);
+               FREE(nvpb);
+               return NULL;
+       }
+
+       pipe_reference_init(&nvpb->base.reference, 1);
+       nvpb->base.screen = pscreen;
+       nvpb->base.alignment = 0;
+       nvpb->base.usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
+                          PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+       nvpb->base.size = nvpb->bo->size;
+       return &nvpb->base;
+}
+
+static boolean
+nouveau_drm_handle_from_pb(struct pipe_screen *pscreen, struct pipe_buffer *pb,
+                          unsigned *handle)
+{
+       struct nouveau_pipe_buffer *nvpb = nouveau_pipe_buffer(pb);
+
+       if (!nvpb)
+               return FALSE;
+
+       *handle = nvpb->bo->handle;
+       return TRUE;
+}
+
+static boolean
+nouveau_drm_name_from_pb(struct pipe_screen *pscreen, struct pipe_buffer *pb,
+                        unsigned *handle)
+{
+       struct nouveau_pipe_buffer *nvpb = nouveau_pipe_buffer(pb);
+
+       if (!nvpb)
+               return FALSE;
+
+       return nouveau_bo_handle_get(nvpb->bo, handle) == 0;
+}
+
+struct drm_api drm_api_hooks = {
+       .create_screen = nouveau_drm_create_screen,
+       .create_context = nouveau_drm_create_context,
+       .buffer_from_texture = nouveau_drm_pb_from_pt,
+       .buffer_from_handle = nouveau_drm_pb_from_handle,
+       .handle_from_buffer = nouveau_drm_handle_from_pb,
+       .global_handle_from_buffer = nouveau_drm_name_from_pb,
+};
+
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
new file mode 100644 (file)
index 0000000..2782c83
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef __NOUVEAU_DRM_API_H__
+#define __NOUVEAU_DRM_API_H__
+#include "state_tracker/drm_api.h"
+
+#endif
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c
new file mode 100644 (file)
index 0000000..e3175fd
--- /dev/null
@@ -0,0 +1,94 @@
+#include "util/u_memory.h"
+
+#include "nouveau_winsys_pipe.h"
+
+static int
+nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count,
+                           struct nouveau_notifier **notify)
+{
+       struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(nvws->ws);
+
+       return nouveau_notifier_alloc(nvpws->channel, nvpws->next_handle++,
+                                     count, notify);
+}
+
+static int
+nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass,
+                        struct nouveau_grobj **grobj)
+{
+       struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(nvws->ws);
+       struct nouveau_channel *chan = nvpws->channel;
+       int ret;
+
+       ret = nouveau_grobj_alloc(chan, nvpws->next_handle++, grclass, grobj);
+       if (ret)
+               return ret;
+
+       BEGIN_RING(chan, *grobj, 0x0000, 1);
+       OUT_RING  (chan, (*grobj)->handle);
+       (*grobj)->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT;
+       return 0;
+}
+
+static int
+nouveau_pipe_push_reloc(struct nouveau_winsys *nvws, void *ptr,
+                       struct pipe_buffer *buf, uint32_t data,
+                       uint32_t flags, uint32_t vor, uint32_t tor)
+{
+       struct nouveau_bo *bo = nouveau_pipe_buffer(buf)->bo;
+
+       return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, bo,
+                                         data, flags, vor, tor);
+}
+
+static int
+nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size,
+                       struct pipe_fence_handle **fence)
+{
+       if (fence)
+               *fence = NULL;
+
+       return nouveau_pushbuf_flush(nvws->channel, size);
+}
+
+static struct nouveau_bo *
+nouveau_pipe_get_bo(struct pipe_buffer *pb)
+{
+       return nouveau_pipe_buffer(pb)->bo;
+}
+
+struct nouveau_winsys *
+nouveau_winsys_new(struct pipe_winsys *ws)
+{
+       struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
+       struct nouveau_winsys *nvws;
+
+       nvws = CALLOC_STRUCT(nouveau_winsys);
+       if (!nvws)
+               return NULL;
+
+       nvws->ws                = ws;
+       nvws->channel           = nvpws->channel;
+
+       nvws->res_init          = nouveau_resource_init;
+       nvws->res_alloc         = nouveau_resource_alloc;
+       nvws->res_free          = nouveau_resource_free;
+
+       nvws->push_reloc        = nouveau_pipe_push_reloc;
+       nvws->push_flush        = nouveau_pipe_push_flush;
+
+       nvws->grobj_alloc       = nouveau_pipe_grobj_alloc;
+       nvws->grobj_free        = nouveau_grobj_free;
+
+       nvws->notifier_alloc    = nouveau_pipe_notifier_alloc;
+       nvws->notifier_free     = nouveau_notifier_free;
+       nvws->notifier_reset    = nouveau_notifier_reset;
+       nvws->notifier_status   = nouveau_notifier_status;
+       nvws->notifier_retval   = nouveau_notifier_return_val;
+       nvws->notifier_wait     = nouveau_notifier_wait_status;
+
+       nvws->get_bo            = nouveau_pipe_get_bo;
+
+       return nvws;
+}
+
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c
new file mode 100644 (file)
index 0000000..9e03a9f
--- /dev/null
@@ -0,0 +1,204 @@
+#include "pipe/internal/p_winsys_screen.h"
+#include <pipe/p_defines.h>
+#include <pipe/p_inlines.h>
+#include <util/u_memory.h>
+
+#include "nouveau_winsys_pipe.h"
+
+#include "nouveau_drmif.h"
+#include "nouveau_bo.h"
+
+static const char *
+nouveau_get_name(struct pipe_winsys *pws)
+{
+       return "Nouveau/DRI";
+}
+
+static uint32_t
+nouveau_flags_from_usage(struct pipe_winsys *ws, unsigned usage)
+{
+       struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
+       struct pipe_screen *pscreen = nvpws->pscreen;
+       uint32_t flags = NOUVEAU_BO_LOCAL;
+
+       if (usage & NOUVEAU_BUFFER_USAGE_TRANSFER)
+               flags |= NOUVEAU_BO_GART;
+
+       if (usage & PIPE_BUFFER_USAGE_PIXEL) {
+               if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
+                       flags |= NOUVEAU_BO_GART;
+               if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE))
+                       flags |= NOUVEAU_BO_VRAM;
+
+               switch (nvpws->channel->device->chipset & 0xf0) {
+               case 0x50:
+               case 0x80:
+               case 0x90:
+                       flags |= NOUVEAU_BO_TILED;
+                       if (usage & NOUVEAU_BUFFER_USAGE_ZETA)
+                               flags |= NOUVEAU_BO_ZTILE;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if (usage & PIPE_BUFFER_USAGE_VERTEX) {
+               if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF))
+                       flags |= NOUVEAU_BO_GART;
+       }
+
+       if (usage & PIPE_BUFFER_USAGE_INDEX) {
+               if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF))
+                       flags |= NOUVEAU_BO_GART;
+       }
+
+       return flags;
+}
+
+static struct pipe_buffer *
+nouveau_pipe_bo_create(struct pipe_winsys *ws, unsigned alignment,
+                      unsigned usage, unsigned size)
+{
+       struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
+       struct nouveau_device *dev = nvpws->channel->device;
+       struct nouveau_pipe_buffer *nvbuf;
+       uint32_t flags;
+
+       nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
+       if (!nvbuf)
+               return NULL;
+       pipe_reference_init(&nvbuf->base.reference, 1);
+       nvbuf->base.alignment = alignment;
+       nvbuf->base.usage = usage;
+       nvbuf->base.size = size;
+
+       flags = nouveau_flags_from_usage(ws, usage);
+       if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
+               FREE(nvbuf);
+               return NULL;
+       }
+
+       return &nvbuf->base;
+}
+
+static struct pipe_buffer *
+nouveau_pipe_bo_user_create(struct pipe_winsys *ws, void *ptr, unsigned bytes)
+{
+       struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
+       struct nouveau_device *dev = nvpws->channel->device;
+       struct nouveau_pipe_buffer *nvbuf;
+
+       nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
+       if (!nvbuf)
+               return NULL;
+       pipe_reference_init(&nvbuf->base.reference, 1);
+       nvbuf->base.size = bytes;
+
+       if (nouveau_bo_user(dev, ptr, bytes, &nvbuf->bo)) {
+               FREE(nvbuf);
+               return NULL;
+       }
+
+       return &nvbuf->base;
+}
+
+static void
+nouveau_pipe_bo_del(struct pipe_buffer *buf)
+{
+       struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);
+
+       nouveau_bo_ref(NULL, &nvbuf->bo);
+       FREE(nvbuf);
+}
+
+static void *
+nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
+                   unsigned flags)
+{
+       struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);
+       uint32_t map_flags = 0;
+
+       if (flags & PIPE_BUFFER_USAGE_CPU_READ)
+               map_flags |= NOUVEAU_BO_RD;
+       if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
+               map_flags |= NOUVEAU_BO_WR;
+
+       if (nouveau_bo_map(nvbuf->bo, map_flags))
+               return NULL;
+       return nvbuf->bo->map;
+}
+
+static void
+nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
+{
+       struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);
+
+       nouveau_bo_unmap(nvbuf->bo);
+}
+
+static void
+nouveau_pipe_fence_reference(struct pipe_winsys *ws,
+                            struct pipe_fence_handle **ptr,
+                            struct pipe_fence_handle *pfence)
+{
+       *ptr = pfence;
+}
+
+static int
+nouveau_pipe_fence_signalled(struct pipe_winsys *ws,
+                            struct pipe_fence_handle *pfence, unsigned flag)
+{
+       return 0;
+}
+
+static int
+nouveau_pipe_fence_finish(struct pipe_winsys *ws,
+                         struct pipe_fence_handle *pfence, unsigned flag)
+{
+       return 0;
+}
+
+static void
+nouveau_destroy(struct pipe_winsys *ws)
+{
+       struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
+
+       nouveau_device_close(&nvpws->channel->device);
+       FREE(nvpws);
+}
+
+struct pipe_winsys *
+nouveau_pipe_winsys_new(struct nouveau_device *dev)
+{
+       struct nouveau_pipe_winsys *nvpws;
+       int ret;
+
+       nvpws = CALLOC_STRUCT(nouveau_pipe_winsys);
+       if (!nvpws)
+               return NULL;
+
+       ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202,
+                                   &nvpws->channel);
+       if (ret) {
+               debug_printf("%s: error opening GPU channel: %d\n",
+                            __func__, ret);
+               FREE(nvpws);
+               return NULL;
+       }
+       nvpws->next_handle = 0x77000000;
+
+       nvpws->base.buffer_create = nouveau_pipe_bo_create;
+       nvpws->base.buffer_destroy = nouveau_pipe_bo_del;
+       nvpws->base.user_buffer_create = nouveau_pipe_bo_user_create;
+       nvpws->base.buffer_map = nouveau_pipe_bo_map;
+       nvpws->base.buffer_unmap = nouveau_pipe_bo_unmap;
+
+       nvpws->base.fence_reference = nouveau_pipe_fence_reference;
+       nvpws->base.fence_signalled = nouveau_pipe_fence_signalled;
+       nvpws->base.fence_finish = nouveau_pipe_fence_finish;
+
+       nvpws->base.get_name = nouveau_get_name;
+       nvpws->base.destroy = nouveau_destroy;
+       return &nvpws->base;
+}
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h
new file mode 100644 (file)
index 0000000..10e1e26
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef NOUVEAU_PIPE_WINSYS_H
+#define NOUVEAU_PIPE_WINSYS_H
+
+#include "pipe/internal/p_winsys_screen.h"
+#include "pipe/p_context.h"
+
+#include "nouveau/nouveau_winsys.h"
+
+#include "nouveau_device.h"
+
+struct nouveau_pipe_buffer {
+       struct pipe_buffer base;
+       struct nouveau_bo *bo;
+};
+
+static INLINE struct nouveau_pipe_buffer *
+nouveau_pipe_buffer(struct pipe_buffer *buf)
+{
+       return (struct nouveau_pipe_buffer *)buf;
+}
+
+struct nouveau_pipe_winsys {
+       struct pipe_winsys base;
+
+       struct pipe_screen *pscreen;
+
+       struct nouveau_channel *channel;
+       uint32_t next_handle;
+
+       unsigned nr_pctx;
+       struct pipe_context **pctx;
+};
+
+static INLINE struct nouveau_pipe_winsys *
+nouveau_pipe_winsys(struct pipe_winsys *ws)
+{
+       return (struct nouveau_pipe_winsys *)ws;
+}
+
+static INLINE struct nouveau_pipe_winsys *
+nouveau_screen(struct pipe_screen *pscreen)
+{
+       return nouveau_pipe_winsys(pscreen->winsys);
+}
+
+struct pipe_winsys *
+nouveau_pipe_winsys_new(struct nouveau_device *);
+
+struct nouveau_winsys *
+nouveau_winsys_new(struct pipe_winsys *ws);
+
+#endif