summaryrefslogtreecommitdiff
path: root/src/gallium/winsys
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys')
-rw-r--r--src/gallium/winsys/drm/nouveau/Makefile65
-rw-r--r--src/gallium/winsys/drm/nouveau/common/Makefile32
-rw-r--r--src/gallium/winsys/drm/nouveau/common/Makefile.template59
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_bo.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_bo.c)34
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_channel.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_channel.c)14
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_context.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_context.c)130
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_context.h (renamed from src/gallium/winsys/drm/nouveau/nouveau_context.h)47
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_device.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_device.c)6
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_dma.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_dma.c)0
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_dma.h (renamed from src/gallium/winsys/drm/nouveau/nouveau_dma.h)0
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_dri.h (renamed from src/gallium/winsys/drm/nouveau/nouveau_dri.h)0
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h (renamed from src/gallium/winsys/drm/nouveau/nouveau_drmif.h)3
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_fence.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_fence.c)0
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_grobj.c)8
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_local.h (renamed from src/gallium/winsys/drm/nouveau/nouveau_local.h)2
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_lock.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_lock.c)50
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_notifier.c)0
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c)7
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_resource.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_resource.c)12
-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.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_winsys.c)0
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c)103
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h (renamed from src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h)5
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c)35
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nv04_surface.c (renamed from src/gallium/winsys/drm/nouveau/nv04_surface.c)90
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nv50_surface.c (renamed from src/gallium/winsys/drm/nouveau/nv50_surface.c)0
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/Makefile31
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c124
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h49
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_screen.c)52
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h13
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c (renamed from src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c)58
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h (renamed from src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h)0
-rw-r--r--src/gallium/winsys/drm/nouveau/nouveau_screen.h20
-rw-r--r--src/gallium/winsys/g3dvl/nouveau/Makefile48
-rw-r--r--src/gallium/winsys/g3dvl/nouveau/nouveau_context.c370
-rw-r--r--src/gallium/winsys/g3dvl/nouveau/nouveau_context.h105
-rw-r--r--src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.c172
-rw-r--r--src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.h39
-rw-r--r--src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c8
-rw-r--r--src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c (renamed from src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c)45
-rw-r--r--src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.h (renamed from src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h)20
-rw-r--r--src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c61
-rw-r--r--src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c63
45 files changed, 1079 insertions, 959 deletions
diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile
index 81562ca78d..b5735329ec 100644
--- a/src/gallium/winsys/drm/nouveau/Makefile
+++ b/src/gallium/winsys/drm/nouveau/Makefile
@@ -1,46 +1,25 @@
-
TOP = ../../../../..
include $(TOP)/configs/current
-LIBNAME = nouveau_dri.so
-
-MINIGLX_SOURCES =
-
-PIPE_DRIVERS = \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
- $(TOP)/src/gallium/drivers/nv04/libnv04.a \
- $(TOP)/src/gallium/drivers/nv10/libnv10.a \
- $(TOP)/src/gallium/drivers/nv20/libnv20.a \
- $(TOP)/src/gallium/drivers/nv30/libnv30.a \
- $(TOP)/src/gallium/drivers/nv40/libnv40.a \
- $(TOP)/src/gallium/drivers/nv50/libnv50.a
-
-DRIVER_SOURCES = \
- nouveau_bo.c \
- nouveau_channel.c \
- nouveau_context.c \
- nouveau_device.c \
- nouveau_dma.c \
- nouveau_fence.c \
- nouveau_grobj.c \
- nouveau_lock.c \
- nouveau_notifier.c \
- nouveau_pushbuf.c \
- nouveau_resource.c \
- nouveau_screen.c \
- nouveau_swapbuffers.c \
- nouveau_winsys.c \
- nouveau_winsys_pipe.c \
- nouveau_winsys_softpipe.c \
- nv04_surface.c \
- nv50_surface.c
-
-C_SOURCES = \
- $(COMMON_GALLIUM_SOURCES) \
- $(DRIVER_SOURCES)
-
-ASM_SOURCES =
-
-include ../Makefile.template
-
-symlinks:
+
+SUBDIRS = common dri
+
+
+default: subdirs
+
+
+subdirs:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE)) || exit 1 ; \
+ fi \
+ done
+
+
+clean:
+ rm -f `find . -name \*.[oa]`
+ rm -f `find . -name depend`
+
+
+# Dummy install target
+install:
diff --git a/src/gallium/winsys/drm/nouveau/common/Makefile b/src/gallium/winsys/drm/nouveau/common/Makefile
new file mode 100644
index 0000000000..06f558959d
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/common/Makefile
@@ -0,0 +1,32 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = nouveaudrm
+
+C_SOURCES = \
+ nouveau_bo.c \
+ nouveau_channel.c \
+ nouveau_context.c \
+ nouveau_device.c \
+ nouveau_dma.c \
+ nouveau_fence.c \
+ nouveau_grobj.c \
+ nouveau_lock.c \
+ nouveau_notifier.c \
+ nouveau_pushbuf.c \
+ nouveau_resource.c \
+ nouveau_screen.c \
+ nouveau_winsys.c \
+ nouveau_winsys_pipe.c \
+ nouveau_winsys_softpipe.c \
+ nv04_surface.c \
+ nv50_surface.c
+
+
+include ./Makefile.template
+
+DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \
+ && pkg-config libdrm --atleast-version=2.3.1 \
+ && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
+symlinks:
+
diff --git a/src/gallium/winsys/drm/nouveau/common/Makefile.template b/src/gallium/winsys/drm/nouveau/common/Makefile.template
new file mode 100644
index 0000000000..e40836e0a8
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/common/Makefile.template
@@ -0,0 +1,59 @@
+# -*-makefile-*-
+
+COMMON_SOURCES =
+
+OBJECTS = $(C_SOURCES:.c=.o) \
+ $(CPP_SOURCES:.cpp=.o) \
+ $(ASM_SOURCES:.S=.o)
+
+
+### Include directories
+INCLUDES = \
+ -I. \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/include \
+ $(DRIVER_INCLUDES)
+
+
+##### RULES #####
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
+
+.cpp.o:
+ $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@
+
+.S.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
+
+
+##### TARGETS #####
+
+default: depend symlinks $(LIBNAME)
+
+
+$(LIBNAME): $(OBJECTS) Makefile Makefile.template
+ $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS)
+
+
+depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
+ rm -f depend
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \
+ $(ASM_SOURCES) 2> /dev/null
+
+
+# Emacs tags
+tags:
+ etags `find . -name \*.[ch]` `find ../include`
+
+
+# Remove .o and backup files
+clean::
+ -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS)
+ -rm -f depend depend.bak
+
+
+include depend
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_bo.c b/src/gallium/winsys/drm/nouveau/common/nouveau_bo.c
index b5942994d9..76b98bed67 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_bo.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_bo.c
@@ -273,6 +273,40 @@ nouveau_bo_del(struct nouveau_bo **bo)
}
int
+nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags)
+{
+ struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
+ struct nouveau_fence *fence;
+
+ if (!nvbo)
+ return -EINVAL;
+
+ /* If the buffer is pending it must be busy, unless
+ * both are RD, in which case we can allow access */
+ if (nvbo->pending) {
+ if ((nvbo->pending->flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD &&
+ (flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD)
+ return 0;
+ else
+ return 1;
+ }
+
+ if (flags & NOUVEAU_BO_WR)
+ fence = nvbo->fence;
+ else
+ fence = nvbo->wr_fence;
+
+ /* If the buffer is not pending and doesn't have a fence
+ * that conflicts with our flags then it can't be busy
+ */
+ if (!fence)
+ return 0;
+ else
+ /* If the fence is signalled the buffer is not busy, else is busy */
+ return !nouveau_fence(fence)->signalled;
+}
+
+int
nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags)
{
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_channel.c b/src/gallium/winsys/drm/nouveau/common/nouveau_channel.c
index 3b4dcd1ecf..b7298131c1 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_channel.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_channel.c
@@ -23,7 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-
+#include <util/u_memory.h>
#include "nouveau_drmif.h"
#include "nouveau_dma.h"
@@ -38,7 +38,7 @@ nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma,
if (!nvdev || !chan || *chan)
return -EINVAL;
- nvchan = calloc(1, sizeof(struct nouveau_channel_priv));
+ nvchan = CALLOC_STRUCT(nouveau_channel_priv);
if (!nvchan)
return -ENOMEM;
nvchan->base.device = dev;
@@ -48,7 +48,7 @@ nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma,
ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
&nvchan->drm, sizeof(nvchan->drm));
if (ret) {
- free(nvchan);
+ FREE(nvchan);
return ret;
}
@@ -111,16 +111,16 @@ nouveau_channel_free(struct nouveau_channel **chan)
nvchan = nouveau_channel(*chan);
*chan = NULL;
nvdev = nouveau_device(nvchan->base.device);
-
+
FIRE_RING_CH(&nvchan->base);
nouveau_grobj_free(&nvchan->base.vram);
nouveau_grobj_free(&nvchan->base.gart);
nouveau_grobj_free(&nvchan->base.nullobj);
+ FREE(nvchan->pb.buffers);
+ FREE(nvchan->pb.relocs);
cf.channel = nvchan->drm.channel;
drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf));
- free(nvchan);
+ FREE(nvchan);
}
-
-
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_context.c b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c
index 74413c408f..2f245046d4 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_context.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c
@@ -1,28 +1,13 @@
-#include "main/glheader.h"
-#include "glapi/glthread.h"
-#include <GL/internal/glcore.h>
-#include "utils.h"
-
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_context.h"
-#include "pipe/p_screen.h"
-
+#include <pipe/p_defines.h>
+#include <pipe/p_context.h>
+#include <pipe/p_screen.h>
+#include <util/u_memory.h>
#include "nouveau_context.h"
#include "nouveau_dri.h"
#include "nouveau_local.h"
#include "nouveau_screen.h"
#include "nouveau_winsys_pipe.h"
-#ifdef DEBUG
-static const struct dri_debug_control debug_control[] = {
- { "bo", DEBUG_BO },
- { NULL, 0 }
-};
-int __nouveau_debug = 0;
-#endif
-
static void
nouveau_channel_context_destroy(struct nouveau_channel_context *nvc)
{
@@ -87,24 +72,17 @@ nouveau_channel_context_create(struct nouveau_device *dev)
return nvc;
}
-GLboolean
-nouveau_context_create(const __GLcontextModes *glVis,
- __DRIcontextPrivate *driContextPriv,
- void *sharedContextPrivate)
+int
+nouveau_context_init(struct nouveau_screen *nv_screen,
+ drm_context_t hHWContext, drmLock *sarea_lock,
+ struct nouveau_context *nv_share,
+ struct nouveau_context *nv)
{
- __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv;
- struct nouveau_screen *nv_screen = driScrnPriv->private;
- struct nouveau_context *nv = CALLOC_STRUCT(nouveau_context);
struct pipe_context *pipe = NULL;
- struct st_context *st_share = NULL;
struct nouveau_channel_context *nvc = NULL;
struct nouveau_device *dev = nv_screen->device;
int i;
- if (sharedContextPrivate) {
- st_share = ((struct nouveau_context *)sharedContextPrivate)->st;
- }
-
switch (dev->chipset & 0xf0) {
case 0x10:
case 0x20:
@@ -121,27 +99,18 @@ nouveau_context_create(const __GLcontextModes *glVis,
break;
default:
NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset);
- return GL_FALSE;
+ return 1;
}
- driContextPriv->driverPrivate = (void *)nv;
nv->nv_screen = nv_screen;
- nv->dri_screen = driScrnPriv;
{
struct nouveau_device_priv *nvdev = nouveau_device(dev);
- nvdev->ctx = driContextPriv->hHWContext;
- nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock;
+ nvdev->ctx = hHWContext;
+ nvdev->lock = sarea_lock;
}
- driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache,
- nv->dri_screen->myNum, "nouveau");
-#ifdef DEBUG
- __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"),
- debug_control);
-#endif
-
/*XXX: Hack up a fake region and buffer object for front buffer.
* This will go away with TTM, replaced with a simple reference
* of the front buffer handle passed to us by the DDX.
@@ -185,12 +154,8 @@ nouveau_context_create(const __GLcontextModes *glVis,
* a single process.
*/
nvc = nv_screen->nvc;
- if (!nvc && st_share) {
- struct nouveau_context *snv = st_share->pipe->priv;
- if (snv) {
- nvc = snv->nvc;
- }
- }
+ if (!nvc && nv_share)
+ nvc = nv_share->nvc;
/*XXX: temporary - disable multi-context/single-channel on pre-NV4x */
switch (dev->chipset & 0xf0) {
@@ -211,7 +176,7 @@ nouveau_context_create(const __GLcontextModes *glVis,
nvc = nouveau_channel_context_create(dev);
if (!nvc) {
NOUVEAU_ERR("Failed initialising GPU context\n");
- return GL_FALSE;
+ return 1;
}
nv_screen->nvc = nvc;
}
@@ -241,11 +206,11 @@ nouveau_context_create(const __GLcontextModes *glVis,
case 0x80:
case 0x90:
if (nouveau_surface_init_nv50(nv))
- return GL_FALSE;
+ return 1;
break;
default:
if (nouveau_surface_init_nv04(nv))
- return GL_FALSE;
+ return 1;
break;
}
@@ -268,26 +233,22 @@ nouveau_context_create(const __GLcontextModes *glVis,
pipe = nouveau_create_softpipe(nv);
if (!pipe) {
NOUVEAU_ERR("Error creating pipe, bailing\n");
- return GL_FALSE;
+ return 1;
}
}
pipe->priv = nv;
- nv->st = st_create_context(pipe, glVis, st_share);
- return GL_TRUE;
+
+ return 0;
}
void
-nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
+nouveau_context_cleanup(struct nouveau_context *nv)
{
- struct nouveau_context *nv = driContextPriv->driverPrivate;
struct nouveau_channel_context *nvc = nv->nvc;
assert(nv);
- st_finish(nv->st);
- st_destroy_context(nv->st);
-
if (nv->pctx_id >= 0) {
nvc->pctx[nv->pctx_id] = NULL;
if (--nvc->refcount <= 0) {
@@ -295,52 +256,7 @@ nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
nv->nv_screen->nvc = NULL;
}
}
-
- free(nv);
-}
-
-GLboolean
-nouveau_context_bind(__DRIcontextPrivate *driContextPriv,
- __DRIdrawablePrivate *driDrawPriv,
- __DRIdrawablePrivate *driReadPriv)
-{
- struct nouveau_context *nv;
- struct nouveau_framebuffer *draw, *read;
-
- if (!driContextPriv) {
- st_make_current(NULL, NULL, NULL);
- return GL_TRUE;
- }
-
- nv = driContextPriv->driverPrivate;
- draw = driDrawPriv->driverPrivate;
- read = driReadPriv->driverPrivate;
-
- st_make_current(nv->st, draw->stfb, read->stfb);
-
- if ((nv->dri_drawable != driDrawPriv) ||
- (nv->last_stamp != driDrawPriv->lastStamp)) {
- nv->dri_drawable = driDrawPriv;
- st_resize_framebuffer(draw->stfb, driDrawPriv->w,
- driDrawPriv->h);
- nv->last_stamp = driDrawPriv->lastStamp;
- }
-
- if (driDrawPriv != driReadPriv) {
- st_resize_framebuffer(read->stfb, driReadPriv->w,
- driReadPriv->h);
- }
-
- return GL_TRUE;
-}
-
-GLboolean
-nouveau_context_unbind(__DRIcontextPrivate *driContextPriv)
-{
- struct nouveau_context *nv = driContextPriv->driverPrivate;
- (void)nv;
-
- st_flush(nv->st, 0, NULL);
- return GL_TRUE;
+
+ /* XXX: Who cleans up the pipe? */
}
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_context.h b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h
index 77e2147a2c..b1bdb01bdf 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_context.h
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h
@@ -1,17 +1,10 @@
#ifndef __NOUVEAU_CONTEXT_H__
#define __NOUVEAU_CONTEXT_H__
-#include "dri_util.h"
-#include "xmlconfig.h"
-
#include "nouveau/nouveau_winsys.h"
#include "nouveau_drmif.h"
#include "nouveau_dma.h"
-struct nouveau_framebuffer {
- struct st_framebuffer *stfb;
-};
-
struct nouveau_channel_context {
struct pipe_screen *pscreen;
int refcount;
@@ -41,16 +34,7 @@ struct nouveau_channel_context {
};
struct nouveau_context {
- struct st_context *st;
-
- /* DRI stuff */
- __DRIscreenPrivate *dri_screen;
- __DRIdrawablePrivate *dri_drawable;
- unsigned int last_stamp;
- driOptionCache dri_option_cache;
- drm_context_t drm_context;
- drmLock drm_lock;
- GLboolean locked;
+ int locked;
struct nouveau_screen *nv_screen;
struct pipe_surface *frontbuffer;
@@ -76,26 +60,11 @@ struct nouveau_context {
unsigned, unsigned, unsigned, unsigned, unsigned);
};
-extern GLboolean nouveau_context_create(const __GLcontextModes *,
- __DRIcontextPrivate *, void *);
-extern void nouveau_context_destroy(__DRIcontextPrivate *);
-extern GLboolean nouveau_context_bind(__DRIcontextPrivate *,
- __DRIdrawablePrivate *draw,
- __DRIdrawablePrivate *read);
-extern GLboolean nouveau_context_unbind(__DRIcontextPrivate *);
-
-#ifdef DEBUG
-extern int __nouveau_debug;
-
-#define DEBUG_BO (1 << 0)
-
-#define DBG(flag, ...) do { \
- if (__nouveau_debug & (DEBUG_##flag)) \
- NOUVEAU_ERR(__VA_ARGS__); \
-} while(0)
-#else
-#define DBG(flag, ...)
-#endif
+extern int nouveau_context_init(struct nouveau_screen *nv_screen,
+ drm_context_t hHWContext, drmLock *sarea_lock,
+ struct nouveau_context *nv_share,
+ struct nouveau_context *nv);
+extern void nouveau_context_cleanup(struct nouveau_context *nv);
extern void LOCK_HARDWARE(struct nouveau_context *);
extern void UNLOCK_HARDWARE(struct nouveau_context *);
@@ -110,4 +79,8 @@ extern int nouveau_surface_init_nv50(struct nouveau_context *);
extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int);
extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *);
+/* Must be provided by clients of common code */
+extern void
+nouveau_contended_lock(struct nouveau_context *nv);
+
#endif
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_device.c b/src/gallium/winsys/drm/nouveau/common/nouveau_device.c
index 0b452fcd02..92b57b834b 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_device.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_device.c
@@ -23,7 +23,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
-
+#include <util/u_memory.h>
#include "nouveau_drmif.h"
int
@@ -36,7 +36,7 @@ nouveau_device_open_existing(struct nouveau_device **dev, int close,
if (!dev || *dev)
return -EINVAL;
- nvdev = calloc(1, sizeof(*nvdev));
+ nvdev = CALLOC_STRUCT(nouveau_device_priv);
if (!nvdev)
return -ENOMEM;
nvdev->fd = fd;
@@ -112,7 +112,7 @@ nouveau_device_close(struct nouveau_device **dev)
drmDestroyContext(nvdev->fd, nvdev->ctx);
drmClose(nvdev->fd);
}
- free(nvdev);
+ FREE(nvdev);
}
int
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_dma.c b/src/gallium/winsys/drm/nouveau/common/nouveau_dma.c
index f8a8ba04f6..f8a8ba04f6 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_dma.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_dma.c
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_dma.h b/src/gallium/winsys/drm/nouveau/common/nouveau_dma.h
index cfa6d26e82..cfa6d26e82 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_dma.h
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_dma.h
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/common/nouveau_dri.h
index 1207c2d609..1207c2d609 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_dri.h
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_dri.h
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_drmif.h b/src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h
index dcd6a5eb0a..5f72800676 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_drmif.h
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h
@@ -287,6 +287,9 @@ extern void
nouveau_bo_del(struct nouveau_bo **);
extern int
+nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags);
+
+extern int
nouveau_bo_map(struct nouveau_bo *, uint32_t flags);
extern void
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_fence.c b/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c
index e7b0b4ff07..e7b0b4ff07 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_fence.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_grobj.c b/src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c
index 51523897d5..fb430a25b8 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_grobj.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c
@@ -22,7 +22,7 @@
#include <stdlib.h>
#include <errno.h>
-
+#include <util/u_memory.h>
#include "nouveau_drmif.h"
int
@@ -37,7 +37,7 @@ nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle,
if (!nvdev || !grobj || *grobj)
return -EINVAL;
- nvgrobj = calloc(1, sizeof(*nvgrobj));
+ nvgrobj = CALLOC_STRUCT(nouveau_grobj_priv);
if (!nvgrobj)
return -ENOMEM;
nvgrobj->base.channel = chan;
@@ -67,7 +67,7 @@ nouveau_grobj_ref(struct nouveau_channel *chan, uint32_t handle,
if (!chan || !grobj || *grobj)
return -EINVAL;
- nvgrobj = calloc(1, sizeof(struct nouveau_grobj_priv));
+ nvgrobj = CALLOC_STRUCT(nouveau_grobj_priv);
if (!nvgrobj)
return -ENOMEM;
nvgrobj->base.channel = chan;
@@ -102,6 +102,6 @@ nouveau_grobj_free(struct nouveau_grobj **grobj)
drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE,
&f, sizeof(f));
}
- free(nvgrobj);
+ FREE(nvgrobj);
}
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_local.h b/src/gallium/winsys/drm/nouveau/common/nouveau_local.h
index e878a40803..877c7a8c47 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_local.h
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_local.h
@@ -5,8 +5,6 @@
#include "nouveau_winsys_pipe.h"
#include <stdio.h>
-struct pipe_buffer;
-
/* Debug output */
#define NOUVEAU_MSG(fmt, args...) do { \
fprintf(stdout, "nouveau: "fmt, ##args); \
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_lock.c b/src/gallium/winsys/drm/nouveau/common/nouveau_lock.c
index 9adb9ac854..e8cf051ed9 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_lock.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_lock.c
@@ -25,34 +25,11 @@
*
**************************************************************************/
-#include "main/glheader.h"
-#include "glapi/glthread.h"
-#include <GL/internal/glcore.h>
-
+#include <pipe/p_thread.h>
#include "nouveau_context.h"
#include "nouveau_screen.h"
-_glthread_DECLARE_STATIC_MUTEX( lockMutex );
-
-static void
-nouveau_contended_lock(struct nouveau_context *nv, GLuint flags)
-{
- __DRIdrawablePrivate *dPriv = nv->dri_drawable;
- __DRIscreenPrivate *sPriv = nv->dri_screen;
- struct nouveau_screen *nv_screen = nv->nv_screen;
- struct nouveau_device *dev = nv_screen->device;
- struct nouveau_device_priv *nvdev = nouveau_device(dev);
-
- drmGetLock(nvdev->fd, nvdev->ctx, flags);
-
- /* If the window moved, may need to set a new cliprect now.
- *
- * NOTE: This releases and regains the hw lock, so all state
- * checking must be done *after* this call:
- */
- if (dPriv)
- DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
-}
+pipe_static_mutex(lockMutex);
/* Lock the hardware and validate our state.
*/
@@ -64,20 +41,21 @@ LOCK_HARDWARE(struct nouveau_context *nv)
struct nouveau_device_priv *nvdev = nouveau_device(dev);
char __ret=0;
- _glthread_LOCK_MUTEX(lockMutex);
assert(!nv->locked);
-
+ pipe_mutex_lock(lockMutex);
+
DRM_CAS(nvdev->lock, nvdev->ctx,
(DRM_LOCK_HELD | nvdev->ctx), __ret);
-
- if (__ret)
- nouveau_contended_lock(nv, 0);
- nv->locked = GL_TRUE;
-}
+ if (__ret) {
+ drmGetLock(nvdev->fd, nvdev->ctx, 0);
+ nouveau_contended_lock(nv);
+ }
+ nv->locked = 1;
+}
- /* Unlock the hardware using the global current context
- */
+/* Unlock the hardware using the global current context
+ */
void
UNLOCK_HARDWARE(struct nouveau_context *nv)
{
@@ -86,9 +64,9 @@ UNLOCK_HARDWARE(struct nouveau_context *nv)
struct nouveau_device_priv *nvdev = nouveau_device(dev);
assert(nv->locked);
- nv->locked = GL_FALSE;
+ nv->locked = 0;
DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx);
- _glthread_UNLOCK_MUTEX(lockMutex);
+ pipe_mutex_unlock(lockMutex);
}
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_notifier.c b/src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c
index 01e8f38440..01e8f38440 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_notifier.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c
index 815046ba85..7c094eb795 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c
@@ -23,7 +23,7 @@
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
-
+#include <util/u_memory.h>
#include "nouveau_drmif.h"
#include "nouveau_dma.h"
@@ -97,9 +97,9 @@ nouveau_pushbuf_init(struct nouveau_channel *chan)
nouveau_pushbuf_space(chan, 0);
chan->pushbuf = &nvchan->pb.base;
- nvchan->pb.buffers = calloc(NOUVEAU_PUSHBUF_MAX_BUFFERS,
+ nvchan->pb.buffers = CALLOC(NOUVEAU_PUSHBUF_MAX_BUFFERS,
sizeof(struct nouveau_pushbuf_bo));
- nvchan->pb.relocs = calloc(NOUVEAU_PUSHBUF_MAX_RELOCS,
+ nvchan->pb.relocs = CALLOC(NOUVEAU_PUSHBUF_MAX_RELOCS,
sizeof(struct nouveau_pushbuf_reloc));
return 0;
}
@@ -268,4 +268,3 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr,
*(uint32_t *)ptr = nouveau_pushbuf_calc_reloc(bo, r);
return 0;
}
-
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_resource.c b/src/gallium/winsys/drm/nouveau/common/nouveau_resource.c
index 3bbcb5c45e..766fd279fe 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_resource.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_resource.c
@@ -22,7 +22,7 @@
#include <stdlib.h>
#include <errno.h>
-
+#include <util/u_memory.h>
#include "nouveau_drmif.h"
#include "nouveau_local.h"
@@ -32,7 +32,7 @@ nouveau_resource_init(struct nouveau_resource **heap,
{
struct nouveau_resource *r;
- r = calloc(1, sizeof(struct nouveau_resource));
+ r = CALLOC_STRUCT(nouveau_resource);
if (!r)
return 1;
@@ -53,7 +53,7 @@ nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv,
while (heap) {
if (!heap->in_use && heap->size >= size) {
- r = calloc(1, sizeof(struct nouveau_resource));
+ r = CALLOC_STRUCT(nouveau_resource);
if (!r)
return 1;
@@ -73,7 +73,7 @@ nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv,
*res = r;
return 0;
}
-
+
heap = heap->next;
}
@@ -110,7 +110,7 @@ nouveau_resource_free(struct nouveau_resource **res)
if (r->next)
r->next->prev = r->prev;
r->prev->size += r->size;
- free(r);
+ FREE(r);
}
-
+
}
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/common/nouveau_screen.c
new file mode 100644
index 0000000000..422fbf0207
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_screen.c
@@ -0,0 +1,31 @@
+#include <util/u_memory.h>
+#include "nouveau_dri.h"
+#include "nouveau_local.h"
+#include "nouveau_screen.h"
+
+int
+nouveau_screen_init(struct nouveau_dri *nv_dri, int dev_fd,
+ struct nouveau_screen *nv_screen)
+{
+ int ret;
+
+ ret = nouveau_device_open_existing(&nv_screen->device, 0,
+ dev_fd, 0);
+ if (ret) {
+ NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret);
+ return 1;
+ }
+
+ nv_screen->front_offset = nv_dri->front_offset;
+ nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8);
+ nv_screen->front_cpp = nv_dri->bpp / 8;
+ nv_screen->front_height = nv_dri->height;
+
+ return 0;
+}
+
+void
+nouveau_screen_cleanup(struct nouveau_screen *nv_screen)
+{
+ nouveau_device_close(&nv_screen->device);
+}
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_screen.h b/src/gallium/winsys/drm/nouveau/common/nouveau_screen.h
new file mode 100644
index 0000000000..3e68e219d8
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_screen.h
@@ -0,0 +1,27 @@
+#ifndef __NOUVEAU_SCREEN_H__
+#define __NOUVEAU_SCREEN_H__
+
+#include <stdint.h>
+
+struct nouveau_device;
+struct nouveau_dri;
+
+struct nouveau_screen {
+ struct nouveau_device *device;
+
+ uint32_t front_offset;
+ uint32_t front_pitch;
+ uint32_t front_cpp;
+ uint32_t front_height;
+
+ void *nvc;
+};
+
+int
+nouveau_screen_init(struct nouveau_dri *nv_dri, int dev_fd,
+ struct nouveau_screen *nv_screen);
+
+void
+nouveau_screen_cleanup(struct nouveau_screen *nv_screen);
+
+#endif
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c
index 364340e1d3..364340e1d3 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_winsys.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c
index 5276806de6..6895137506 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c
@@ -1,55 +1,29 @@
-#include "pipe/p_winsys.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_inlines.h"
-
-#include "util/u_memory.h"
-
+#include <pipe/p_winsys.h>
+#include <pipe/p_defines.h>
+#include <pipe/p_inlines.h>
+#include <util/u_memory.h>
#include "nouveau_context.h"
#include "nouveau_local.h"
#include "nouveau_screen.h"
-#include "nouveau_swapbuffers.h"
#include "nouveau_winsys_pipe.h"
-static void
-nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
- void *context_private)
-{
- struct nouveau_context *nv = context_private;
- __DRIdrawablePrivate *dPriv = nv->dri_drawable;
-
- nouveau_copy_buffer(dPriv, surf, NULL);
-}
-
static const char *
nouveau_get_name(struct pipe_winsys *pws)
{
return "Nouveau/DRI";
}
-static struct pipe_buffer *
-nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
- unsigned usage, unsigned size)
+static uint32_t
+nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
{
- struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
- struct nouveau_context *nv = nvpws->nv;
struct nouveau_device *dev = nv->nv_screen->device;
- struct nouveau_pipe_buffer *nvbuf;
- uint32_t flags;
-
- nvbuf = calloc(1, sizeof(*nvbuf));
- if (!nvbuf)
- return NULL;
- nvbuf->base.refcount = 1;
- nvbuf->base.alignment = alignment;
- nvbuf->base.usage = usage;
- nvbuf->base.size = size;
-
- flags = NOUVEAU_BO_LOCAL;
+ uint32_t flags = NOUVEAU_BO_LOCAL;
if (usage & PIPE_BUFFER_USAGE_PIXEL) {
if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
flags |= NOUVEAU_BO_GART;
- flags |= NOUVEAU_BO_VRAM;
+ if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE))
+ flags |= NOUVEAU_BO_VRAM;
switch (dev->chipset & 0xf0) {
case 0x50:
@@ -74,8 +48,31 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
flags |= NOUVEAU_BO_GART;
}
+ return flags;
+}
+
+static struct pipe_buffer *
+nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
+ unsigned usage, unsigned size)
+{
+ struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
+ struct nouveau_context *nv = nvpws->nv;
+ struct nouveau_device *dev = nv->nv_screen->device;
+ struct nouveau_pipe_buffer *nvbuf;
+ uint32_t flags;
+
+ nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
+ if (!nvbuf)
+ return NULL;
+ nvbuf->base.refcount = 1;
+ nvbuf->base.alignment = alignment;
+ nvbuf->base.usage = usage;
+ nvbuf->base.size = size;
+
+ flags = nouveau_flags_from_usage(nv, flags);
+
if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
- free(nvbuf);
+ FREE(nvbuf);
return NULL;
}
@@ -89,14 +86,14 @@ nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
struct nouveau_device *dev = nvpws->nv->nv_screen->device;
struct nouveau_pipe_buffer *nvbuf;
- nvbuf = calloc(1, sizeof(*nvbuf));
+ nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
if (!nvbuf)
return NULL;
nvbuf->base.refcount = 1;
nvbuf->base.size = bytes;
if (nouveau_bo_user(dev, ptr, bytes, &nvbuf->bo)) {
- free(nvbuf);
+ FREE(nvbuf);
return NULL;
}
@@ -109,7 +106,7 @@ nouveau_pipe_bo_del(struct pipe_winsys *ws, struct pipe_buffer *buf)
struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf);
nouveau_bo_del(&nvbuf->bo);
- free(nvbuf);
+ FREE(nvbuf);
}
static void *
@@ -124,6 +121,26 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
map_flags |= NOUVEAU_BO_WR;
+ /* XXX: Technically incorrect. If the client maps a buffer for write-only
+ * and leaves part of the buffer untouched it probably expects those parts
+ * to remain intact. This is violated because we allocate a whole new buffer
+ * and don't copy the previous buffer's contents, so this optimization is
+ * only valid if the client intends to overwrite the whole buffer.
+ */
+ if ((map_flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_WR &&
+ !nouveau_bo_busy(nvbuf->bo, map_flags)) {
+ struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
+ struct nouveau_context *nv = nvpws->nv;
+ struct nouveau_device *dev = nv->nv_screen->device;
+ struct nouveau_bo *rename;
+ uint32_t flags = nouveau_flags_from_usage(nv, buf->usage);
+
+ if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) {
+ nouveau_bo_del(&nvbuf->bo);
+ nvbuf->bo = rename;
+ }
+ }
+
if (nouveau_bo_map(nvbuf->bo, map_flags))
return NULL;
return nvbuf->bo->map;
@@ -175,6 +192,12 @@ nouveau_pipe_fence_finish(struct pipe_winsys *ws,
return nouveau_fence_wait(&ref);
}
+static void
+nouveau_destroy(struct pipe_winsys *pws)
+{
+ FREE(pws);
+}
+
struct pipe_winsys *
nouveau_create_pipe_winsys(struct nouveau_context *nv)
{
@@ -200,7 +223,7 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv)
pws->fence_finish = nouveau_pipe_fence_finish;
pws->get_name = nouveau_get_name;
+ pws->destroy = nouveau_destroy;
return &nvpws->pws;
}
-
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h
index 6a03ac0d77..14c728690d 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.h
@@ -31,4 +31,9 @@ nouveau_create_softpipe(struct nouveau_context *nv);
struct pipe_context *
nouveau_pipe_create(struct nouveau_context *nv);
+/* Must be provided by clients of common code */
+extern void
+nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
+ void *context_private);
+
#endif
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c
index 68aade829d..04def600f4 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_softpipe.c
@@ -29,12 +29,12 @@
* Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
*/
-#include "imports.h"
-
-#include "pipe/p_defines.h"
-#include "pipe/p_format.h"
-#include "softpipe/sp_winsys.h"
-
+#include <pipe/p_winsys.h>
+#include <pipe/p_screen.h>
+#include <pipe/p_defines.h>
+#include <pipe/p_format.h>
+#include <softpipe/sp_winsys.h>
+#include <util/u_memory.h>
#include "nouveau_context.h"
#include "nouveau_winsys_pipe.h"
@@ -48,7 +48,7 @@ struct nouveau_softpipe_winsys {
*/
static boolean
nouveau_is_format_supported(struct softpipe_winsys *sws,
- enum pipe_format format)
+ enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
@@ -68,19 +68,34 @@ nouveau_create_softpipe(struct nouveau_context *nv)
struct nouveau_softpipe_winsys *nvsws;
struct pipe_screen *pscreen;
struct pipe_winsys *ws;
+ struct pipe_context *pipe;
ws = nouveau_create_pipe_winsys(nv);
if (!ws)
return NULL;
pscreen = softpipe_create_screen(ws);
-
+ if (!pscreen) {
+ ws->destroy(ws);
+ return NULL;
+ }
nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys);
- if (!nvsws)
+ if (!nvsws) {
+ ws->destroy(ws);
+ pscreen->destroy(pscreen);
return NULL;
+ }
nvsws->sws.is_format_supported = nouveau_is_format_supported;
nvsws->nv = nv;
- return softpipe_create(pscreen, ws, &nvsws->sws);
+ pipe = softpipe_create(pscreen, ws, &nvsws->sws);
+ if (!pipe) {
+ ws->destroy(ws);
+ pscreen->destroy(pscreen);
+ FREE(nvsws);
+ return NULL;
+ }
+
+ return pipe;
}
diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c
index 68338eb814..e9a8a2ac1c 100644
--- a/src/gallium/winsys/drm/nouveau/nv04_surface.c
+++ b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c
@@ -82,6 +82,37 @@ nv04_scaled_image_format(enum pipe_format format)
}
}
+static INLINE unsigned
+nv04_swizzle_bits(unsigned x, unsigned y)
+{
+ unsigned u = (x & 0x001) << 0 |
+ (x & 0x002) << 1 |
+ (x & 0x004) << 2 |
+ (x & 0x008) << 3 |
+ (x & 0x010) << 4 |
+ (x & 0x020) << 5 |
+ (x & 0x040) << 6 |
+ (x & 0x080) << 7 |
+ (x & 0x100) << 8 |
+ (x & 0x200) << 9 |
+ (x & 0x400) << 10 |
+ (x & 0x800) << 11;
+
+ unsigned v = (y & 0x001) << 1 |
+ (y & 0x002) << 2 |
+ (y & 0x004) << 3 |
+ (y & 0x008) << 4 |
+ (y & 0x010) << 5 |
+ (y & 0x020) << 6 |
+ (y & 0x040) << 7 |
+ (y & 0x080) << 8 |
+ (y & 0x100) << 9 |
+ (y & 0x200) << 10 |
+ (y & 0x400) << 11 |
+ (y & 0x800) << 12;
+ return v | u;
+}
+
static void
nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy,
unsigned sx, unsigned sy, unsigned w, unsigned h)
@@ -90,19 +121,23 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy,
struct pipe_surface *dst = nv->surf_dst;
struct pipe_surface *src = nv->surf_src;
+ const unsigned max_w = 1024;
+ const unsigned max_h = 1024;
+ const unsigned sub_w = w > max_w ? max_w : w;
+ const unsigned sub_h = h > max_h ? max_h : h;
+ unsigned cx = 0;
+ unsigned cy = 0;
+
/* POT or GTFO */
assert(!(w & (w - 1)) && !(h & (h - 1)));
BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1);
OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo,
NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-
- BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 2);
+ BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 1);
OUT_RING (chan, nv04_surface_format(dst->format) |
log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT |
log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT);
- OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset,
- NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1);
OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo,
@@ -110,24 +145,35 @@ nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy,
BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1);
OUT_RING (chan, nv->nvc->NvSwzSurf->handle);
- BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9);
- OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE);
- OUT_RING (chan, nv04_scaled_image_format(src->format));
- OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
- OUT_RING (chan, 0);
- OUT_RING (chan, h << 16 | w);
- OUT_RING (chan, 0);
- OUT_RING (chan, h << 16 | w);
- OUT_RING (chan, 1 << 20);
- OUT_RING (chan, 1 << 20);
- BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4);
- OUT_RING (chan, h << 16 | w);
- OUT_RING (chan, src->stride |
- NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
- NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE);
- OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset,
- NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RING (chan, 0);
+ for (cy = 0; cy < h; cy += sub_h) {
+ for (cx = 0; cx < w; cx += sub_w) {
+ BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_OFFSET, 1);
+ OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo,
+ dst->offset + nv04_swizzle_bits(cx, cy) * dst->block.size,
+ NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+ BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9);
+ OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE);
+ OUT_RING (chan, nv04_scaled_image_format(src->format));
+ OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, sub_h << 16 | sub_w);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, sub_h << 16 | sub_w);
+ OUT_RING (chan, 1 << 20);
+ OUT_RING (chan, 1 << 20);
+
+ BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4);
+ OUT_RING (chan, sub_h << 16 | sub_w);
+ OUT_RING (chan, src->stride |
+ NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
+ NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE);
+ OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo,
+ src->offset + cy * src->stride + cx * src->block.size,
+ NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ OUT_RING (chan, 0);
+ }
+ }
}
static void
diff --git a/src/gallium/winsys/drm/nouveau/nv50_surface.c b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c
index c8ab7f690f..c8ab7f690f 100644
--- a/src/gallium/winsys/drm/nouveau/nv50_surface.c
+++ b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c
diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/winsys/drm/nouveau/dri/Makefile
new file mode 100644
index 0000000000..e129e42e97
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/dri/Makefile
@@ -0,0 +1,31 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = nouveau_dri.so
+
+MINIGLX_SOURCES =
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/nv04/libnv04.a \
+ $(TOP)/src/gallium/drivers/nv10/libnv10.a \
+ $(TOP)/src/gallium/drivers/nv20/libnv20.a \
+ $(TOP)/src/gallium/drivers/nv30/libnv30.a \
+ $(TOP)/src/gallium/drivers/nv40/libnv40.a \
+ $(TOP)/src/gallium/drivers/nv50/libnv50.a
+
+DRIVER_SOURCES = \
+ nouveau_context_dri.c \
+ nouveau_screen_dri.c \
+ nouveau_swapbuffers.c \
+ ../common/libnouveaudrm.a
+
+C_SOURCES = \
+ $(COMMON_GALLIUM_SOURCES) \
+ $(DRIVER_SOURCES)
+
+ASM_SOURCES =
+
+include ../../Makefile.template
+
+symlinks:
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c
new file mode 100644
index 0000000000..006978b182
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c
@@ -0,0 +1,124 @@
+#include <main/glheader.h>
+#include <glapi/glthread.h>
+#include <GL/internal/glcore.h>
+#include <utils.h>
+
+#include <state_tracker/st_public.h>
+#include <state_tracker/st_context.h>
+#include <pipe/p_defines.h>
+#include <pipe/p_context.h>
+#include <pipe/p_screen.h>
+
+#include "../common/nouveau_winsys_pipe.h"
+#include "../common/nouveau_dri.h"
+#include "../common/nouveau_local.h"
+#include "nouveau_context_dri.h"
+#include "nouveau_screen_dri.h"
+
+#ifdef DEBUG
+static const struct dri_debug_control debug_control[] = {
+ { "bo", DEBUG_BO },
+ { NULL, 0 }
+};
+int __nouveau_debug = 0;
+#endif
+
+GLboolean
+nouveau_context_create(const __GLcontextModes *glVis,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate)
+{
+ __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv;
+ struct nouveau_screen_dri *nv_screen = driScrnPriv->private;
+ struct nouveau_context_dri *nv = CALLOC_STRUCT(nouveau_context_dri);
+ struct st_context *st_share = NULL;
+ struct nouveau_context_dri *nv_share = NULL;
+ struct pipe_context *pipe;
+
+ if (sharedContextPrivate) {
+ st_share = ((struct nouveau_context_dri *)sharedContextPrivate)->st;
+ nv_share = st_share->pipe->priv;
+ }
+
+ if (nouveau_context_init(&nv_screen->base, driContextPriv->hHWContext,
+ (drmLock *)&driScrnPriv->pSAREA->lock,
+ nv_share, &nv->base)) {
+ return GL_FALSE;
+ }
+
+ pipe = nv->base.nvc->pctx[nv->base.pctx_id];
+ driContextPriv->driverPrivate = (void *)nv;
+ //nv->nv_screen = nv_screen;
+ nv->dri_screen = driScrnPriv;
+
+ driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache,
+ nv->dri_screen->myNum, "nouveau");
+#ifdef DEBUG
+ __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"),
+ debug_control);
+#endif
+
+ nv->st = st_create_context(pipe, glVis, st_share);
+ return GL_TRUE;
+}
+
+void
+nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
+{
+ struct nouveau_context_dri *nv = driContextPriv->driverPrivate;
+
+ assert(nv);
+
+ st_finish(nv->st);
+ st_destroy_context(nv->st);
+
+ nouveau_context_cleanup(&nv->base);
+
+ FREE(nv);
+}
+
+GLboolean
+nouveau_context_bind(__DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv)
+{
+ struct nouveau_context_dri *nv;
+ struct nouveau_framebuffer *draw, *read;
+
+ if (!driContextPriv) {
+ st_make_current(NULL, NULL, NULL);
+ return GL_TRUE;
+ }
+
+ nv = driContextPriv->driverPrivate;
+ draw = driDrawPriv->driverPrivate;
+ read = driReadPriv->driverPrivate;
+
+ st_make_current(nv->st, draw->stfb, read->stfb);
+
+ if ((nv->dri_drawable != driDrawPriv) ||
+ (nv->last_stamp != driDrawPriv->lastStamp)) {
+ nv->dri_drawable = driDrawPriv;
+ st_resize_framebuffer(draw->stfb, driDrawPriv->w,
+ driDrawPriv->h);
+ nv->last_stamp = driDrawPriv->lastStamp;
+ }
+
+ if (driDrawPriv != driReadPriv) {
+ st_resize_framebuffer(read->stfb, driReadPriv->w,
+ driReadPriv->h);
+ }
+
+ return GL_TRUE;
+}
+
+GLboolean
+nouveau_context_unbind(__DRIcontextPrivate *driContextPriv)
+{
+ struct nouveau_context_dri *nv = driContextPriv->driverPrivate;
+ (void)nv;
+
+ st_flush(nv->st, 0, NULL);
+ return GL_TRUE;
+}
+
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h
new file mode 100644
index 0000000000..8257790d47
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h
@@ -0,0 +1,49 @@
+#ifndef __NOUVEAU_CONTEXT_DRI_H__
+#define __NOUVEAU_CONTEXT_DRI_H__
+
+#include <dri_util.h>
+#include <xmlconfig.h>
+#include <nouveau/nouveau_winsys.h>
+#include "../common/nouveau_context.h"
+#include "../common/nouveau_drmif.h"
+#include "../common/nouveau_dma.h"
+
+struct nouveau_framebuffer {
+ struct st_framebuffer *stfb;
+};
+
+struct nouveau_context_dri {
+ struct nouveau_context base;
+ struct st_context *st;
+
+ /* DRI stuff */
+ __DRIscreenPrivate *dri_screen;
+ __DRIdrawablePrivate *dri_drawable;
+ unsigned int last_stamp;
+ driOptionCache dri_option_cache;
+ drm_context_t drm_context;
+ drmLock drm_lock;
+};
+
+extern GLboolean nouveau_context_create(const __GLcontextModes *,
+ __DRIcontextPrivate *, void *);
+extern void nouveau_context_destroy(__DRIcontextPrivate *);
+extern GLboolean nouveau_context_bind(__DRIcontextPrivate *,
+ __DRIdrawablePrivate *draw,
+ __DRIdrawablePrivate *read);
+extern GLboolean nouveau_context_unbind(__DRIcontextPrivate *);
+
+#ifdef DEBUG
+extern int __nouveau_debug;
+
+#define DEBUG_BO (1 << 0)
+
+#define DBG(flag, ...) do { \
+ if (__nouveau_debug & (DEBUG_##flag)) \
+ NOUVEAU_ERR(__VA_ARGS__); \
+} while(0)
+#else
+#define DBG(flag, ...)
+#endif
+
+#endif
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c
index c6d0c53588..1d7c92376f 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_screen.c
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c
@@ -1,16 +1,15 @@
-#include "utils.h"
-#include "vblank.h"
-#include "xmlpool.h"
-
-#include "pipe/p_context.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_cb_fbo.h"
-
-#include "nouveau_context.h"
-#include "nouveau_drm.h"
-#include "nouveau_dri.h"
-#include "nouveau_local.h"
-#include "nouveau_screen.h"
+#include <utils.h>
+#include <vblank.h>
+#include <xmlpool.h>
+
+#include <pipe/p_context.h>
+#include <state_tracker/st_public.h>
+#include <state_tracker/st_cb_fbo.h>
+#include <nouveau_drm.h>
+#include "../common/nouveau_dri.h"
+#include "../common/nouveau_local.h"
+#include "nouveau_context_dri.h"
+#include "nouveau_screen_dri.h"
#include "nouveau_swapbuffers.h"
#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11
@@ -183,13 +182,12 @@ static const __DRIconfig **
nouveau_screen_create(__DRIscreenPrivate *psp)
{
struct nouveau_dri *nv_dri = psp->pDevPriv;
- struct nouveau_screen *nv_screen;
+ struct nouveau_screen_dri *nv_screen;
static const __DRIversion ddx_expected =
{ 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected =
{ 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
- int ret;
if (!driCheckDriDdxDrmVersions2("nouveau",
&psp->dri_version, &dri_expected,
@@ -209,28 +207,23 @@ nouveau_screen_create(__DRIscreenPrivate *psp)
if (psp->devPrivSize != sizeof(struct nouveau_dri)) {
NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n");
- return GL_FALSE;
+ return NULL;
}
- nv_screen = CALLOC_STRUCT(nouveau_screen);
+ nv_screen = CALLOC_STRUCT(nouveau_screen_dri);
if (!nv_screen)
- return GL_FALSE;
- nv_screen->driScrnPriv = psp;
- psp->private = (void *)nv_screen;
+ return NULL;
driParseOptionInfo(&nv_screen->option_cache,
__driConfigOptions, __driNConfigOptions);
- if ((ret = nouveau_device_open_existing(&nv_screen->device, 0,
- psp->fd, 0))) {
- NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret);
- return GL_FALSE;
+ if (nouveau_screen_init(nv_dri, psp->fd, &nv_screen->base)) {
+ FREE(nv_screen);
+ return NULL;
}
- nv_screen->front_offset = nv_dri->front_offset;
- nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8);
- nv_screen->front_cpp = nv_dri->bpp / 8;
- nv_screen->front_height = nv_dri->height;
+ nv_screen->driScrnPriv = psp;
+ psp->private = (void *)nv_screen;
return (const __DRIconfig **)
nouveau_fill_in_modes(psp, nv_dri->bpp,
@@ -241,9 +234,10 @@ nouveau_screen_create(__DRIscreenPrivate *psp)
static void
nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv)
{
- struct nouveau_screen *nv_screen = driScrnPriv->private;
+ struct nouveau_screen_dri *nv_screen = driScrnPriv->private;
driScrnPriv->private = NULL;
+ nouveau_screen_cleanup(&nv_screen->base);
FREE(nv_screen);
}
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h
new file mode 100644
index 0000000000..1498087819
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.h
@@ -0,0 +1,13 @@
+#ifndef __NOUVEAU_SCREEN_DRI_H__
+#define __NOUVEAU_SCREEN_DRI_H__
+
+#include "../common/nouveau_screen.h"
+#include "xmlconfig.h"
+
+struct nouveau_screen_dri {
+ struct nouveau_screen base;
+ __DRIscreenPrivate *driScrnPriv;
+ driOptionCache option_cache;
+};
+
+#endif
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c
index 70e0104e83..38461b2b0c 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c
@@ -1,34 +1,34 @@
-#include "main/glheader.h"
-#include "glapi/glthread.h"
+#include <main/glheader.h>
+#include <glapi/glthread.h>
#include <GL/internal/glcore.h>
-#include "pipe/p_context.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_cb_fbo.h"
+#include <pipe/p_context.h>
+#include <state_tracker/st_public.h>
+#include <state_tracker/st_context.h>
+#include <state_tracker/st_cb_fbo.h>
-#include "nouveau_context.h"
-#include "nouveau_local.h"
-#include "nouveau_screen.h"
+#include "../common/nouveau_local.h"
+#include "nouveau_context_dri.h"
+#include "nouveau_screen_dri.h"
#include "nouveau_swapbuffers.h"
void
nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
const drm_clip_rect_t *rect)
{
- struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate;
+ struct nouveau_context_dri *nv = dPriv->driContextPriv->driverPrivate;
drm_clip_rect_t *pbox;
int nbox, i;
- LOCK_HARDWARE(nv);
+ LOCK_HARDWARE(&nv->base);
if (!dPriv->numClipRects) {
- UNLOCK_HARDWARE(nv);
+ UNLOCK_HARDWARE(&nv->base);
return;
}
pbox = dPriv->pClipRects;
nbox = dPriv->numClipRects;
- nv->surface_copy_prep(nv, nv->frontbuffer, surf);
+ nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf);
for (i = 0; i < nbox; i++, pbox++) {
int sx, sy, dx, dy, w, h;
@@ -39,11 +39,11 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
w = pbox->x2 - pbox->x1;
h = pbox->y2 - pbox->y1;
- nv->surface_copy(nv, dx, dy, sx, sy, w, h);
+ nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h);
}
- FIRE_RING(nv->nvc->channel);
- UNLOCK_HARDWARE(nv);
+ FIRE_RING(nv->base.nvc->channel);
+ UNLOCK_HARDWARE(&nv->base);
if (nv->last_stamp != dPriv->lastStamp) {
struct nouveau_framebuffer *nvfb = dPriv->driverPrivate;
@@ -84,3 +84,29 @@ nouveau_swap_buffers(__DRIdrawablePrivate *dPriv)
}
}
+void
+nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
+ void *context_private)
+{
+ struct nouveau_context_dri *nv = context_private;
+ __DRIdrawablePrivate *dPriv = nv->dri_drawable;
+
+ nouveau_copy_buffer(dPriv, surf, NULL);
+}
+
+void
+nouveau_contended_lock(struct nouveau_context *nv)
+{
+ struct nouveau_context_dri *nv_sub = (struct nouveau_context_dri*)nv;
+ __DRIdrawablePrivate *dPriv = nv_sub->dri_drawable;
+ __DRIscreenPrivate *sPriv = nv_sub->dri_screen;
+
+ /* If the window moved, may need to set a new cliprect now.
+ *
+ * NOTE: This releases and regains the hw lock, so all state
+ * checking must be done *after* this call:
+ */
+ if (dPriv)
+ DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
+}
+
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h
index 825d3da6da..825d3da6da 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_screen.h b/src/gallium/winsys/drm/nouveau/nouveau_screen.h
deleted file mode 100644
index 388d6be9bb..0000000000
--- a/src/gallium/winsys/drm/nouveau/nouveau_screen.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __NOUVEAU_SCREEN_H__
-#define __NOUVEAU_SCREEN_H__
-
-#include "xmlconfig.h"
-
-struct nouveau_screen {
- __DRIscreenPrivate *driScrnPriv;
- driOptionCache option_cache;
-
- struct nouveau_device *device;
-
- uint32_t front_offset;
- uint32_t front_pitch;
- uint32_t front_cpp;
- uint32_t front_height;
-
- void *nvc;
-};
-
-#endif
diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile
index ff43327778..22d925b643 100644
--- a/src/gallium/winsys/g3dvl/nouveau/Makefile
+++ b/src/gallium/winsys/g3dvl/nouveau/Makefile
@@ -3,35 +3,33 @@ GALLIUMDIR = ../../..
DRMDIR ?= /usr
DRIDIR = ../../../../driclient
-OBJECTS = nouveau_bo.o nouveau_fence.o nouveau_swapbuffers.o nouveau_channel.o \
- nouveau_grobj.o nouveau_context.o nouveau_winsys.o nouveau_lock.o \
- nouveau_winsys_pipe.o nouveau_device.o nouveau_notifier.o nouveau_dma.o \
- nouveau_pushbuf.o nouveau_resource.o nouveau_screen.o nv04_surface.o \
- nv50_surface.o #nouveau_winsys_softpipe.o
-
-CFLAGS += -g -Wall -fPIC \
- -I${GALLIUMDIR}/include \
- -I${GALLIUMDIR}/winsys/g3dvl \
- -I${DRMDIR}/include \
- -I${DRMDIR}/include/drm \
- -I${GALLIUMDIR}/drivers \
- -I${GALLIUMDIR}/auxiliary \
+OBJECTS = nouveau_screen_vl.o nouveau_context_vl.o nouveau_swapbuffers.o
+
+CFLAGS += -g -Wall -Werror=implicit-function-declaration -fPIC \
+ -I${GALLIUMDIR}/include \
+ -I${GALLIUMDIR}/winsys/g3dvl \
+ -I${GALLIUMDIR}/winsys/drm/nouveau \
+ -I${DRMDIR}/include \
+ -I${DRMDIR}/include/drm \
+ -I${GALLIUMDIR}/drivers \
+ -I${GALLIUMDIR}/auxiliary \
-I${DRIDIR}/include
-LDFLAGS += -L${DRMDIR}/lib \
- -L${DRIDIR}/lib \
- -L${GALLIUMDIR}/auxiliary/draw \
- -L${GALLIUMDIR}/auxiliary/tgsi \
- -L${GALLIUMDIR}/auxiliary/translate \
- -L${GALLIUMDIR}/auxiliary/rtasm \
- -L${GALLIUMDIR}/auxiliary/cso_cache \
- -L${GALLIUMDIR}/drivers/nv10 \
- -L${GALLIUMDIR}/drivers/nv20 \
- -L${GALLIUMDIR}/drivers/nv30 \
- -L${GALLIUMDIR}/drivers/nv40 \
+LDFLAGS += -L${DRMDIR}/lib \
+ -L${DRIDIR}/lib \
+ -L${GALLIUMDIR}/winsys/drm/nouveau/common \
+ -L${GALLIUMDIR}/auxiliary/draw \
+ -L${GALLIUMDIR}/auxiliary/tgsi \
+ -L${GALLIUMDIR}/auxiliary/translate \
+ -L${GALLIUMDIR}/auxiliary/rtasm \
+ -L${GALLIUMDIR}/auxiliary/cso_cache \
+ -L${GALLIUMDIR}/drivers/nv10 \
+ -L${GALLIUMDIR}/drivers/nv20 \
+ -L${GALLIUMDIR}/drivers/nv30 \
+ -L${GALLIUMDIR}/drivers/nv40 \
-L${GALLIUMDIR}/drivers/nv50
-LIBS += -ldriclient -ldrm -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm
+LIBS += -lnouveaudrm -ldriclient -ldrm -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm
#############################################
diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c
deleted file mode 100644
index 06a61fcda3..0000000000
--- a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c
+++ /dev/null
@@ -1,370 +0,0 @@
-#include "pipe/p_defines.h"
-#include "pipe/p_context.h"
-#include "pipe/p_screen.h"
-#include "util/u_memory.h"
-
-#include "nouveau_context.h"
-#include "nouveau_dri.h"
-#include "nouveau_local.h"
-#include "nouveau_screen.h"
-#include "nouveau_winsys_pipe.h"
-
-/*
-#ifdef DEBUG
-static const struct dri_debug_control debug_control[] = {
- { "bo", DEBUG_BO },
- { NULL, 0 }
-};
-int __nouveau_debug = 0;
-#endif
-*/
-
-/*
- * TODO: Re-examine dri_screen, dri_context, nouveau_screen, nouveau_context
- * relationships, seems like there is a lot of room for simplification there.
- */
-
-static void
-nouveau_channel_context_destroy(struct nouveau_channel_context *nvc)
-{
- nouveau_grobj_free(&nvc->NvCtxSurf2D);
- nouveau_grobj_free(&nvc->NvImageBlit);
- nouveau_grobj_free(&nvc->NvGdiRect);
- nouveau_grobj_free(&nvc->NvM2MF);
- nouveau_grobj_free(&nvc->Nv2D);
- nouveau_grobj_free(&nvc->NvSwzSurf);
- nouveau_grobj_free(&nvc->NvSIFM);
-
- nouveau_notifier_free(&nvc->sync_notifier);
-
- nouveau_channel_free(&nvc->channel);
-
- FREE(nvc);
-}
-
-static struct nouveau_channel_context *
-nouveau_channel_context_create(struct nouveau_device *dev)
-{
- struct nouveau_channel_context *nvc;
- int ret;
-
- nvc = CALLOC_STRUCT(nouveau_channel_context);
- if (!nvc)
- return NULL;
-
- if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002,
- &nvc->channel))) {
- NOUVEAU_ERR("Error creating GPU channel: %d\n", ret);
- nouveau_channel_context_destroy(nvc);
- return NULL;
- }
-
- nvc->next_handle = 0x80000000;
-
- if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1,
- &nvc->sync_notifier))) {
- NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret);
- nouveau_channel_context_destroy(nvc);
- return NULL;
- }
-
- switch (dev->chipset & 0xf0) {
- case 0x50:
- case 0x80:
- case 0x90:
- ret = nouveau_surface_channel_create_nv50(nvc);
- break;
- default:
- ret = nouveau_surface_channel_create_nv04(nvc);
- break;
- }
-
- if (ret) {
- NOUVEAU_ERR("Error initialising surface objects: %d\n", ret);
- nouveau_channel_context_destroy(nvc);
- return NULL;
- }
-
- return nvc;
-}
-
-int
-nouveau_context_create(dri_context_t *dri_context)
-{
- dri_screen_t *dri_screen = dri_context->dri_screen;
- struct nouveau_screen *nv_screen = dri_screen->private;
- struct nouveau_context *nv = CALLOC_STRUCT(nouveau_context);
- struct pipe_context *pipe = NULL;
- struct nouveau_channel_context *nvc = NULL;
- struct nouveau_device *dev = nv_screen->device;
- int i;
-
- switch (dev->chipset & 0xf0) {
- case 0x10:
- case 0x20:
- /* NV10 */
- case 0x30:
- /* NV30 */
- case 0x40:
- case 0x60:
- /* NV40 */
- case 0x50:
- case 0x80:
- case 0x90:
- /* G80 */
- break;
- default:
- NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset);
- return 1;
- }
-
- dri_context->private = (void*)nv;
- nv->dri_context = dri_context;
- nv->nv_screen = nv_screen;
-
- {
- struct nouveau_device_priv *nvdev = nouveau_device(dev);
-
- nvdev->ctx = dri_context->drm_context;
- nvdev->lock = (drmLock*)&dri_screen->sarea->lock;
- }
-
- /*
- driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache,
- nv->dri_screen->myNum, "nouveau");
-#ifdef DEBUG
- __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"),
- debug_control);
-#endif
- */
-
- /*XXX: Hack up a fake region and buffer object for front buffer.
- * This will go away with TTM, replaced with a simple reference
- * of the front buffer handle passed to us by the DDX.
- */
- {
- struct pipe_surface *fb_surf;
- struct nouveau_pipe_buffer *fb_buf;
- struct nouveau_bo_priv *fb_bo;
-
- fb_bo = calloc(1, sizeof(struct nouveau_bo_priv));
- fb_bo->drm.offset = nv_screen->front_offset;
- fb_bo->drm.flags = NOUVEAU_MEM_FB;
- fb_bo->drm.size = nv_screen->front_pitch *
- nv_screen->front_height;
- fb_bo->refcount = 1;
- fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM;
- fb_bo->base.offset = fb_bo->drm.offset;
- fb_bo->base.handle = (unsigned long)fb_bo;
- fb_bo->base.size = fb_bo->drm.size;
- fb_bo->base.device = nv_screen->device;
-
- fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer));
- fb_buf->bo = &fb_bo->base;
-
- fb_surf = calloc(1, sizeof(struct pipe_surface));
- if (nv_screen->front_cpp == 2)
- fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM;
- else
- fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM;
- pf_get_block(fb_surf->format, &fb_surf->block);
- fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp;
- fb_surf->height = nv_screen->front_height;
- fb_surf->stride = fb_surf->width * fb_surf->block.size;
- fb_surf->refcount = 1;
- fb_surf->buffer = &fb_buf->base;
-
- nv->frontbuffer = fb_surf;
- }
-
- nvc = nv_screen->nvc;
-
- if (!nvc) {
- nvc = nouveau_channel_context_create(dev);
- if (!nvc) {
- NOUVEAU_ERR("Failed initialising GPU context\n");
- return 1;
- }
- nv_screen->nvc = nvc;
- }
-
- nvc->refcount++;
- nv->nvc = nvc;
-
- /* Find a free slot for a pipe context, allocate a new one if needed */
- nv->pctx_id = -1;
- for (i = 0; i < nvc->nr_pctx; i++) {
- if (nvc->pctx[i] == NULL) {
- nv->pctx_id = i;
- break;
- }
- }
-
- if (nv->pctx_id < 0) {
- nv->pctx_id = nvc->nr_pctx++;
- nvc->pctx =
- realloc(nvc->pctx,
- sizeof(struct pipe_context *) * nvc->nr_pctx);
- }
-
- /* Create pipe */
- switch (dev->chipset & 0xf0) {
- case 0x50:
- case 0x80:
- case 0x90:
- if (nouveau_surface_init_nv50(nv))
- return 1;
- break;
- default:
- if (nouveau_surface_init_nv04(nv))
- return 1;
- break;
- }
-
- if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) {
- struct pipe_screen *pscreen;
-
- pipe = nouveau_pipe_create(nv);
- if (!pipe)
- NOUVEAU_ERR("Couldn't create hw pipe\n");
- pscreen = nvc->pscreen;
-
- nv->cap.hw_vertex_buffer =
- pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF);
- nv->cap.hw_index_buffer =
- pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF);
- }
-
- /* XXX: nouveau_winsys_softpipe needs a mesa header removed before we can compile it. */
- /*
- if (!pipe) {
- NOUVEAU_MSG("Using softpipe\n");
- pipe = nouveau_create_softpipe(nv);
- if (!pipe) {
- NOUVEAU_ERR("Error creating pipe, bailing\n");
- return 1;
- }
- }
- */
- if (!pipe) {
- NOUVEAU_ERR("Error creating pipe, bailing\n");
- return 1;
- }
-
- pipe->priv = nv;
-
- return 0;
-}
-
-void
-nouveau_context_destroy(dri_context_t *dri_context)
-{
- struct nouveau_context *nv = dri_context->private;
- struct nouveau_channel_context *nvc = nv->nvc;
-
- assert(nv);
-
- if (nv->pctx_id >= 0) {
- nvc->pctx[nv->pctx_id] = NULL;
- if (--nvc->refcount <= 0) {
- nouveau_channel_context_destroy(nvc);
- nv->nv_screen->nvc = NULL;
- }
- }
-
- free(nv);
-}
-
-int
-nouveau_context_bind(struct nouveau_context *nv, dri_drawable_t *dri_drawable)
-{
- assert(nv);
- assert(dri_drawable);
-
- if (nv->dri_drawable != dri_drawable)
- {
- nv->dri_drawable = dri_drawable;
- dri_drawable->private = nv;
- }
-
- return 0;
-}
-
-int
-nouveau_context_unbind(struct nouveau_context *nv)
-{
- assert(nv);
-
- nv->dri_drawable = NULL;
-
- return 0;
-}
-
-/* Show starts here */
-
-int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable)
-{
- struct nouveau_context *nv;
- dri_drawable_t *dri_drawable;
-
- nv = pipe->priv;
-
- driCreateDrawable(nv->nv_screen->dri_screen, drawable, &dri_drawable);
-
- nouveau_context_bind(nv, dri_drawable);
-
- return 0;
-}
-
-int unbind_pipe_drawable(struct pipe_context *pipe)
-{
- nouveau_context_unbind(pipe->priv);
-
- return 0;
-}
-
-struct pipe_context* create_pipe_context(Display *display, int screen)
-{
- dri_screen_t *dri_screen;
- dri_framebuffer_t dri_framebuf;
- dri_context_t *dri_context;
- struct nouveau_context *nv;
-
- driCreateScreen(display, screen, &dri_screen, &dri_framebuf);
- driCreateContext(dri_screen, XDefaultVisual(display, screen), &dri_context);
-
- nouveau_screen_create(dri_screen, &dri_framebuf);
- nouveau_context_create(dri_context);
-
- nv = dri_context->private;
-
- return nv->nvc->pctx[nv->pctx_id];
-}
-
-int destroy_pipe_context(struct pipe_context *pipe)
-{
- struct pipe_screen *screen;
- struct pipe_winsys *winsys;
- struct nouveau_context *nv;
- dri_screen_t *dri_screen;
- dri_context_t *dri_context;
-
- assert(pipe);
-
- screen = pipe->screen;
- winsys = pipe->winsys;
- nv = pipe->priv;
- dri_context = nv->dri_context;
- dri_screen = dri_context->dri_screen;
-
- pipe->destroy(pipe);
- screen->destroy(screen);
- free(winsys);
-
- nouveau_context_destroy(dri_context);
- nouveau_screen_destroy(dri_screen);
- driDestroyContext(dri_context);
- driDestroyScreen(dri_screen);
-
- return 0;
-}
diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h
deleted file mode 100644
index 395a3ab790..0000000000
--- a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef __NOUVEAU_CONTEXT_H__
-#define __NOUVEAU_CONTEXT_H__
-
-/*#include "xmlconfig.h"*/
-
-#include <driclient.h>
-#include "nouveau/nouveau_winsys.h"
-#include "nouveau_drmif.h"
-#include "nouveau_dma.h"
-
-struct nouveau_channel_context {
- struct pipe_screen *pscreen;
- int refcount;
-
- unsigned cur_pctx;
- unsigned nr_pctx;
- struct pipe_context **pctx;
-
- struct nouveau_channel *channel;
-
- struct nouveau_notifier *sync_notifier;
-
- /* Common */
- struct nouveau_grobj *NvM2MF;
- /* NV04-NV40 */
- struct nouveau_grobj *NvCtxSurf2D;
- struct nouveau_grobj *NvSwzSurf;
- struct nouveau_grobj *NvImageBlit;
- struct nouveau_grobj *NvGdiRect;
- struct nouveau_grobj *NvSIFM;
- /* G80 */
- struct nouveau_grobj *Nv2D;
-
- uint32_t next_handle;
- uint32_t next_subchannel;
- uint32_t next_sequence;
-};
-
-struct nouveau_context {
- /* DRI stuff */
- dri_context_t *dri_context;
- dri_drawable_t *dri_drawable;
- unsigned int last_stamp;
- /*driOptionCache dri_option_cache;*/
- drm_context_t drm_context;
- drmLock drm_lock;
- int locked;
- struct nouveau_screen *nv_screen;
- struct pipe_surface *frontbuffer;
-
- struct {
- int hw_vertex_buffer;
- int hw_index_buffer;
- } cap;
-
- /* Hardware context */
- struct nouveau_channel_context *nvc;
- int pctx_id;
-
- /* pipe_surface accel */
- struct pipe_surface *surf_src, *surf_dst;
- unsigned surf_src_offset, surf_dst_offset;
-
- int (*surface_copy_prep)(struct nouveau_context *,
- struct pipe_surface *dst,
- struct pipe_surface *src);
- void (*surface_copy)(struct nouveau_context *, unsigned dx, unsigned dy,
- unsigned sx, unsigned sy, unsigned w, unsigned h);
- void (*surface_copy_done)(struct nouveau_context *);
- int (*surface_fill)(struct nouveau_context *, struct pipe_surface *,
- unsigned, unsigned, unsigned, unsigned, unsigned);
-};
-
-extern int nouveau_context_create(dri_context_t *);
-extern void nouveau_context_destroy(dri_context_t *);
-extern int nouveau_context_bind(struct nouveau_context *, dri_drawable_t *);
-extern int nouveau_context_unbind(struct nouveau_context *);
-
-#ifdef DEBUG
-extern int __nouveau_debug;
-
-#define DEBUG_BO (1 << 0)
-
-#define DBG(flag, ...) do { \
- if (__nouveau_debug & (DEBUG_##flag)) \
- NOUVEAU_ERR(__VA_ARGS__); \
-} while(0)
-#else
-#define DBG(flag, ...)
-#endif
-
-extern void LOCK_HARDWARE(struct nouveau_context *);
-extern void UNLOCK_HARDWARE(struct nouveau_context *);
-
-extern int
-nouveau_surface_channel_create_nv04(struct nouveau_channel_context *);
-extern int
-nouveau_surface_channel_create_nv50(struct nouveau_channel_context *);
-extern int nouveau_surface_init_nv04(struct nouveau_context *);
-extern int nouveau_surface_init_nv50(struct nouveau_context *);
-
-extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int);
-extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *);
-
-#endif
diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.c
new file mode 100644
index 0000000000..dfc4905bc0
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.c
@@ -0,0 +1,172 @@
+#include "nouveau_context_vl.h"
+#include <pipe/p_defines.h>
+#include <pipe/p_context.h>
+#include <pipe/p_screen.h>
+#include <util/u_memory.h>
+#include <common/nouveau_dri.h>
+#include <common/nouveau_local.h>
+#include <common/nouveau_winsys_pipe.h>
+#include "nouveau_screen_vl.h"
+
+/*
+#ifdef DEBUG
+static const struct dri_debug_control debug_control[] = {
+ { "bo", DEBUG_BO },
+ { NULL, 0 }
+};
+int __nouveau_debug = 0;
+#endif
+*/
+
+int
+nouveau_context_create(dri_context_t *dri_context)
+{
+ dri_screen_t *dri_screen;
+ struct nouveau_screen_vl *nv_screen;
+ struct nouveau_context_vl *nv;
+
+ assert (dri_context);
+
+ dri_screen = dri_context->dri_screen;
+ nv_screen = dri_screen->private;
+ nv = CALLOC_STRUCT(nouveau_context_vl);
+
+ if (!nv)
+ return 1;
+
+ if (nouveau_context_init(&nv_screen->base, dri_context->drm_context,
+ (drmLock*)&dri_screen->sarea->lock, NULL, &nv->base))
+ {
+ FREE(nv);
+ return 1;
+ }
+
+ dri_context->private = (void*)nv;
+ nv->dri_context = dri_context;
+ nv->nv_screen = nv_screen;
+
+ /*
+ driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache,
+ nv->dri_screen->myNum, "nouveau");
+#ifdef DEBUG
+ __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"),
+ debug_control);
+#endif
+ */
+
+ nv->base.nvc->pctx[nv->base.pctx_id]->priv = nv;
+
+ return 0;
+}
+
+void
+nouveau_context_destroy(dri_context_t *dri_context)
+{
+ struct nouveau_context_vl *nv = dri_context->private;
+
+ assert(dri_context);
+
+ nouveau_context_cleanup(&nv->base);
+
+ FREE(nv);
+}
+
+int
+nouveau_context_bind(struct nouveau_context_vl *nv, dri_drawable_t *dri_drawable)
+{
+ assert(nv);
+ assert(dri_drawable);
+
+ if (nv->dri_drawable != dri_drawable)
+ {
+ nv->dri_drawable = dri_drawable;
+ dri_drawable->private = nv;
+ }
+
+ return 0;
+}
+
+int
+nouveau_context_unbind(struct nouveau_context_vl *nv)
+{
+ assert(nv);
+
+ nv->dri_drawable = NULL;
+
+ return 0;
+}
+
+/* Show starts here */
+
+int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable)
+{
+ struct nouveau_context_vl *nv;
+ dri_drawable_t *dri_drawable;
+
+ assert(pipe);
+
+ nv = pipe->priv;
+
+ driCreateDrawable(nv->nv_screen->dri_screen, drawable, &dri_drawable);
+
+ nouveau_context_bind(nv, dri_drawable);
+
+ return 0;
+}
+
+int unbind_pipe_drawable(struct pipe_context *pipe)
+{
+ assert (pipe);
+
+ nouveau_context_unbind(pipe->priv);
+
+ return 0;
+}
+
+struct pipe_context* create_pipe_context(Display *display, int screen)
+{
+ dri_screen_t *dri_screen;
+ dri_framebuffer_t dri_framebuf;
+ dri_context_t *dri_context;
+ struct nouveau_context_vl *nv;
+
+ assert(display);
+
+ driCreateScreen(display, screen, &dri_screen, &dri_framebuf);
+ driCreateContext(dri_screen, XDefaultVisual(display, screen), &dri_context);
+
+ nouveau_screen_create(dri_screen, &dri_framebuf);
+ nouveau_context_create(dri_context);
+
+ nv = dri_context->private;
+
+ return nv->base.nvc->pctx[nv->base.pctx_id];
+}
+
+int destroy_pipe_context(struct pipe_context *pipe)
+{
+ struct pipe_screen *screen;
+ struct pipe_winsys *winsys;
+ struct nouveau_context_vl *nv;
+ dri_screen_t *dri_screen;
+ dri_context_t *dri_context;
+
+ assert(pipe);
+
+ screen = pipe->screen;
+ winsys = pipe->winsys;
+ nv = pipe->priv;
+ dri_context = nv->dri_context;
+ dri_screen = dri_context->dri_screen;
+
+ pipe->destroy(pipe);
+ screen->destroy(screen);
+ FREE(winsys);
+
+ nouveau_context_destroy(dri_context);
+ nouveau_screen_destroy(dri_screen);
+ driDestroyContext(dri_context);
+ driDestroyScreen(dri_screen);
+
+ return 0;
+}
diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.h
new file mode 100644
index 0000000000..1115c3130c
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_context_vl.h
@@ -0,0 +1,39 @@
+#ifndef __NOUVEAU_CONTEXT_VL_H__
+#define __NOUVEAU_CONTEXT_VL_H__
+
+#include <driclient.h>
+#include <nouveau/nouveau_winsys.h>
+#include <common/nouveau_context.h>
+
+/*#include "xmlconfig.h"*/
+
+struct nouveau_context_vl {
+ struct nouveau_context base;
+ struct nouveau_screen_vl *nv_screen;
+ dri_context_t *dri_context;
+ dri_drawable_t *dri_drawable;
+ unsigned int last_stamp;
+ /*driOptionCache dri_option_cache;*/
+ drm_context_t drm_context;
+ drmLock drm_lock;
+};
+
+extern int nouveau_context_create(dri_context_t *);
+extern void nouveau_context_destroy(dri_context_t *);
+extern int nouveau_context_bind(struct nouveau_context_vl *, dri_drawable_t *);
+extern int nouveau_context_unbind(struct nouveau_context_vl *);
+
+#ifdef DEBUG
+extern int __nouveau_debug;
+
+#define DEBUG_BO (1 << 0)
+
+#define DBG(flag, ...) do { \
+ if (__nouveau_debug & (DEBUG_##flag)) \
+ NOUVEAU_ERR(__VA_ARGS__); \
+} while(0)
+#else
+#define DBG(flag, ...)
+#endif
+
+#endif
diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c
index 375634bd05..f292586974 100644
--- a/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c
+++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c
@@ -25,12 +25,12 @@
*
**************************************************************************/
-#include <pthread.h>
+#include <pipe/p_thread.h>
#include <driclient.h>
#include "nouveau_context.h"
#include "nouveau_screen.h"
-static pthread_mutex_t lockMutex = PTHREAD_MUTEX_INITIALIZER;
+pipe_static_mutex(lockMutex);
static void
nouveau_contended_lock(struct nouveau_context *nv, unsigned int flags)
@@ -62,7 +62,7 @@ LOCK_HARDWARE(struct nouveau_context *nv)
struct nouveau_device_priv *nvdev = nouveau_device(dev);
char __ret=0;
- pthread_mutex_lock(&lockMutex);
+ pipe_mutex_lock(lockMutex);
assert(!nv->locked);
DRM_CAS(nvdev->lock, nvdev->ctx,
@@ -88,5 +88,5 @@ UNLOCK_HARDWARE(struct nouveau_context *nv)
DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx);
- pthread_mutex_unlock(&lockMutex);
+ pipe_mutex_unlock(lockMutex);
}
diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c
index f80d00050c..658dafd910 100644
--- a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c
+++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.c
@@ -1,11 +1,8 @@
-#include "pipe/p_context.h"
-#include "util/u_memory.h"
-#include "nouveau_context.h"
+#include "nouveau_screen_vl.h"
+#include <util/u_memory.h>
#include <nouveau_drm.h>
-#include "nouveau_dri.h"
-#include "nouveau_local.h"
-#include "nouveau_screen.h"
-#include "nouveau_swapbuffers.h"
+#include <common/nouveau_dri.h>
+#include <common/nouveau_local.h>
#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11
#error nouveau_drm.h version does not match expected version
@@ -50,34 +47,33 @@ int nouveau_check_dri_drm_ddx(dri_version_t *dri, dri_version_t *drm, dri_versio
int
nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf)
{
- struct nouveau_dri *nv_dri = dri_framebuf->private;
- struct nouveau_screen *nv_screen;
- int ret;
+ struct nouveau_dri *nv_dri = dri_framebuf->private;
+ struct nouveau_screen_vl *nv_screen;
+
+ assert(dri_screen);
+ assert(dri_framebuf);
if (nouveau_check_dri_drm_ddx(&dri_screen->dri, &dri_screen->drm, &dri_screen->ddx))
return 1;
- nv_screen = CALLOC_STRUCT(nouveau_screen);
+ nv_screen = CALLOC_STRUCT(nouveau_screen_vl);
+
if (!nv_screen)
return 1;
- nv_screen->dri_screen = dri_screen;
- dri_screen->private = (void*)nv_screen;
+
+ if (nouveau_screen_init(nv_dri, dri_screen->fd, &nv_screen->base))
+ {
+ FREE(nv_screen);
+ return 1;
+ }
/*
driParseOptionInfo(&nv_screen->option_cache,
__driConfigOptions, __driNConfigOptions);
*/
- if ((ret = nouveau_device_open_existing(&nv_screen->device, 0,
- dri_screen->fd, 0))) {
- NOUVEAU_ERR("Failed opening nouveau device: %d.\n", ret);
- return 1;
- }
-
- nv_screen->front_offset = nv_dri->front_offset;
- nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8);
- nv_screen->front_cpp = nv_dri->bpp / 8;
- nv_screen->front_height = nv_dri->height;
+ nv_screen->dri_screen = dri_screen;
+ dri_screen->private = (void*)nv_screen;
return 0;
}
@@ -85,7 +81,8 @@ nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf)
void
nouveau_screen_destroy(dri_screen_t *dri_screen)
{
- struct nouveau_screen *nv_screen = dri_screen->private;
+ struct nouveau_screen_vl *nv_screen = dri_screen->private;
+ nouveau_screen_cleanup(&nv_screen->base);
FREE(nv_screen);
}
diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.h
index 8a58bb7556..0c1ceca6de 100644
--- a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h
+++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen_vl.h
@@ -1,19 +1,16 @@
-#ifndef __NOUVEAU_SCREEN_H__
-#define __NOUVEAU_SCREEN_H__
+#ifndef __NOUVEAU_SCREEN_VL_H__
+#define __NOUVEAU_SCREEN_VL_H__
+
+#include <driclient.h>
+#include <common/nouveau_screen.h>
/* TODO: Investigate using DRI options for interesting things */
/*#include "xmlconfig.h"*/
-struct nouveau_screen {
+struct nouveau_screen_vl
+{
+ struct nouveau_screen base;
dri_screen_t *dri_screen;
- struct nouveau_device *device;
- struct nouveau_channel_context *nvc;
-
- uint32_t front_offset;
- uint32_t front_pitch;
- uint32_t front_cpp;
- uint32_t front_height;
-
/*driOptionCache option_cache;*/
};
@@ -21,4 +18,3 @@ int nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_frame
void nouveau_screen_destroy(dri_screen_t *dri_screen);
#endif
-
diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c
index 7916c80615..16e6d5543c 100644
--- a/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c
+++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c
@@ -1,26 +1,26 @@
-#include "pipe/p_context.h"
-#include "nouveau_context.h"
-#include "nouveau_local.h"
-#include "nouveau_screen.h"
+#include <driclient.h>
+#include <common/nouveau_local.h>
+#include <common/nouveau_screen.h>
+#include "nouveau_context_vl.h"
#include "nouveau_swapbuffers.h"
void
nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf,
const drm_clip_rect_t *rect)
{
- struct nouveau_context *nv = dri_drawable->private;
- drm_clip_rect_t *pbox;
- int nbox, i;
+ struct nouveau_context_vl *nv = dri_drawable->private;
+ drm_clip_rect_t *pbox;
+ int nbox, i;
- LOCK_HARDWARE(nv);
+ LOCK_HARDWARE(&nv->base);
if (!dri_drawable->num_cliprects) {
- UNLOCK_HARDWARE(nv);
+ UNLOCK_HARDWARE(&nv->base);
return;
}
pbox = dri_drawable->cliprects;
nbox = dri_drawable->num_cliprects;
- nv->surface_copy_prep(nv, nv->frontbuffer, surf);
+ nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf);
for (i = 0; i < nbox; i++, pbox++) {
int sx, sy, dx, dy, w, h;
@@ -31,14 +31,11 @@ nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf,
w = pbox->x2 - pbox->x1;
h = pbox->y2 - pbox->y1;
- nv->surface_copy(nv, dx, dy, sx, sy, w, h);
+ nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h);
}
- FIRE_RING(nv->nvc->channel);
- UNLOCK_HARDWARE(nv);
-
- //if (nv->last_stamp != dri_drawable->last_sarea_stamp)
- //nv->last_stamp = dri_drawable->last_sarea_stamp;
+ FIRE_RING(nv->base.nvc->channel);
+ UNLOCK_HARDWARE(&nv->base);
}
void
@@ -62,3 +59,35 @@ nouveau_swap_buffers(dri_drawable_t *dri_drawable, struct pipe_surface *surf)
nouveau_copy_buffer(dri_drawable, surf, NULL);
}
+void
+nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
+ void *context_private)
+{
+ struct nouveau_context_vl *nv;
+ dri_drawable_t *dri_drawable;
+
+ assert(pws);
+ assert(surf);
+ assert(context_private);
+
+ nv = context_private;
+ dri_drawable = nv->dri_drawable;
+
+ nouveau_copy_buffer(dri_drawable, surf, NULL);
+}
+
+void
+nouveau_contended_lock(struct nouveau_context *nv)
+{
+ struct nouveau_context_vl *nv_vl = (struct nouveau_context_vl*)nv;
+ dri_drawable_t *dri_drawable = nv_vl->dri_drawable;
+ dri_screen_t *dri_screen = nv_vl->dri_context->dri_screen;
+
+ /* If the window moved, may need to set a new cliprect now.
+ *
+ * NOTE: This releases and regains the hw lock, so all state
+ * checking must be done *after* this call:
+ */
+ if (dri_drawable)
+ DRI_VALIDATE_DRAWABLE_INFO(dri_screen, dri_drawable);
+}
diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c
index 4f6ac9cad0..17c409e1ce 100644
--- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c
+++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c
@@ -89,6 +89,31 @@ nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s)
}
}
+static uint32_t
+nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
+{
+ uint32_t flags = NOUVEAU_BO_LOCAL;
+
+ if (usage & PIPE_BUFFER_USAGE_PIXEL) {
+ if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
+ flags |= NOUVEAU_BO_GART;
+ if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE))
+ flags |= NOUVEAU_BO_VRAM;
+ }
+
+ 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)
@@ -107,23 +132,7 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
nvbuf->base.usage = usage;
nvbuf->base.size = size;
- flags = NOUVEAU_BO_LOCAL;
-
- if (usage & PIPE_BUFFER_USAGE_PIXEL) {
- if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
- flags |= NOUVEAU_BO_GART;
- flags |= NOUVEAU_BO_VRAM;
- }
-
- 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;
- }
+ flags = nouveau_flags_from_usage(nv, usage);
if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
free(nvbuf);
@@ -175,6 +184,26 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
map_flags |= NOUVEAU_BO_WR;
+ if ((map_flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_WR &&
+ !nouveau_bo_busy(nvbuf->bo, map_flags)) {
+ /* XXX: Technically incorrect. If the client maps a buffer for write-only
+ * and leaves part of the buffer untouched it probably expects those parts
+ * to remain intact. This is violated because we allocate a whole new buffer
+ * and don't copy the previous buffer's contents, so this optimization is
+ * only valid if the client intends to overwrite the whole buffer.
+ */
+ struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
+ struct nouveau_context *nv = nvpws->nv;
+ struct nouveau_device *dev = nv->nv_screen->device;
+ struct nouveau_bo *rename;
+ uint32_t flags = nouveau_flags_from_usage(nv, buf->usage);
+
+ if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) {
+ nouveau_bo_del(&nvbuf->bo);
+ nvbuf->bo = rename;
+ }
+ }
+
if (nouveau_bo_map(nvbuf->bo, map_flags))
return NULL;
return nvbuf->bo->map;