#define NOUVEAU_BUFFER_USAGE_TRANSFER (1 << 18)
struct nouveau_winsys {
- struct nouveau_context *nv;
+ struct pipe_winsys *ws;
struct nouveau_channel *channel;
TOP = ../../../../..
include $(TOP)/configs/current
-SUBDIRS = common dri
+SUBDIRS = drm dri dri2
default install clean:
@for dir in $(SUBDIRS) ; do \
+++ /dev/null
-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
+++ /dev/null
-#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? */
-}
-
+++ /dev/null
-#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
+++ /dev/null
-#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
-
+++ /dev/null
-#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
+++ /dev/null
-/**************************************************************************
- *
- * 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);
-}
+++ /dev/null
-#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);
-}
+++ /dev/null
-#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
+++ /dev/null
-#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];
-}
-
+++ /dev/null
-#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;
-}
+++ /dev/null
-#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
+++ /dev/null
-/**************************************************************************
- *
- * 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;
-}
-
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 \
$(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) \
--- /dev/null
+#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;
+}
+
--- /dev/null
+#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
+++ /dev/null
-#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;
-}
-
+++ /dev/null
-#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
--- /dev/null
+#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
+
--- /dev/null
+/**************************************************************************
+ *
+ * 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);
+}
--- /dev/null
+#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! */
+};
+
--- /dev/null
+#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
+++ /dev/null
-#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! */
-};
-
+++ /dev/null
-#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
#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;
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;
}
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;
#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
--- /dev/null
+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:
--- /dev/null
+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
--- /dev/null
+#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,
+};
+
--- /dev/null
+#ifndef __NOUVEAU_DRM_API_H__
+#define __NOUVEAU_DRM_API_H__
+#include "state_tracker/drm_api.h"
+
+#endif
--- /dev/null
+#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;
+}
+
--- /dev/null
+#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;
+}
--- /dev/null
+#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