Add DRI2 support.

Add EXA stubs.

Currently tested with i915.
This commit is contained in:
Alan Hourihane 2008-06-16 15:07:39 +01:00
parent 6a1910a0e5
commit 47969d7928
7 changed files with 521 additions and 123 deletions

View File

@ -37,6 +37,7 @@ modesetting_drv_la_SOURCES = \
driver.h \
output.c \
crtc.c \
exa.c
exa.c \
dri2.c
EXTRA_DIST =

View File

@ -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);
memcpy (ptr, image, 64 * 64 * 4);
drmBOMap(ms->fd, &crtcp->cursor_bo, DRM_BO_FLAG_WRITE, DRM_BO_HINT_DONT_FENCE, (void **)&ptr);
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,15 +239,27 @@ 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)
{
@ -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:

View File

@ -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);
}

View File

@ -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;

View File

@ -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))

View File

@ -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;

View File

@ -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;