summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@tungstengraphics.com>2008-06-16 15:07:39 +0100
committerAlan Hourihane <alanh@tungstengraphics.com>2008-06-16 15:08:30 +0100
commit3390583c92f2dfb1d525bb55d25edf6ce8b753ae (patch)
treea0858dece48ebc3fbb2066cb40cf8d9e3ad8a88c
parentec2814a34db917f9bf3749476461135fa1a83227 (diff)
Add DRI2 support.
Add EXA stubs. Currently tested with i915.
-rw-r--r--src/Makefile.am3
-rw-r--r--src/crtc.c47
-rw-r--r--src/dri2.c127
-rw-r--r--src/driver.c220
-rw-r--r--src/driver.h10
-rw-r--r--src/exa.c189
-rw-r--r--src/output.c48
7 files changed, 521 insertions, 123 deletions
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@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;