Commit 53b66c08 authored by Dave Airlie's avatar Dave Airlie

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's avatarKeith Packard <keithp@keithp.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 726d467b
......@@ -465,4 +465,7 @@ extern _X_EXPORT ScreenPtr xf86ScrnToScreen(ScrnInfoPtr pScrn);
#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 */
......@@ -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 (xf86NumScreens == 0) {
xf86Msg(X_ERROR,
......
......@@ -51,6 +51,7 @@ DevPrivateKeyRec xf86CreateRootWindowKeyRec;
DevPrivateKeyRec xf86ScreenKeyRec;
ScrnInfoPtr *xf86Screens = NULL; /* List of ScrnInfos */
ScrnInfoPtr *xf86GPUScreens = NULL; /* List of ScrnInfos */
const unsigned char byte_reversed[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
......@@ -153,6 +154,7 @@ int xf86NumDrivers = 0;
InputDriverPtr *xf86InputDriverList = NULL;
int xf86NumInputDrivers = 0;
int xf86NumScreens = 0;
int xf86NumGPUScreens = 0;
const char *xf86VisualNames[] = {
"StaticGray",
......
......@@ -169,15 +169,28 @@ xf86AllocateScreen(DriverPtr drv, int flags)
int i;
ScrnInfoPtr pScrn;
if (xf86Screens == NULL)
xf86NumScreens = 0;
i = xf86NumScreens++;
xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
pScrn = xf86Screens[i];
pScrn->scrnIndex = i; /* Changes when a screen is removed */
pScrn->origIndex = i; /* This never changes */
if (flags & XF86_ALLOCATE_GPU_SCREEN) {
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++;
xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
pScrn = xf86Screens[i];
pScrn->scrnIndex = i; /* Changes when a screen is removed */
}
pScrn->origIndex = pScrn->scrnIndex; /* This never changes */
pScrn->privates = xnfcalloc(sizeof(DevUnion), xf86ScrnInfoPrivateCount);
/*
* EnableDisableFBAccess now gets initialized in InitOutput()
......@@ -203,10 +216,17 @@ xf86DeleteScreen(ScrnInfoPtr pScrn)
{
int i;
int scrnIndex;
/* First check if the screen is valid */
if (xf86NumScreens == 0 || xf86Screens == NULL)
return;
Bool is_gpu = FALSE;
if (pScrn->is_gpu) {
/* First check if the screen is valid */
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)
return;
......@@ -238,12 +258,23 @@ xf86DeleteScreen(ScrnInfoPtr pScrn)
/* 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++) {
xf86Screens[i] = xf86Screens[i + 1];
xf86Screens[i]->scrnIndex = i;
/* Also need to take care of the screen layout settings */
for (i = scrnIndex; i < xf86NumScreens; i++) {
xf86Screens[i] = xf86Screens[i + 1];
xf86Screens[i]->scrnIndex = i;
/* Also need to take care of the screen layout settings */
}
}
}
......@@ -267,6 +298,14 @@ xf86AllocateScrnInfoPrivateIndex(void)
memset(&nprivs[idx], 0, sizeof(DevUnion));
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;
}
......@@ -1059,6 +1098,11 @@ xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
xf86Screens[scrnIndex]->name)
LogHdrMessageVerb(type, verb, format, args, "%s(%d): ",
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
LogVMessageVerb(type, verb, format, args);
}
......@@ -1834,13 +1878,23 @@ xf86MotionHistoryAllocate(InputInfoPtr pInfo)
ScrnInfoPtr
xf86ScreenToScrn(ScreenPtr pScreen)
{
assert(pScreen->myNum < xf86NumScreens);
return xf86Screens[pScreen->myNum];
if (pScreen->isGPU) {
assert(pScreen->myNum - GPU_SCREEN_OFFSET < xf86NumGPUScreens);
return xf86GPUScreens[pScreen->myNum - GPU_SCREEN_OFFSET];
} else {
assert(pScreen->myNum < xf86NumScreens);
return xf86Screens[pScreen->myNum];
}
}
ScreenPtr
xf86ScrnToScreen(ScrnInfoPtr pScrn)
{
assert(pScrn->scrnIndex < screenInfo.numScreens);
return screenInfo.screens[pScrn->scrnIndex];
if (pScrn->is_gpu) {
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];
}
}
......@@ -593,6 +593,18 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
if (!xf86Screens[i]->configured)
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.
*/
......@@ -818,6 +830,36 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
!dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0))
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++) {
xf86VGAarbiterLock(xf86Screens[i]);
/*
......
......@@ -95,6 +95,8 @@ extern _X_EXPORT Bool xorgHWAccess;
extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable;
extern ScrnInfoPtr *xf86GPUScreens; /* List of pointers to ScrnInfoRecs */
extern int xf86NumGPUScreens;
#ifndef DEFAULT_VERBOSE
#define DEFAULT_VERBOSE 0
#endif
......
......@@ -332,9 +332,9 @@ typedef struct _DriverRec {
/*
* 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
*/
......@@ -813,6 +813,7 @@ typedef struct _ScrnInfoRec {
*/
funcPointer reservedFuncs[NUM_RESERVED_FUNCS];
Bool is_gpu;
} ScrnInfoRec;
typedef struct {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment