xfree86: add DDX gpu screen support. (v3)

This just adds the structures and interfaces required for adding/deleteing
gpu screens at the DDX level. The platform probe can pass a new flag
to the driver, so they can call xf86AllocateScreen and pass back the new
gpu screen flag.

It also calls the gpu screens preinit and screeninit routines at
startup.

v2: fix delete screen use after free.

v3: split out pScrn into separate patch

Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Dave Airlie 2012-06-05 17:18:10 +01:00
parent 726d467b53
commit 53b66c084f
7 changed files with 131 additions and 23 deletions

View File

@ -465,4 +465,7 @@ extern _X_EXPORT ScreenPtr xf86ScrnToScreen(ScrnInfoPtr pScrn);
#define XF86_SCRN_INTERFACE 1 /* define for drivers to use in api compat */ #define XF86_SCRN_INTERFACE 1 /* define for drivers to use in api compat */
/* flags passed to xf86 allocate screen */
#define XF86_ALLOCATE_GPU_SCREEN 1
#endif /* _XF86_H */ #endif /* _XF86_H */

View File

@ -189,6 +189,10 @@ xf86BusConfig(void)
} }
} }
/* bind GPU conf screen to protocol screen 0 */
for (i = 0; i < xf86NumGPUScreens; i++)
xf86GPUScreens[i]->confScreen = xf86Screens[0]->confScreen;
/* If no screens left, return now. */ /* If no screens left, return now. */
if (xf86NumScreens == 0) { if (xf86NumScreens == 0) {
xf86Msg(X_ERROR, xf86Msg(X_ERROR,

View File

@ -51,6 +51,7 @@ DevPrivateKeyRec xf86CreateRootWindowKeyRec;
DevPrivateKeyRec xf86ScreenKeyRec; DevPrivateKeyRec xf86ScreenKeyRec;
ScrnInfoPtr *xf86Screens = NULL; /* List of ScrnInfos */ ScrnInfoPtr *xf86Screens = NULL; /* List of ScrnInfos */
ScrnInfoPtr *xf86GPUScreens = NULL; /* List of ScrnInfos */
const unsigned char byte_reversed[256] = { const unsigned char byte_reversed[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
@ -153,6 +154,7 @@ int xf86NumDrivers = 0;
InputDriverPtr *xf86InputDriverList = NULL; InputDriverPtr *xf86InputDriverList = NULL;
int xf86NumInputDrivers = 0; int xf86NumInputDrivers = 0;
int xf86NumScreens = 0; int xf86NumScreens = 0;
int xf86NumGPUScreens = 0;
const char *xf86VisualNames[] = { const char *xf86VisualNames[] = {
"StaticGray", "StaticGray",

View File

@ -169,15 +169,28 @@ xf86AllocateScreen(DriverPtr drv, int flags)
int i; int i;
ScrnInfoPtr pScrn; ScrnInfoPtr pScrn;
if (xf86Screens == NULL) if (flags & XF86_ALLOCATE_GPU_SCREEN) {
xf86NumScreens = 0; if (xf86GPUScreens == NULL)
xf86NumGPUScreens = 0;
i = xf86NumGPUScreens++;
xf86GPUScreens = xnfrealloc(xf86GPUScreens, xf86NumGPUScreens * sizeof(ScrnInfoPtr));
xf86GPUScreens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
pScrn = xf86GPUScreens[i];
pScrn->scrnIndex = i + GPU_SCREEN_OFFSET; /* Changes when a screen is removed */
pScrn->is_gpu = TRUE;
} else {
if (xf86Screens == NULL)
xf86NumScreens = 0;
i = xf86NumScreens++; i = xf86NumScreens++;
xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr)); xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1); xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
pScrn = xf86Screens[i]; pScrn = xf86Screens[i];
pScrn->scrnIndex = i; /* Changes when a screen is removed */
pScrn->origIndex = i; /* This never changes */ pScrn->scrnIndex = i; /* Changes when a screen is removed */
}
pScrn->origIndex = pScrn->scrnIndex; /* This never changes */
pScrn->privates = xnfcalloc(sizeof(DevUnion), xf86ScrnInfoPrivateCount); pScrn->privates = xnfcalloc(sizeof(DevUnion), xf86ScrnInfoPrivateCount);
/* /*
* EnableDisableFBAccess now gets initialized in InitOutput() * EnableDisableFBAccess now gets initialized in InitOutput()
@ -203,10 +216,17 @@ xf86DeleteScreen(ScrnInfoPtr pScrn)
{ {
int i; int i;
int scrnIndex; int scrnIndex;
Bool is_gpu = FALSE;
/* First check if the screen is valid */ if (pScrn->is_gpu) {
if (xf86NumScreens == 0 || xf86Screens == NULL) /* First check if the screen is valid */
return; if (xf86NumGPUScreens == 0 || xf86GPUScreens == NULL)
return;
is_gpu = TRUE;
} else {
/* First check if the screen is valid */
if (xf86NumScreens == 0 || xf86Screens == NULL)
return;
}
if (!pScrn) if (!pScrn)
return; return;
@ -238,12 +258,23 @@ xf86DeleteScreen(ScrnInfoPtr pScrn)
/* Move the other entries down, updating their scrnIndex fields */ /* Move the other entries down, updating their scrnIndex fields */
xf86NumScreens--; if (is_gpu) {
xf86NumGPUScreens--;
scrnIndex -= GPU_SCREEN_OFFSET;
for (i = scrnIndex; i < xf86NumGPUScreens; i++) {
xf86GPUScreens[i] = xf86GPUScreens[i + 1];
xf86GPUScreens[i]->scrnIndex = i + GPU_SCREEN_OFFSET;
/* Also need to take care of the screen layout settings */
}
}
else {
xf86NumScreens--;
for (i = scrnIndex; i < xf86NumScreens; i++) { for (i = scrnIndex; i < xf86NumScreens; i++) {
xf86Screens[i] = xf86Screens[i + 1]; xf86Screens[i] = xf86Screens[i + 1];
xf86Screens[i]->scrnIndex = i; xf86Screens[i]->scrnIndex = i;
/* Also need to take care of the screen layout settings */ /* Also need to take care of the screen layout settings */
}
} }
} }
@ -267,6 +298,14 @@ xf86AllocateScrnInfoPrivateIndex(void)
memset(&nprivs[idx], 0, sizeof(DevUnion)); memset(&nprivs[idx], 0, sizeof(DevUnion));
pScr->privates = nprivs; pScr->privates = nprivs;
} }
for (i = 0; i < xf86NumGPUScreens; i++) {
pScr = xf86GPUScreens[i];
nprivs = xnfrealloc(pScr->privates,
xf86ScrnInfoPrivateCount * sizeof(DevUnion));
/* Zero the new private */
memset(&nprivs[idx], 0, sizeof(DevUnion));
pScr->privates = nprivs;
}
return idx; return idx;
} }
@ -1059,6 +1098,11 @@ xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
xf86Screens[scrnIndex]->name) xf86Screens[scrnIndex]->name)
LogHdrMessageVerb(type, verb, format, args, "%s(%d): ", LogHdrMessageVerb(type, verb, format, args, "%s(%d): ",
xf86Screens[scrnIndex]->name, scrnIndex); xf86Screens[scrnIndex]->name, scrnIndex);
else if (scrnIndex >= GPU_SCREEN_OFFSET &&
scrnIndex < GPU_SCREEN_OFFSET + xf86NumGPUScreens &&
xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name)
LogHdrMessageVerb(type, verb, format, args, "%s(G%d): ",
xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name, scrnIndex - GPU_SCREEN_OFFSET);
else else
LogVMessageVerb(type, verb, format, args); LogVMessageVerb(type, verb, format, args);
} }
@ -1834,13 +1878,23 @@ xf86MotionHistoryAllocate(InputInfoPtr pInfo)
ScrnInfoPtr ScrnInfoPtr
xf86ScreenToScrn(ScreenPtr pScreen) xf86ScreenToScrn(ScreenPtr pScreen)
{ {
assert(pScreen->myNum < xf86NumScreens); if (pScreen->isGPU) {
return xf86Screens[pScreen->myNum]; assert(pScreen->myNum - GPU_SCREEN_OFFSET < xf86NumGPUScreens);
return xf86GPUScreens[pScreen->myNum - GPU_SCREEN_OFFSET];
} else {
assert(pScreen->myNum < xf86NumScreens);
return xf86Screens[pScreen->myNum];
}
} }
ScreenPtr ScreenPtr
xf86ScrnToScreen(ScrnInfoPtr pScrn) xf86ScrnToScreen(ScrnInfoPtr pScrn)
{ {
assert(pScrn->scrnIndex < screenInfo.numScreens); if (pScrn->is_gpu) {
return screenInfo.screens[pScrn->scrnIndex]; assert(pScrn->scrnIndex - GPU_SCREEN_OFFSET < screenInfo.numGPUScreens);
return screenInfo.gpuscreens[pScrn->scrnIndex - GPU_SCREEN_OFFSET];
} else {
assert(pScrn->scrnIndex < screenInfo.numScreens);
return screenInfo.screens[pScrn->scrnIndex];
}
} }

View File

@ -593,6 +593,18 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
if (!xf86Screens[i]->configured) if (!xf86Screens[i]->configured)
xf86DeleteScreen(xf86Screens[i--]); xf86DeleteScreen(xf86Screens[i--]);
for (i = 0; i < xf86NumGPUScreens; i++) {
xf86VGAarbiterScrnInit(xf86GPUScreens[i]);
xf86VGAarbiterLock(xf86GPUScreens[i]);
if (xf86GPUScreens[i]->PreInit &&
xf86GPUScreens[i]->PreInit(xf86GPUScreens[i], 0))
xf86GPUScreens[i]->configured = TRUE;
xf86VGAarbiterUnlock(xf86GPUScreens[i]);
}
for (i = 0; i < xf86NumGPUScreens; i++)
if (!xf86GPUScreens[i]->configured)
xf86DeleteScreen(xf86GPUScreens[i--]);
/* /*
* If no screens left, return now. * If no screens left, return now.
*/ */
@ -818,6 +830,36 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
!dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0)) !dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0))
FatalError("Cannot register DDX private keys"); FatalError("Cannot register DDX private keys");
for (i = 0; i < xf86NumGPUScreens; i++) {
ScrnInfoPtr pScrn = xf86GPUScreens[i];
xf86VGAarbiterLock(pScrn);
/*
* Almost everything uses these defaults, and many of those that
* don't, will wrap them.
*/
pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess;
#ifdef XFreeXDGA
pScrn->SetDGAMode = xf86SetDGAMode;
#endif
pScrn->DPMSSet = NULL;
pScrn->LoadPalette = NULL;
pScrn->SetOverscan = NULL;
pScrn->DriverFunc = NULL;
pScrn->pScreen = NULL;
scr_index = AddGPUScreen(pScrn->ScreenInit, argc, argv);
xf86VGAarbiterUnlock(pScrn);
if (scr_index == i) {
dixSetPrivate(&screenInfo.gpuscreens[scr_index]->devPrivates,
xf86ScreenKey, xf86GPUScreens[i]);
pScrn->pScreen = screenInfo.gpuscreens[scr_index];
/* The driver should set this, but make sure it is set anyway */
pScrn->vtSema = TRUE;
} else {
FatalError("AddScreen/ScreenInit failed for gpu driver %d %d\n", i, scr_index);
}
}
for (i = 0; i < xf86NumScreens; i++) { for (i = 0; i < xf86NumScreens; i++) {
xf86VGAarbiterLock(xf86Screens[i]); xf86VGAarbiterLock(xf86Screens[i]);
/* /*

View File

@ -95,6 +95,8 @@ extern _X_EXPORT Bool xorgHWAccess;
extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable; extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable;
extern ScrnInfoPtr *xf86GPUScreens; /* List of pointers to ScrnInfoRecs */
extern int xf86NumGPUScreens;
#ifndef DEFAULT_VERBOSE #ifndef DEFAULT_VERBOSE
#define DEFAULT_VERBOSE 0 #define DEFAULT_VERBOSE 0
#endif #endif

View File

@ -332,9 +332,9 @@ typedef struct _DriverRec {
/* /*
* platform probe flags * platform probe flags
* no flags are defined yet - but drivers should fail to load if a flag they
* don't understand is passed.
*/ */
#define PLATFORM_PROBE_GPU_SCREEN 1
/* /*
* AddDriver flags * AddDriver flags
*/ */
@ -813,6 +813,7 @@ typedef struct _ScrnInfoRec {
*/ */
funcPointer reservedFuncs[NUM_RESERVED_FUNCS]; funcPointer reservedFuncs[NUM_RESERVED_FUNCS];
Bool is_gpu;
} ScrnInfoRec; } ScrnInfoRec;
typedef struct { typedef struct {