From c79f3765944e059bb2aef2b2b1b6a1fa69faa2c1 Mon Sep 17 00:00:00 2001 From: Oleh Nykyforchyn Date: Sat, 27 Dec 2025 23:01:28 +0200 Subject: [PATCH] xfree86/common: introduce SingleDriver server flag It is patch 1/3 of a series that makes adding GPU screens more controllable. If SingleDriver option is set to "on", then only the first successfully probed driver adds non-GPU screens, others may add secondary GPU screens only. Fixes github.com/X11Libre/xserver/issues/1669 Signed-off-by: Oleh Nykyforchyn --- hw/xfree86/common/xf86Bus.c | 13 ++++++++++--- hw/xfree86/common/xf86Bus.h | 2 +- hw/xfree86/common/xf86Config.c | 14 ++++++++++++++ hw/xfree86/common/xf86Globals.c | 1 + hw/xfree86/common/xf86Init.c | 2 +- hw/xfree86/common/xf86Privstr.h | 3 +++ 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c index 1389432984..0d19a4b570 100644 --- a/hw/xfree86/common/xf86Bus.c +++ b/hw/xfree86/common/xf86Bus.c @@ -144,9 +144,12 @@ xf86BusConfigMatch(ScrnInfoPtr scrnInfo, Bool is_gpu) { /** * @return TRUE if all buses are configured and set up correctly and FALSE * otherwise. + * + * If singleDriver is TRUE, then only the first successfully probed driver adds screens to xf86Screens, + * others may add GPU secondary screens only */ Bool -xf86BusConfig(void) +xf86BusConfig(Bool singleDriver) { screenLayoutPtr layout; int i; @@ -160,7 +163,9 @@ xf86BusConfig(void) * xf86Screens[] list for each instance of the hardware found. */ for (i = 0; i < xf86NumDrivers; i++) { - xf86CallDriverProbe(xf86DriverList[i], FALSE); + /* The order of the && operands below is essential! */ + if (xf86CallDriverProbe(xf86DriverList[i], FALSE) && singleDriver) + break; } /* @@ -171,7 +176,9 @@ xf86BusConfig(void) if (xf86NumScreens == 0) { xf86ProbeIgnorePrimary = TRUE; for (i = 0; i < xf86NumDrivers && xf86NumScreens == 0; i++) { - xf86CallDriverProbe(xf86DriverList[i], FALSE); + /* The order of the && operands below is essential! */ + if (xf86CallDriverProbe(xf86DriverList[i], FALSE) && singleDriver) + break; } xf86ProbeIgnorePrimary = FALSE; } diff --git a/hw/xfree86/common/xf86Bus.h b/hw/xfree86/common/xf86Bus.h index 933bef492b..6bec9fa7d9 100644 --- a/hw/xfree86/common/xf86Bus.h +++ b/hw/xfree86/common/xf86Bus.h @@ -77,7 +77,7 @@ Bool xf86IsEntityPrimary(int entityIndex); _X_EXPORT /* only for internal int10 module - not supposed to be used by OOT drivers */ ScrnInfoPtr xf86FindScreenForEntity(int entityIndex); -Bool xf86BusConfig(void); +Bool xf86BusConfig(Bool singleDriver); void xf86ClearEntityListForScreen(ScrnInfoPtr pScrn); void xf86RemoveDevFromEntity(int entityIndex, GDevPtr dev); diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 0a2e3a7454..8dce643fbb 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -657,6 +657,7 @@ typedef enum { FLAG_IGLX, FLAG_DEBUG, FLAG_ALLOW_BYTE_SWAPPED_CLIENTS, + FLAG_SINGLE_DRIVER, } FlagValues; /** @@ -718,6 +719,8 @@ static OptionInfoRec FlagOptions[] = { {0}, FALSE}, {FLAG_ALLOW_BYTE_SWAPPED_CLIENTS, "AllowByteSwappedClients", OPTV_BOOLEAN, {0}, FALSE}, + {FLAG_SINGLE_DRIVER, "SingleDriver", OPTV_BOOLEAN, + {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE}, }; @@ -815,6 +818,17 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) LogMessageVerb(from, 1, "%sutomatically binding GPU devices\n", xf86Info.autoBindGPU ? "A" : "Not a"); + if (xf86IsOptionSet(FlagOptions, FLAG_SINGLE_DRIVER)) { + xf86GetOptValBool(FlagOptions, FLAG_SINGLE_DRIVER, + &xf86Info.singleDriver); + from = X_CONFIG; + } + else { + from = X_DEFAULT; + } + LogMessageVerb(from, 1, "Allowing %s one driver to add non-GPU screens\n", + xf86Info.singleDriver ? "only" : "more than"); + /* * Set things up based on the config file information. Some of these * settings may be overridden later when the command line options are diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c index 58e20dcde3..5c7d5820bd 100644 --- a/hw/xfree86/common/xf86Globals.c +++ b/hw/xfree86/common/xf86Globals.c @@ -131,6 +131,7 @@ xf86InfoRec xf86Info = { .autoAddGPU = FALSE, #endif .autoBindGPU = TRUE, + .singleDriver = FALSE, }; const char *xf86ConfigFile = NULL; diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 33e2c4aad0..557f357d56 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -440,7 +440,7 @@ InitOutput(int argc, char **argv) if (want_hw_access) xorgHWAccess = xf86EnableIO(); - if (xf86BusConfig() == FALSE) + if (xf86BusConfig(xf86Info.singleDriver) == FALSE) return; diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h index 5a1db5d1c1..38100c4db4 100644 --- a/hw/xfree86/common/xf86Privstr.h +++ b/hw/xfree86/common/xf86Privstr.h @@ -94,6 +94,9 @@ typedef struct { Bool autoAddGPU; const char *debug; Bool autoBindGPU; + + Bool singleDriver; /* Only the first successfully probed driver adds primary screens, + * others may add GPU secondary screens only */ } xf86InfoRec, *xf86InfoPtr; /* ISC's cc can't handle ~ of UL constants, so explicitly type cast them. */