[RFC PATCH] xfree86: add a -gpu switch to select primary gpu

Maarten Lankhorst maarten.lankhorst at canonical.com
Mon Jun 10 07:00:01 PDT 2013


For obvious reasons probably not suitable to be upstreamed, but I'm looking for some feedback on this patch.
This allows some playing around with optimus, if you feel so inclined.

Xorg -gpu 0 would use the boot vga, Xorg -gpu 1 the first pci device that's not.
I was also considering adding support for platform names or device names, but that's not implemented here yet.

I don't believe it's suitable for inclusion in this form, but if you're toying with optimus it will save you some headaches.

Thoughts?

---
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 91ec4c8..b9a1065 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -95,6 +95,9 @@ void (*xf86OSPMClose) (void) = NULL;
 #endif
 static Bool xorgHWOpenConsole = FALSE;
 
+int xf86gpu_idx = -1;
+const char *xf86gpu_name = NULL;
+
 /* Common pixmap formats */
 
 static PixmapFormatRec formats[MAXFORMATS] = {
@@ -1399,6 +1402,23 @@ ddxProcessArgument(int argc, char **argv, int i)
         xf86PointerName = argv[++i];
         return 2;
     }
+    if (!strcmp(argv[i], "-gpu")) {
+        char *ptr;
+        long idx;
+        CHECK_FOR_REQUIRED_ARGUMENT();
+
+        idx = strtol(argv[++i], &ptr, 10);
+
+        if (idx >= 0 && *argv[i] && !ptr[0]) {
+            xf86gpu_idx = idx;
+            xf86gpu_name = NULL;
+        } else if (strchr(argv[i], ':')) {
+            xf86gpu_idx = -1;
+            xf86gpu_name = argv[i];
+        } else
+            FatalError("Invalid argument passed for -gpu.\n");
+        return 2;
+    }
     if (!strcmp(argv[i], "-keyboard")) {
         CHECK_FOR_REQUIRED_ARGUMENT();
         xf86KeyboardName = argv[++i];
@@ -1507,6 +1527,7 @@ ddxUseMsg(void)
         ("-keyboard name         specify the core keyboard InputDevice name\n");
     ErrorF
         ("-pointer name          specify the core pointer InputDevice name\n");
+    ErrorF("-gpu <index|name>      select the primary gpu\n");
     ErrorF("-nosilk                disable Silken Mouse\n");
     ErrorF("-flipPixels            swap default black/white Pixel values\n");
 #ifdef XF86VIDMODE
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
index 58cfe0a..a639fbd 100644
--- a/hw/xfree86/common/xf86Priv.h
+++ b/hw/xfree86/common/xf86Priv.h
@@ -96,6 +96,11 @@ extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable;
 
 extern ScrnInfoPtr *xf86GPUScreens;      /* List of pointers to ScrnInfoRecs */
 extern int xf86NumGPUScreens;
+
+extern int xf86gpu_idx;
+extern const char *xf86gpu_name;
+
+
 #ifndef DEFAULT_VERBOSE
 #define DEFAULT_VERBOSE		0
 #endif
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index e368dee..5047269 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -355,7 +355,40 @@ xf86platformProbeDev(DriverPtr drvp)
     Bool foundScreen = FALSE;
     GDevPtr *devList;
     const unsigned numDevs = xf86MatchDevice(drvp->driverName, &devList);
-    int i, j;
+    int i, j, primary_idx = 0, gpu_idx = -1;
+
+    for (i = 0; i < xf86_num_platform_devices; ++i) {
+        if (xf86_platform_devices[j].pdev && xf86IsPrimaryPlatform(&xf86_platform_devices[i])) {
+            primary_idx = i;
+            break;
+        }
+    }
+
+    if (xf86gpu_idx >= 0) {
+        /*
+         * When xf86gpu_idx is set the primary device will come first.
+         * The rest will be reordered, this way -gpu 0 will always map
+         * to the default.
+         */
+        if (xf86gpu_idx == 0)
+            gpu_idx = primary_idx;
+        else if (xf86gpu_idx <= primary_idx)
+            gpu_idx = xf86gpu_idx - 1;
+        else
+            gpu_idx = xf86gpu_idx;
+
+        for (i = 0; i < numDevs; ++i) {
+            if (devList[i]->busID && *devList[i]->busID) {
+                if (xf86PlatformDeviceCheckBusID(&xf86_platform_devices[gpu_idx], devList[i]->busID))
+                    break;
+            }
+        }
+
+        if (i == numDevs)
+            i = 0;
+
+        foundScreen = probeSingleDevice(&xf86_platform_devices[gpu_idx], drvp, devList[i], 0);
+    }
 
     /* find the main device or any device specificed in xorg.conf */
     for (i = 0; i < numDevs; i++) {
@@ -369,13 +402,13 @@ xf86platformProbeDev(DriverPtr drvp)
                 if (ServerIsNotSeat0())
                     break;
                 if (xf86_platform_devices[j].pdev) {
-                    if (xf86IsPrimaryPlatform(&xf86_platform_devices[j]))
+                    if (xf86gpu_idx < 0 && j == primary_idx)
                         break;
                 }
             }
         }
 
-        if (j == xf86_num_platform_devices)
+        if (j == xf86_num_platform_devices || j == gpu_idx)
              continue;
 
         foundScreen = probeSingleDevice(&xf86_platform_devices[j], drvp, devList[i], 0);



More information about the xorg-devel mailing list