summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-06-05 17:18:10 +0100
committerDave Airlie <airlied@redhat.com>2012-07-06 10:35:19 +0100
commit53b66c084fbf5bf47f8121632fabdc39b9fe8337 (patch)
treeb90f91637a992d5a72664a915b35ea062b0a8787
parent726d467b534a30d8cbaafb858339c638c9f83195 (diff)
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>
-rw-r--r--hw/xfree86/common/xf86.h3
-rw-r--r--hw/xfree86/common/xf86Bus.c4
-rw-r--r--hw/xfree86/common/xf86Globals.c2
-rw-r--r--hw/xfree86/common/xf86Helper.c98
-rw-r--r--hw/xfree86/common/xf86Init.c42
-rw-r--r--hw/xfree86/common/xf86Priv.h2
-rw-r--r--hw/xfree86/common/xf86str.h5
7 files changed, 132 insertions, 24 deletions
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;
-
- 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];
+ }
}
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 {