diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h index 88a219c7f..61169857f 100644 --- a/hw/xfree86/common/xf86.h +++ b/hw/xfree86/common/xf86.h @@ -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 */ diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c index d0cfb2b3e..6de8409fc 100644 --- a/hw/xfree86/common/xf86Bus.c +++ b/hw/xfree86/common/xf86Bus.c @@ -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, diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c index 0071004eb..bb089175d 100644 --- a/hw/xfree86/common/xf86Globals.c +++ b/hw/xfree86/common/xf86Globals.c @@ -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", diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c index 18f30b7c4..f681a8577 100644 --- a/hw/xfree86/common/xf86Helper.c +++ b/hw/xfree86/common/xf86Helper.c @@ -169,15 +169,28 @@ xf86AllocateScreen(DriverPtr drv, int flags) int i; ScrnInfoPtr pScrn; - if (xf86Screens == NULL) - xf86NumScreens = 0; + 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 = i; /* This never changes */ + 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]; + } } diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 1f5a382b7..aa17a58fd 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -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]); /* diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index 42a3b30f0..c9f2e7eb8 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -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 diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h index e12dcc4ce..6bd6a6218 100644 --- a/hw/xfree86/common/xf86str.h +++ b/hw/xfree86/common/xf86str.h @@ -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 {