xf86-video-modesetting: src/crtc.c src/dri2.c src/driver.c src/driver.h src/exa.c src/Makefile.am src/output.c

Alan Hourihane alanh at kemper.freedesktop.org
Mon Jun 16 07:08:45 PDT 2008


 src/Makefile.am |    3 
 src/crtc.c      |   47 +++++++----
 src/dri2.c      |  127 ++++++++++++++++++++++++++++++++
 src/driver.c    |  220 ++++++++++++++++++++++++++++++++++++++++----------------
 src/driver.h    |   10 +-
 src/exa.c       |  189 ++++++++++++++++++++++++++++++++++++++++++++----
 src/output.c    |   48 +++++-------
 7 files changed, 521 insertions(+), 123 deletions(-)

New commits:
commit 3390583c92f2dfb1d525bb55d25edf6ce8b753ae
Author: Alan Hourihane <alanh at tungstengraphics.com>
Date:   Mon Jun 16 15:07:39 2008 +0100

    Add DRI2 support.
    
    Add EXA stubs.
    
    Currently tested with i915.

diff --git a/src/Makefile.am b/src/Makefile.am
index 17d884f..a182d44 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -37,6 +37,7 @@ modesetting_drv_la_SOURCES = \
 	 driver.h \
 	 output.c \
 	 crtc.c \
-	 exa.c
+	 exa.c \
+	 dri2.c
 
 EXTRA_DIST =
diff --git a/src/crtc.c b/src/crtc.c
index 14ee53e..89ffe92 100644
--- a/src/crtc.c
+++ b/src/crtc.c
@@ -168,8 +168,11 @@ crtc_destroy(xf86CrtcPtr crtc)
     modesettingPtr ms = modesettingPTR(crtc->scrn);
     struct crtc_private *crtcp = crtc->driver_private;
 
-    drmBOUnreference(ms->fd, &crtcp->cursor_bo);
+    if (crtcp->cursor_bo.handle)
+	drmBOUnreference(ms->fd, &crtcp->cursor_bo);
+
     drmModeFreeCrtc(crtcp->drm_crtc);
+    xfree(crtcp);
 }
 
 static void
@@ -179,9 +182,17 @@ crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
     modesettingPtr ms = modesettingPTR(crtc->scrn);
     struct crtc_private *crtcp = crtc->driver_private;
 
-    drmBOMap(ms->fd, &crtcp->cursor_bo, DRM_BO_FLAG_WRITE, 0, (void **)&ptr);
+    if (!crtcp->cursor_bo.handle)
+        drmBOCreate(ms->fd, 64 * 64 * 4, 0, NULL,
+		DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE 
+		| DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE |
+		DRM_BO_FLAG_MEM_VRAM,
+		DRM_BO_HINT_DONT_FENCE, &crtcp->cursor_bo);
+
+    drmBOMap(ms->fd, &crtcp->cursor_bo, DRM_BO_FLAG_WRITE, DRM_BO_HINT_DONT_FENCE, (void **)&ptr);
 
-    memcpy (ptr, image, 64 * 64 * 4);
+    if (ptr)
+	memcpy (ptr, image, 64 * 64 * 4);
 
     drmBOUnmap(ms->fd, &crtcp->cursor_bo);
 }
@@ -201,7 +212,8 @@ crtc_show_cursor (xf86CrtcPtr crtc)
     modesettingPtr ms = modesettingPTR(crtc->scrn);
     struct crtc_private *crtcp = crtc->driver_private;
 
-    drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, crtcp->cursor_bo.handle, 64, 64);
+    if (crtcp->cursor_bo.handle)
+	drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, crtcp->cursor_bo.handle, 64, 64);
 }
 
 static void
@@ -213,12 +225,6 @@ crtc_hide_cursor (xf86CrtcPtr crtc)
     drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0);
 }
 
-static void
-crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
-{
-    ScrnInfoPtr		scrn = crtc->scrn;
-}
-
 static const xf86CrtcFuncsRec crtc_funcs = {
     .dpms = crtc_dpms,
     .save = NULL,
@@ -233,16 +239,28 @@ static const xf86CrtcFuncsRec crtc_funcs = {
     .shadow_create = crtc_shadow_create,
     .shadow_allocate = crtc_shadow_allocate,
     .shadow_destroy = crtc_shadow_destroy,
-    .set_cursor_colors = crtc_set_cursor_colors,
     .set_cursor_position = crtc_set_cursor_position,
     .show_cursor = crtc_show_cursor,
     .hide_cursor = crtc_hide_cursor,
     .load_cursor_image = NULL,	/* lets convert to argb only */
+    .set_cursor_colors = NULL, /* using argb only */
     .load_cursor_argb = crtc_load_cursor_argb,
     .destroy = crtc_destroy,
 };
 
 void
+cursor_destroy(xf86CrtcPtr crtc)
+{
+    modesettingPtr ms = modesettingPTR(crtc->scrn);
+    struct crtc_private *crtcp = crtc->driver_private;
+
+    if (crtcp->cursor_bo.handle) {
+    	drmBOSetStatus(ms->fd, &crtcp->cursor_bo, 0, 0, 0, 0, 0);
+    	drmBOUnreference(ms->fd, &crtcp->cursor_bo);
+    }
+}
+
+void
 crtc_init(ScrnInfoPtr pScrn)
 {
     modesettingPtr ms = modesettingPTR(pScrn);
@@ -267,7 +285,7 @@ crtc_init(ScrnInfoPtr pScrn)
 	if (crtc == NULL)
 	    goto out;
 
-	crtcp = xalloc(sizeof(struct crtc_private));
+	crtcp = xcalloc(1, sizeof(struct crtc_private));
 	if (!crtcp) {
 	    xf86CrtcDestroy(crtc);
 	    goto out;
@@ -277,11 +295,6 @@ crtc_init(ScrnInfoPtr pScrn)
 
 	crtc->driver_private = crtcp;
     
-        drmBOCreate(ms->fd, 64 * 64 * 4, 0, NULL,
-		DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE 
-		| DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE |
-		DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT,
-		DRM_BO_HINT_DONT_FENCE, &crtcp->cursor_bo);
     }
 
   out:
diff --git a/src/dri2.c b/src/dri2.c
new file mode 100644
index 0000000..eec8069
--- /dev/null
+++ b/src/dri2.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * Author: Alan Hourihane <alanh at tungstengraphics.com>
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include "driver.h"
+
+#include "dri2.h"
+
+extern unsigned int
+driGetPixmapHandle(PixmapPtr pPixmap, unsigned int *flags);
+
+void
+driLock(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+
+    if (!ms->lock_held)
+	DRM_LOCK(ms->fd, ms->lock, ms->context, 0);
+
+    ms->lock_held = 1;
+}
+
+void
+driUnlock(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+
+    if (ms->lock_held)
+	DRM_UNLOCK(ms->fd, ms->lock, ms->context);
+
+    ms->lock_held = 0;
+}
+
+static void
+driBeginClipNotify(ScreenPtr pScreen)
+{
+    driLock(pScreen);
+}
+
+static void
+driEndClipNotify(ScreenPtr pScreen)
+{
+    driUnlock(pScreen);
+}
+
+struct __DRILock {
+    unsigned int block_header;
+    drm_hw_lock_t lock;
+    unsigned int next_id;
+};
+
+#define DRI2_SAREA_BLOCK_HEADER(type, size) (((type) << 16) | (size))
+#define DRI2_SAREA_BLOCK_LOCK		0x0001
+
+void
+driScreenInit(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+    DRI2InfoRec dri2info;
+    const char *driverName;
+    unsigned int sarea_handle;
+    struct __DRILock *DRILock;
+    void *p;
+
+    dri2info.version = 1;
+    dri2info.fd = ms->fd;
+    dri2info.driverSareaSize = sizeof(struct __DRILock);
+    dri2info.driverName = "i915"; /* FIXME */
+    dri2info.getPixmapHandle = driGetPixmapHandle;
+    dri2info.beginClipNotify = driBeginClipNotify;
+    dri2info.endClipNotify   = driEndClipNotify;
+
+    p = DRI2ScreenInit(pScreen, &dri2info);
+    if (!p) 
+	return;
+
+    DRILock = p;
+    DRILock->block_header =
+	DRI2_SAREA_BLOCK_HEADER(DRI2_SAREA_BLOCK_LOCK, sizeof *DRILock);
+    ms->lock = &DRILock->lock;
+    ms->context = 1;
+    DRILock->next_id = 2;
+    driLock(pScreen);
+
+    DRI2Connect(pScreen, &ms->fd, &driverName, &sarea_handle);
+}
+
+void
+driCloseScreen(ScreenPtr pScreen)
+{
+    driUnlock(pScreen);
+    DRI2CloseScreen(pScreen);
+}
diff --git a/src/driver.c b/src/driver.c
index 8f1c905..6bf6388 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -132,6 +132,16 @@ static const OptionInfoRec Options[] = {
     {-1, NULL, OPTV_NONE, {0}, FALSE}
 };
 
+static const char *exaSymbols[] = {
+    "exaGetVersion",
+    "exaDriverInit",
+    "exaDriverFini",
+    "exaOffscreenAlloc",
+    "exaOffscreenFree",
+    "exaWaitSync",
+    NULL
+};
+
 static const char *fbSymbols[] = {
     "fbPictureInit",
     "fbScreenInit",
@@ -190,7 +200,7 @@ Setup(pointer module, pointer opts, int *errmaj, int *errmin)
 	 * Tell the loader about symbols from other modules that this module
 	 * might refer to.
 	 */
-	LoaderRefSymLists(fbSymbols, shadowSymbols, ddcSymbols, NULL);
+	LoaderRefSymLists(exaSymbols, fbSymbols, shadowSymbols, ddcSymbols, NULL);
 
 	/*
 	 * The return value must be non-NULL on success even though there
@@ -417,6 +427,8 @@ MapMem(ScrnInfoPtr pScrn)
     drmBOMap(ms->fd,
 	     &ms->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &ms->virtual);
 
+    ms->virtual = ms->bo.virtual;
+
     return TRUE;
 }
 
@@ -438,7 +450,7 @@ LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
 }
 
 static Bool
-crtc_resize(ScrnInfoPtr pScrn, int width, int height)
+CreateFrontBuffer(ScrnInfoPtr pScrn)
 {
     modesettingPtr ms = modesettingPTR(pScrn);
     ScreenPtr pScreen = pScrn->pScreen;
@@ -446,37 +458,14 @@ crtc_resize(ScrnInfoPtr pScrn, int width, int height)
     Bool fbAccessDisabled;
     CARD8 *fbstart;
 
-    if (width == pScrn->virtualX && height == pScrn->virtualY)
-	return TRUE;
-
-    ErrorF("RESIZING TO %dx%d\n", width, height);
-
-    pScrn->virtualX = width;
-    pScrn->virtualY = height;
-    pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
-
-    if (ms->shadowMem) {
-	xfree(ms->shadowMem);
-	ms->shadowMem = NULL;
-    }
-
-    UnmapMem(pScrn);
-
-    /* move old buffer out of the way */
-    drmBOSetStatus(ms->fd, &ms->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_LOCAL,
-		   DRM_BO_MASK_MEM | DRM_BO_FLAG_NO_EVICT,
-		   DRM_BO_HINT_DONT_FENCE, 0, 0);
-
-    /* unreference it */
-    drmBOUnreference(ms->fd, &ms->bo);
-
     drmBOCreate(ms->fd,
 		pScrn->virtualY * pScrn->displayWidth *
 		pScrn->bitsPerPixel / 8, 0, NULL,
 		DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_SHAREABLE
+		| DRM_BO_FLAG_CACHED_MAPPED
 		| DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE |
-		DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT,
-		DRM_BO_HINT_DONT_FENCE, &ms->bo);
+		/*DRM_BO_FLAG_MEM_VRAM |*/ DRM_BO_FLAG_MEM_TT,
+		0, &ms->bo);
 
     MapMem(pScrn);
 
@@ -498,7 +487,7 @@ crtc_resize(ScrnInfoPtr pScrn, int width, int height)
 	}
 	fbstart = ms->shadowMem;
     } else {
-	fbstart = ms->virtual;
+	fbstart = ms->bo.virtual;
     }
 
     /*
@@ -526,9 +515,49 @@ crtc_resize(ScrnInfoPtr pScrn, int width, int height)
     pScrn->frameY0 = 0;
     AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 
+    UnmapMem(pScrn);
+
+    ms->front = TRUE;
+
     return TRUE;
 }
 
+static Bool
+crtc_resize(ScrnInfoPtr pScrn, int width, int height)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    ScreenPtr pScreen = pScrn->pScreen;
+    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+    Bool fbAccessDisabled;
+    CARD8 *fbstart;
+
+    if (width == pScrn->virtualX && height == pScrn->virtualY)
+	return TRUE;
+
+    ErrorF("RESIZING TO %dx%d\n", width, height);
+
+    pScrn->virtualX = width;
+    pScrn->virtualY = height;
+    pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
+
+    if (ms->shadowMem) {
+	xfree(ms->shadowMem);
+	ms->shadowMem = NULL;
+    }
+
+    drmModeRmFB(ms->fd, ms->fb_id);
+
+    /* move old buffer out of the way */
+    drmBOSetStatus(ms->fd, &ms->bo, 0, 0, 0, 0, 0);
+
+    /* unreference it */
+    drmBOUnreference(ms->fd, &ms->bo);
+    ms->front = FALSE;
+
+    /* now create new frontbuffer */
+    return CreateFrontBuffer(pScrn);
+}
+
 static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
     crtc_resize
 };
@@ -713,6 +742,12 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 
     xf86LoaderReqSymLists(fbSymbols, NULL);
 
+    xf86LoadSubModule(pScrn, "exa");
+
+#ifdef DRI2
+    xf86LoadSubModule(pScrn, "dri2");
+#endif
+
     return TRUE;
 }
 
@@ -744,7 +779,7 @@ WindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode,
 
     *size = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
 
-    return ((CARD8 *) ms->virtual + row * (*size) + offset);
+    return ((CARD8 *) ms->bo.virtual + row * (*size) + offset);
 }
 
 static Bool
@@ -752,15 +787,23 @@ CreateScreenResources(ScreenPtr pScreen)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
+    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
     Bool ret;
 
     pScreen->CreateScreenResources = ms->createScreenResources;
     ret = pScreen->CreateScreenResources(pScreen);
     pScreen->CreateScreenResources = CreateScreenResources;
 
-    shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen),
+    if (ms->shadowFB)
+    	shadowAdd(pScreen, rootPixmap,
 	      ms->update, WindowLinear, 0, 0);
 
+    if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen),
+                                     -1, -1, -1, -1, -1,
+                                     ms->shadowFB ? (pointer)ms->shadowMem : (pointer)ms->bo.virtual))
+	FatalError("Couldn't adjust screen pixmap\n");
+
+
     return ret;
 }
 
@@ -775,6 +818,30 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     MessageType from;
     CARD8 *fbstart;
 
+    /* deal with server regeneration */
+    if (ms->fd < 0) {
+    	char *BusID;
+
+    	BusID = xalloc(64);
+    	sprintf(BusID, "PCI:%d:%d:%d",
+#if XSERVER_LIBPCIACCESS
+	    ((ms->PciInfo->domain << 8) | ms->PciInfo->bus),
+	    ms->PciInfo->dev, ms->PciInfo->func
+#else
+	    ((pciConfigPtr) ms->PciInfo->thisCard)->busnum,
+	    ((pciConfigPtr) ms->PciInfo->thisCard)->devnum,
+	    ((pciConfigPtr) ms->PciInfo->thisCard)->funcnum
+#endif
+	);
+
+    	ms->fd = drmOpen(NULL, BusID);
+
+    	if (ms->fd < 0)
+	    return FALSE;
+    }
+
+    pScrn->pScreen = pScreen;
+
     pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
 
     miClearVisualTypes();
@@ -787,9 +854,6 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     if (!miSetPixmapDepths())
 	return FALSE;
 
-    if (!MapMem(pScrn))
-	return FALSE;
-
     pScrn->memPhysBase = 0;
     pScrn->fbOffset = 0;
 
@@ -797,9 +861,10 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 		pScrn->virtualY * pScrn->displayWidth *
 		pScrn->bitsPerPixel / 8, 0, NULL,
 		DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_SHAREABLE
+		| DRM_BO_FLAG_CACHED_MAPPED
 		| DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE |
-		DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT,
-		DRM_BO_HINT_DONT_FENCE, &ms->bo);
+		/*DRM_BO_FLAG_MEM_VRAM |*/ DRM_BO_FLAG_MEM_TT,
+		0, &ms->bo);
 
     MapMem(pScrn);
 
@@ -821,7 +886,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 	}
 	fbstart = ms->shadowMem;
     } else {
-	fbstart = ms->virtual;
+	fbstart = ms->bo.virtual;
     }
 
     if (!fbScreenInit(pScreen, fbstart,
@@ -853,18 +918,18 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 		       "Shadow framebuffer initialization failed.\n");
 	    return FALSE;
 	}
-
-	ms->createScreenResources = pScreen->CreateScreenResources;
-	pScreen->CreateScreenResources = CreateScreenResources;
     }
 
+    ms->createScreenResources = pScreen->CreateScreenResources;
+    pScreen->CreateScreenResources = CreateScreenResources;
+
     xf86SetBlackWhitePixels(pScreen);
 
 #if 0
     glucoseScreenInit(pScreen, 0);
 #endif
-#if 0
-    ms->pExa = ExaInit(pScreen);
+#if 1
+    ms->pExa = ExaInit(pScrn);
 #endif
 
     miInitializeBackingStore(pScreen);
@@ -872,8 +937,9 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     xf86SetSilkenMouse(pScreen);
     miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
 
-    /* Need to extend HWcursor support in kernel to handle mask interleave ?? */
-    xf86_cursors_init (pScreen, 64, 64,
+    /* Need to extend HWcursor support to handle mask interleave */
+    if (!ms->SWCursor)
+	xf86_cursors_init (pScreen, 64, 64,
 			       HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
 			       HARDWARE_CURSOR_ARGB);
 
@@ -908,6 +974,14 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     if (serverGeneration == 1)
 	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
 
+#ifdef DRI2
+    driScreenInit(pScreen);
+#endif
+
+    UnmapMem(pScrn);
+
+    ms->front = TRUE;
+
     return EnterVT(scrnIndex, 0);
 }
 
@@ -944,6 +1018,8 @@ LeaveVT(int scrnIndex, int flags)
     for (o = 0; o < config->num_crtc; o++) {
 	xf86CrtcPtr crtc = config->crtc[o];
 
+    	cursor_destroy(crtc);
+
 	if (crtc->rotatedPixmap || crtc->rotatedData) {
 	    crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
 					crtc->rotatedData);
@@ -952,11 +1028,25 @@ LeaveVT(int scrnIndex, int flags)
 	}
     }
 
-    xf86_hide_cursors(pScrn);
+    drmModeRmFB(ms->fd, ms->fb_id);
 
-    drmMMLock(ms->fd, DRM_BO_MEM_VRAM, 1, 0);
+    /* move old buffer out of the way */
+    drmBOSetStatus(ms->fd, &ms->bo, 0, 0, 0, 0, 0);
+
+    drmBOUnreference(ms->fd, &ms->bo);
+    ms->front = FALSE;
 
     RestoreHWState(pScrn);
+
+#if 0
+    drmMMLock(ms->fd, DRM_BO_MEM_VRAM, 1, 0);
+    drmMMLock(ms->fd, DRM_BO_MEM_TT, 1, 0);
+#endif
+#ifdef DRI2
+    driLock(pScrn->pScreen);
+#endif
+
+    pScrn->vtSema = FALSE;
 }
 
 /*
@@ -968,6 +1058,17 @@ EnterVT(int scrnIndex, int flags)
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     modesettingPtr ms = modesettingPTR(pScrn);
 
+#if 0
+    if (pScrn->vtSema) {
+	drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1);
+	drmMMUnlock(ms->fd, DRM_BO_MEM_TT, 1);
+    }
+#endif
+
+#ifdef DRI2
+    driUnlock(pScrn->pScreen);
+#endif
+
     /*
      * Only save state once per server generation since that's what most
      * drivers do.  Could change this to save state at each VT enter.
@@ -977,7 +1078,8 @@ EnterVT(int scrnIndex, int flags)
 	SaveHWState(pScrn);
     }
 
-    drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1);
+    if (!ms->front)
+	CreateFrontBuffer(pScrn);
 
     if (!xf86SetDesiredModes(pScrn))
 	return FALSE;
@@ -1001,15 +1103,19 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     modesettingPtr ms = modesettingPTR(pScrn);
 
-    if (pScrn->vtSema == TRUE) {
-	LeaveVT(scrnIndex, 0);
-	drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1);
+    if (pScrn->vtSema) {
+    	LeaveVT(scrnIndex, 0);
+#if 0
+    	drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1);
+    	drmMMUnlock(ms->fd, DRM_BO_MEM_TT, 1);
+#endif
     }
 
-    UnmapMem(pScrn);
+#ifdef DRI2
+    driCloseScreen(pScreen);
+#endif
 
-    if (ms->shadowFB)
-	pScreen->CreateScreenResources = ms->createScreenResources;
+    pScreen->CreateScreenResources = ms->createScreenResources;
 
     if (ms->shadowMem) {
 	xfree(ms->shadowMem);
@@ -1019,14 +1125,8 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
     if (ms->pExa)
 	ExaClose(pScrn);
 
-    /* move old buffer out of the way */
-    drmBOSetStatus(ms->fd, &ms->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_LOCAL,
-		   DRM_BO_MASK_MEM | DRM_BO_FLAG_NO_EVICT,
-		   DRM_BO_HINT_DONT_FENCE, 0, 0);
-
-    drmBOUnreference(ms->fd, &ms->bo);
-
     drmClose(ms->fd);
+    ms->fd = -1;
 
     pScrn->vtSema = FALSE;
     pScreen->CloseScreen = ms->CloseScreen;
diff --git a/src/driver.h b/src/driver.h
index c9cb764..7ac6466 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -31,6 +31,7 @@
 #include <drm.h>
 #include <xf86drm.h>
 #include <xf86drmMode.h>
+#include <xf86mm.h>
 #include "shadow.h"
 #include "exa.h"
 
@@ -50,6 +51,7 @@ typedef struct _modesettingRec
     unsigned int fb_id;
     void *virtual;
     drmBO bo;
+    Bool front;
 
     EntPtr entityPrivate;
 
@@ -68,9 +70,6 @@ typedef struct _modesettingRec
     Bool SWCursor;
     CloseScreenProcPtr CloseScreen;
 
-    Bool directRenderingDisabled;      /* DRI disabled in PreInit. */
-    Bool directRenderingEnabled;       /* DRI enabled this generation. */
-
     /* Broken-out options. */
     OptionInfoPtr Options;
 
@@ -85,6 +84,11 @@ typedef struct _modesettingRec
     /* exa */
     ExaDriverPtr pExa;
     drmBO exa_bo;
+
+    /* dri2 */
+    drm_context_t context;
+    drm_hw_lock_t *lock;
+    int lock_held;
 } modesettingRec, *modesettingPtr;
 
 #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
diff --git a/src/exa.c b/src/exa.c
index 70968f0..9327cbc 100644
--- a/src/exa.c
+++ b/src/exa.c
@@ -36,6 +36,14 @@
 
 #include "driver.h"
 
+struct PixmapPriv {
+    drmBO bo;
+    #if 0
+    dri_fence *fence;
+    #endif
+    int flags;
+};
+
 static void
 ExaWaitMarker(ScreenPtr pScreen, int marker)
 {
@@ -44,10 +52,6 @@ ExaWaitMarker(ScreenPtr pScreen, int marker)
 static int
 ExaMarkSync(ScreenPtr pScreen)
 {
-    /*
-     * See ExaWaitMarker.
-     */
-
     return 1;
 }
 
@@ -56,6 +60,30 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
 {
     ScreenPtr pScreen = pPix->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+    struct PixmapPriv *priv;
+    int ret;
+
+    priv = exaGetPixmapDriverPrivate(pPix);
+
+    if (!priv)
+	return FALSE;
+
+    if (priv->bo.handle) {
+    	void *virtual;
+
+    	ret = drmBOMap(ms->fd,
+	     &priv->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &virtual);
+	if (ret) {
+    	    driUnlock(pScreen);
+	    FatalError("Failed to map pixmap: %s\n", strerror(-ret));
+	    return;
+	}
+
+	pPix->devPrivate.ptr = priv->bo.virtual;
+    }
+
 
     return TRUE;
 }
@@ -65,6 +93,26 @@ ExaFinishAccess(PixmapPtr pPix, int index)
 {
     ScreenPtr pScreen = pPix->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+    struct PixmapPriv *priv;
+    int ret;
+
+    priv = exaGetPixmapDriverPrivate(pPix);
+
+    if (!priv)
+	return;
+
+    if (priv->bo.handle) {
+	ret = drmBOUnmap(ms->fd, &priv->bo);
+	if (ret) {
+	    driUnlock(pScreen);
+	    FatalError("Failed to unmap pixmap: %s\n", strerror(-ret));
+	    return;
+	}
+
+	pPix->devPrivate.ptr = NULL;
+    }
 }
 
 static void
@@ -84,6 +132,8 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
 {
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
 
+    ErrorF("SOLID\n");
+
     if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask))
 	return FALSE;
 
@@ -91,7 +141,7 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
     if (pPixmap->drawable.depth == 4)
 	return FALSE;
 
-    return TRUE;
+    return FALSE;
 }
 
 static void
@@ -106,11 +156,13 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
 {
     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
 
+    ErrorF("COPY\n");
+
     /* can't do depth 4 */
     if (pSrcPixmap->drawable.depth == 4 || pDstPixmap->drawable.depth == 4)
 	return FALSE;
 
-    return TRUE;
+    return FALSE;
 }
 
 static void
@@ -138,6 +190,8 @@ ExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
     ScreenPtr pScreen = pDst->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 
+    ErrorF("UPLOAD\n");
+
     return FALSE;
 }
 
@@ -158,18 +212,118 @@ ExaCheckComposite(int op,
     int w = pDraw->width;
     int h = pDraw->height;
 
-    return TRUE;
+    return FALSE;
 }
 
-static Bool
-ExaPixmapIsOffscreen(PixmapPtr p)
+static void *
+ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
 {
-    ScreenPtr pScreen = p->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+    struct PixmapPriv *priv;
+    void *virtual;
+
+    priv = xcalloc(1, sizeof(struct PixmapPriv));
+    if (!priv)
+        return NULL;
+
+    if (size == 0)
+	return priv;
+
+    drmBOCreate(ms->fd, size, 4096, NULL,
+		DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_SHAREABLE
+		| DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MAPPABLE |
+		DRM_BO_FLAG_CACHED_MAPPED,
+		0, &priv->bo);
+
+    return priv;
+}
+
+static void 
+ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv)
+{
+    struct PixmapPriv *priv = (struct PixmapPriv *)dPriv;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+
+    if (!priv)
+    	return;
+
+    if (priv->bo.handle)
+	drmBOUnreference(ms->fd, &priv->bo);
+
+    xfree(priv);
+}
+
+static Bool 
+ExaPixmapIsOffscreen(PixmapPtr pPixmap)
+{
+    struct PixmapPriv *priv;
+    ScreenPtr pScreen = pPixmap->drawable.pScreen;
+    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+
+    priv = exaGetPixmapDriverPrivate(pPixmap);
+
+    if (!priv)
+       return FALSE;
+
+    if (priv->bo.handle)
+       return TRUE;
 
     return FALSE;
 }
 
+/* FIXME !! */
+unsigned int
+driGetPixmapHandle(PixmapPtr pPixmap, unsigned int *flags)
+{
+    ScreenPtr pScreen = pPixmap->drawable.pScreen;
+    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+    struct PixmapPriv *priv;
+
+    *flags = 0;
+
+    if (rootPixmap == pPixmap)
+        return ms->bo.handle;
+
+    if (!ms->pExa)
+    	return 0;
+
+    priv = exaGetPixmapDriverPrivate(pPixmap);
+
+    if (!priv)
+       return 0;
+
+    if (priv->bo.handle)
+        return priv->bo.handle;
+
+    return 0;
+}
+
+static Bool 
+ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
+		      int depth, int bitsPerPixel, int devKind,
+		      pointer pPixData)
+{
+    ScreenPtr	pScreen = pPixmap->drawable.pScreen;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
+    modesettingPtr ms = modesettingPTR(pScrn);
+    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+
+    if (rootPixmap == pPixmap) {
+	miModifyPixmapHeader(pPixmap, width, height, depth,
+			     bitsPerPixel, devKind, NULL);
+
+	return TRUE;
+    }
+
+    return FALSE;
+}
+
+
 void
 ExaClose(ScrnInfoPtr pScrn)
 {
@@ -177,7 +331,9 @@ ExaClose(ScrnInfoPtr pScrn)
 
     exaDriverFini(pScrn->pScreen);
 
+#if 0
     drmBOUnreference(ms->fd, &ms->exa_bo);
+#endif
 }
 
 ExaDriverPtr
@@ -191,20 +347,22 @@ ExaInit(ScrnInfoPtr pScrn)
 	goto out_err;
     }
 
+#if 0
     /* Create a 256KB offscreen area */
     drmBOCreate(ms->fd, 256 * 1024, 0, NULL,
 		DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_TT,
 		DRM_BO_HINT_DONT_FENCE, &ms->exa_bo);
+#endif
 
     memset(pExa, 0, sizeof(*pExa));
     pExa->exa_major = 2;
-    pExa->exa_minor = 2;
-    pExa->memoryBase = ms->exa_bo.virtual;
+    pExa->exa_minor = 4;
+    pExa->memoryBase = 0; /* ms->exa_bo.virtual; */
+    pExa->memorySize = 0; /* ms->exa_bo.size; */
     pExa->offScreenBase = 0;
-    pExa->memorySize = ms->exa_bo.size;
     pExa->pixmapOffsetAlign = 8;
     pExa->pixmapPitchAlign = 32 * 4;
-    pExa->flags = EXA_OFFSCREEN_PIXMAPS;
+    pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
     pExa->maxX = 8191;		       /* FIXME */
     pExa->maxY = 8191;		       /* FIXME */
     pExa->WaitMarker = ExaWaitMarker;
@@ -223,6 +381,9 @@ ExaInit(ScrnInfoPtr pScrn)
     pExa->PrepareAccess = ExaPrepareAccess;
     pExa->FinishAccess = ExaFinishAccess;
     pExa->UploadToScreen = ExaUploadToScreen;
+    pExa->CreatePixmap = ExaCreatePixmap;
+    pExa->DestroyPixmap = ExaDestroyPixmap;
+    pExa->ModifyPixmapHeader = ExaModifyPixmapHeader;
 
     if (!exaDriverInit(pScrn->pScreen, pExa)) {
 	goto out_err;
diff --git a/src/output.c b/src/output.c
index 7767ef2..484acb2 100644
--- a/src/output.c
+++ b/src/output.c
@@ -51,6 +51,23 @@
 
 #include "driver.h"
 
+static char *connector_enum_list[] = {
+    "Unknown",
+    "VGA",
+    "DVI-I",
+    "DVI-D",
+    "DVI-A",
+    "Composite",
+    "SVIDEO",
+    "LVDS",
+    "Component",
+    "9-pin DIN",
+    "DisplayPort",
+    "HDMI Type A",
+    "HDMI Type B",
+};
+
+
 static void
 dpms(xf86OutputPtr output, int mode)
 {
@@ -145,6 +162,7 @@ get_modes(xf86OutputPtr output)
 	    mode->VRefresh = xf86ModeVRefresh(mode);
 	    mode->Private = (void *)drm_mode;
 	    xf86SetModeDefaultName(mode);
+	    ErrorF("MODE %s\n",mode->name);
 	    modes = xf86ModesAdd(modes, mode);
 	    xf86PrintModeline(0, mode);
 	}
@@ -237,7 +255,6 @@ output_init(ScrnInfoPtr pScrn)
 	if (!drm_connector)
 	    goto out;
 
-#if 0
 	for (p = 0; p < drm_connector->count_props; p++) {
 	    drmModePropertyPtr prop;
 
@@ -249,41 +266,16 @@ output_init(ScrnInfoPtr pScrn)
 
 		for (v = 0; v < prop->count_values; v++)
 		    ErrorF("%s %lld\n", prop->name, prop->values[v]);
-
-		for (v = 0; v < prop->count_enums; v++) {
-		    ErrorF("%s %s\n", prop->name, prop->enums[v].name);
-		    if (drm_connector->prop_values[p] == prop->enums[v].value) {
-			if (!strncmp("Connector Type", prop->name, 14)) {
-			    ErrorF("WE'VE GOT %s\n", prop->enums[v].name);
-			    name = xalloc(strlen(prop->enums[v].name));
-			    strncpy(name, prop->enums[v].name, strlen(name));
-			}
-		    }
-		    if (name)
-			break;
-		}
-		if (name)
-		    break;
 	    }
 	}
 
-	if (!name)
-	    continue;
-#endif
-
-
-#if 0
-	free(name);
-#endif
-
-	
-	name = "Unknown";
+	name = connector_enum_list[drm_connector->connector_type];
 
 	output = xf86OutputCreate(pScrn, &output_funcs, name);
 	if (!output)
 	    continue;
 
-	drm_encoder = drmModeGetEncoder(ms->fd, drm_connector->encoder);
+	drm_encoder = drmModeGetEncoder(ms->fd, drm_connector->encoders[0]);
 	if (drm_encoder) {
 	output->possible_crtcs = drm_encoder->crtcs;
 	output->possible_clones = drm_encoder->clones;


More information about the xorg-commit mailing list