summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/drm/nouveau
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2009-03-18 08:22:35 +1000
committerBen Skeggs <bskeggs@redhat.com>2009-03-18 09:44:40 +1000
commite00ae524e236afba1305150cacd634eaa1f5460b (patch)
treee6173fc3a85b6f6b66691e4a880257a39764fd6e /src/gallium/winsys/drm/nouveau
parentb46fcf25be4d1d5a5d072fbce03c2490bf41203f (diff)
nouveau: rewrite winsys in terms of drm_api, support dri2 state tracker
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.
Diffstat (limited to 'src/gallium/winsys/drm/nouveau')
-rw-r--r--src/gallium/winsys/drm/nouveau/Makefile2
-rw-r--r--src/gallium/winsys/drm/nouveau/common/Makefile22
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_context.c206
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_context.h59
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_local.h19
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_screen.c31
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_screen.h27
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h44
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c101
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/Makefile8
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_context.c (renamed from src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c)62
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_context.h (renamed from src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h)14
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h (renamed from src/gallium/winsys/drm/nouveau/common/nouveau_dri.h)0
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c (renamed from src/gallium/winsys/drm/nouveau/common/nouveau_lock.c)5
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c (renamed from src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c)94
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h (renamed from src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h)9
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c32
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h11
-rw-r--r--src/gallium/winsys/drm/nouveau/dri2/Makefile26
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/Makefile13
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c194
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h5
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c (renamed from src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c)78
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c (renamed from src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c)135
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h52
25 files changed, 504 insertions, 745 deletions
diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile
index 652cf7146c..f8c8135854 100644
--- a/src/gallium/winsys/drm/nouveau/Makefile
+++ b/src/gallium/winsys/drm/nouveau/Makefile
@@ -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
index f675f7caf1..0000000000
--- a/src/gallium/winsys/drm/nouveau/common/Makefile
+++ /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
index fbe57eacf2..0000000000
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c
+++ /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
index ba8fc3ad2d..0000000000
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h
+++ /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_local.h b/src/gallium/winsys/drm/nouveau/common/nouveau_local.h
deleted file mode 100644
index 11175bce7a..0000000000
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_local.h
+++ /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_screen.c b/src/gallium/winsys/drm/nouveau/common/nouveau_screen.c
deleted file mode 100644
index 422fbf0207..0000000000
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_screen.c
+++ /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
index 3e68e219d8..0000000000
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_screen.h
+++ /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_pipe.h b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h
deleted file mode 100644
index 1eb8043478..0000000000
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h
+++ /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
index 396e4f2a2e..0000000000
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c
+++ /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;
-}
-
diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/winsys/drm/nouveau/dri/Makefile
index a73e8d5cb4..f7db6201fe 100644
--- a/src/gallium/winsys/drm/nouveau/dri/Makefile
+++ b/src/gallium/winsys/drm/nouveau/dri/Makefile
@@ -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_dri.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c
index aacfe984d1..deb6ffcff1 100644
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c
@@ -5,23 +5,15 @@
#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 "../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"
+#include "nouveau_context.h"
+#include "nouveau_screen.h"
-#ifdef DEBUG
-static const struct dri_debug_control debug_control[] = {
- { "bo", DEBUG_BO },
- { NULL, 0 }
-};
-int __nouveau_debug = 0;
-#endif
+#include "nouveau_drmif.h"
GLboolean
nouveau_context_create(const __GLcontextModes *glVis,
@@ -29,34 +21,38 @@ nouveau_context_create(const __GLcontextModes *glVis,
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 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_dri *)sharedContextPrivate)->st;
- nv_share = st_share->pipe->priv;
+ 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;
}
- if (nouveau_context_init(&nv_screen->base, driContextPriv->hHWContext,
- (drmLock *)&driScrnPriv->pSAREA->lock,
- &nv_share->base, &nv->base)) {
+ pipe = drm_api_hooks.create_context(nv_screen->pscreen);
+ if (!pipe) {
+ FREE(nv);
return GL_FALSE;
}
+ pipe->priv = nv;
- pipe = nv->base.nvc->pctx[nv->base.pctx_id];
- driContextPriv->driverPrivate = (void *)nv;
- //nv->nv_screen = nv_screen;
+ driContextPriv->driverPrivate = nv;
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;
@@ -65,15 +61,13 @@ nouveau_context_create(const __GLcontextModes *glVis,
void
nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
{
- struct nouveau_context_dri *nv = driContextPriv->driverPrivate;
+ struct nouveau_context *nv = driContextPriv->driverPrivate;
assert(nv);
st_finish(nv->st);
st_destroy_context(nv->st);
- nouveau_context_cleanup(&nv->base);
-
FREE(nv);
}
@@ -82,7 +76,7 @@ nouveau_context_bind(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv)
{
- struct nouveau_context_dri *nv;
+ struct nouveau_context *nv;
struct nouveau_framebuffer *draw, *read;
if (!driContextPriv) {
@@ -115,7 +109,7 @@ nouveau_context_bind(__DRIcontextPrivate *driContextPriv,
GLboolean
nouveau_context_unbind(__DRIcontextPrivate *driContextPriv)
{
- struct nouveau_context_dri *nv = driContextPriv->driverPrivate;
+ struct nouveau_context *nv = driContextPriv->driverPrivate;
(void)nv;
st_flush(nv->st, 0, NULL);
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h
index 64cf326411..2779b092e6 100644
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h
@@ -3,15 +3,16 @@
#include <dri_util.h>
#include <xmlconfig.h>
-#include <nouveau/nouveau_winsys.h>
-#include "../common/nouveau_context.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_dri {
- struct nouveau_context base;
+struct nouveau_context {
struct st_context *st;
/* DRI stuff */
@@ -21,6 +22,7 @@ struct nouveau_context_dri {
driOptionCache dri_option_cache;
drm_context_t drm_context;
drmLock drm_lock;
+ int locked;
};
extern GLboolean nouveau_context_create(const __GLcontextModes *,
@@ -31,6 +33,10 @@ extern GLboolean nouveau_context_bind(__DRIcontextPrivate *,
__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;
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h
index 1207c2d609..1207c2d609 100644
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_dri.h
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_lock.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c
index e8cf051ed9..92f5bd09c9 100644
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_lock.c
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c
@@ -28,6 +28,7 @@
#include <pipe/p_thread.h>
#include "nouveau_context.h"
#include "nouveau_screen.h"
+#include "nouveau_drmif.h"
pipe_static_mutex(lockMutex);
@@ -36,7 +37,7 @@ pipe_static_mutex(lockMutex);
void
LOCK_HARDWARE(struct nouveau_context *nv)
{
- struct nouveau_screen *nv_screen = nv->nv_screen;
+ 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;
@@ -59,7 +60,7 @@ LOCK_HARDWARE(struct nouveau_context *nv)
void
UNLOCK_HARDWARE(struct nouveau_context *nv)
{
- struct nouveau_screen *nv_screen = nv->nv_screen;
+ struct nouveau_screen *nv_screen = nv->dri_screen->private;
struct nouveau_device *dev = nv_screen->device;
struct nouveau_device_priv *nvdev = nouveau_device(dev);
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c
index 964a9028aa..c4cbbc2124 100644
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c
@@ -5,12 +5,15 @@
#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 <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
@@ -178,11 +181,58 @@ nouveau_fill_in_modes(__DRIscreenPrivate *psp,
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_dri *nv_screen;
+ struct nouveau_screen *nv_screen;
static const __DRIversion ddx_expected =
{ 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
static const __DRIversion dri_expected = { 4, 0, 0 };
@@ -210,17 +260,38 @@ nouveau_screen_create(__DRIscreenPrivate *psp)
return NULL;
}
- nv_screen = CALLOC_STRUCT(nouveau_screen_dri);
+ nv_screen = CALLOC_STRUCT(nouveau_screen);
if (!nv_screen)
return NULL;
- driParseOptionInfo(&nv_screen->option_cache,
- __driConfigOptions, __driNConfigOptions);
+ nouveau_device_open_existing(&nv_screen->device, 0, psp->fd, 0);
- if (nouveau_screen_init(nv_dri, psp->fd, &nv_screen->base)) {
+ 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;
@@ -234,10 +305,9 @@ nouveau_screen_create(__DRIscreenPrivate *psp)
static void
nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv)
{
- struct nouveau_screen_dri *nv_screen = driScrnPriv->private;
+ struct nouveau_screen *nv_screen = driScrnPriv->private;
driScrnPriv->private = NULL;
- nouveau_screen_cleanup(&nv_screen->base);
FREE(nv_screen);
}
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h
index 1498087819..ac078f3c63 100644
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h
@@ -1,13 +1,16 @@
#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;
+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_swapbuffers.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c
index 3cac722b4a..9c841a0b2d 100644
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c
@@ -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;
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h
index 825d3da6da..4ca9cc2283 100644
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h
@@ -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
index 0000000000..728870d2e1
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/dri2/Makefile
@@ -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
index 0000000000..2da78d8690
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/drm/Makefile
@@ -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
index 0000000000..c0127e803f
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
@@ -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
index 0000000000..2782c83c0e
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
@@ -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/common/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c
index 52c3b02247..e3175fd775 100644
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c
@@ -1,18 +1,14 @@
#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;
+ struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(nvws->ws);
- return nouveau_notifier_alloc(nv->nvc->channel, nv->nvc->next_handle++,
+ return nouveau_notifier_alloc(nvpws->channel, nvpws->next_handle++,
count, notify);
}
@@ -20,12 +16,11 @@ 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;
+ struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(nvws->ws);
+ struct nouveau_channel *chan = nvpws->channel;
int ret;
- ret = nouveau_grobj_alloc(chan, nv->nvc->next_handle++,
- grclass, grobj);
+ ret = nouveau_grobj_alloc(chan, nvpws->next_handle++, grclass, grobj);
if (ret)
return ret;
@@ -62,55 +57,18 @@ 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_winsys *
+nouveau_winsys_new(struct pipe_winsys *ws)
{
- 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;
+ struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
+ struct nouveau_winsys *nvws;
+ nvws = CALLOC_STRUCT(nouveau_winsys);
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->ws = ws;
+ nvws->channel = nvpws->channel;
nvws->res_init = nouveau_resource_init;
nvws->res_alloc = nouveau_resource_alloc;
@@ -131,16 +89,6 @@ nouveau_pipe_create(struct nouveau_context *nv)
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];
+ return nvws;
}
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c
index 24bbd4516f..9e03a9f5db 100644
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c
@@ -2,11 +2,12 @@
#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"
+#include "nouveau_drmif.h"
+#include "nouveau_bo.h"
+
static const char *
nouveau_get_name(struct pipe_winsys *pws)
{
@@ -14,9 +15,10 @@ nouveau_get_name(struct pipe_winsys *pws)
}
static uint32_t
-nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
+nouveau_flags_from_usage(struct pipe_winsys *ws, unsigned usage)
{
- struct nouveau_device *dev = nv->nv_screen->device;
+ 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)
@@ -28,7 +30,7 @@ nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE))
flags |= NOUVEAU_BO_VRAM;
- switch (dev->chipset & 0xf0) {
+ switch (nvpws->channel->device->chipset & 0xf0) {
case 0x50:
case 0x80:
case 0x90:
@@ -42,12 +44,12 @@ nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
}
if (usage & PIPE_BUFFER_USAGE_VERTEX) {
- if (nv->cap.hw_vertex_buffer)
+ if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF))
flags |= NOUVEAU_BO_GART;
}
if (usage & PIPE_BUFFER_USAGE_INDEX) {
- if (nv->cap.hw_index_buffer)
+ if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF))
flags |= NOUVEAU_BO_GART;
}
@@ -55,12 +57,11 @@ nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
}
static struct pipe_buffer *
-nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
+nouveau_pipe_bo_create(struct pipe_winsys *ws, 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_winsys *nvpws = nouveau_pipe_winsys(ws);
+ struct nouveau_device *dev = nvpws->channel->device;
struct nouveau_pipe_buffer *nvbuf;
uint32_t flags;
@@ -72,8 +73,7 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
nvbuf->base.usage = usage;
nvbuf->base.size = size;
- flags = nouveau_flags_from_usage(nv, usage);
-
+ flags = nouveau_flags_from_usage(ws, usage);
if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
FREE(nvbuf);
return NULL;
@@ -83,10 +83,10 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
}
static struct pipe_buffer *
-nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
+nouveau_pipe_bo_user_create(struct pipe_winsys *ws, 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_winsys *nvpws = nouveau_pipe_winsys(ws);
+ struct nouveau_device *dev = nvpws->channel->device;
struct nouveau_pipe_buffer *nvbuf;
nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
@@ -119,34 +119,11 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
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;
@@ -182,70 +159,46 @@ nouveau_pipe_fence_finish(struct pipe_winsys *ws,
return 0;
}
-struct pipe_surface *
-nouveau_surface_buffer_ref(struct nouveau_context *nv, struct pipe_buffer *pb,
- enum pipe_format format, int w, int h,
- unsigned pitch, struct pipe_texture **ppt)
-{
- struct pipe_screen *pscreen = nv->nvc->pscreen;
- struct pipe_texture tmpl, *pt;
- struct pipe_surface *ps;
-
- memset(&tmpl, 0, sizeof(tmpl));
- tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- NOUVEAU_TEXTURE_USAGE_LINEAR;
- tmpl.target = PIPE_TEXTURE_2D;
- tmpl.width[0] = w;
- tmpl.height[0] = h;
- tmpl.depth[0] = 1;
- tmpl.format = format;
- pf_get_block(tmpl.format, &tmpl.block);
- tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w);
- tmpl.nblocksy[0] = pf_get_nblocksy(&tmpl.block, h);
-
- pt = pscreen->texture_blanket(pscreen, &tmpl, &pitch, pb);
- if (!pt)
- return NULL;
-
- ps = pscreen->get_tex_surface(pscreen, pt, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- *ppt = pt;
- return ps;
-}
-
static void
-nouveau_destroy(struct pipe_winsys *pws)
+nouveau_destroy(struct pipe_winsys *ws)
{
- FREE(pws);
+ struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
+
+ nouveau_device_close(&nvpws->channel->device);
+ FREE(nvpws);
}
struct pipe_winsys *
-nouveau_create_pipe_winsys(struct nouveau_context *nv)
+nouveau_pipe_winsys_new(struct nouveau_device *dev)
{
struct nouveau_pipe_winsys *nvpws;
- struct pipe_winsys *pws;
+ int ret;
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;
+ 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;
- pws->fence_reference = nouveau_pipe_fence_reference;
- pws->fence_signalled = nouveau_pipe_fence_signalled;
- pws->fence_finish = nouveau_pipe_fence_finish;
+ 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;
- pws->get_name = nouveau_get_name;
- pws->destroy = nouveau_destroy;
+ nvpws->base.fence_reference = nouveau_pipe_fence_reference;
+ nvpws->base.fence_signalled = nouveau_pipe_fence_signalled;
+ nvpws->base.fence_finish = nouveau_pipe_fence_finish;
- return &nvpws->pws;
+ 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
index 0000000000..10e1e269e8
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h
@@ -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