123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- From 4471df41ea6e94834a2b10643ca7fcd69682d276 Mon Sep 17 00:00:00 2001
- From: Dave Airlie <airlied@redhat.com>
- Date: Fri, 17 Aug 2012 09:49:24 +1000
- Subject: [PATCH xserver v3] autobind GPUs to the screen
- This is a modified version of a patch we've been carry-ing in Fedora and
- RHEL for years now. This patch automatically adds secondary GPUs to the
- master as output sink / offload source making e.g. the use of
- slave-outputs just work, with requiring the user to manually run
- "xrandr --setprovideroutputsource" before he can hookup an external
- monitor to his hybrid graphics laptop.
- There is one problem with this patch, which is why it was not upstreamed
- before. What to do when a secondary GPU gets detected really is a policy
- decission (e.g. one may want to autobind PCI GPUs but not USB ones) and
- as such should be under control of the Desktop Environment.
- Unconditionally adding autobinding support to the xserver will result
- in races between the DE dealing with the hotplug of a secondary GPU
- and the server itself dealing with it.
- However we've waited for years for any Desktop Environments to actually
- start doing some sort of autoconfiguration of secondary GPUs and there
- is still not a single DE dealing with this, so I believe that it is
- time to upstream this now.
- To avoid potential future problems if any DEs get support for doing
- secondary GPU configuration themselves, the new autobind functionality
- is made optional. Since no DEs currently support doing this themselves it
- is enabled by default. When DEs grow support for doing this themselves
- they can disable the servers autobinding through the servers cmdline or a
- xorg.conf snippet.
- Signed-off-by: Dave Airlie <airlied@gmail.com>
- [hdegoede@redhat.com: Make configurable, fix with nvidia, submit upstream]
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- ---
- Changes in v2:
- -Make the default enabled instead of installing a xorg.conf
- snippet which enables it unconditionally
- Changes in v3:
- -Handle GPUScreen autoconfig in randr/rrprovider.c, looking at
- rrScrPriv->provider, rather then in hw/xfree86/modes/xf86Crtc.c
- looking at xf86CrtcConfig->provider. This fixes the autoconfig not
- working with the nvidia binary driver
- ---
- hw/xfree86/common/xf86Config.c | 19 +++++++++++++++++++
- hw/xfree86/common/xf86Globals.c | 2 ++
- hw/xfree86/common/xf86Init.c | 20 ++++++++++++++++++++
- hw/xfree86/common/xf86Priv.h | 1 +
- hw/xfree86/common/xf86Privstr.h | 1 +
- hw/xfree86/common/xf86platformBus.c | 4 ++++
- hw/xfree86/man/Xorg.man | 7 +++++++
- hw/xfree86/man/xorg.conf.man | 6 ++++++
- randr/randrstr.h | 3 +++
- randr/rrprovider.c | 22 ++++++++++++++++++++++
- 10 files changed, 85 insertions(+)
- diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
- index 21daf1a..df3ca50 100644
- --- a/hw/xfree86/common/xf86Config.c
- +++ b/hw/xfree86/common/xf86Config.c
- @@ -719,6 +719,7 @@ typedef enum {
- FLAG_DRI2,
- FLAG_USE_SIGIO,
- FLAG_AUTO_ADD_GPU,
- + FLAG_AUTO_BIND_GPU,
- FLAG_MAX_CLIENTS,
- FLAG_IGLX,
- } FlagValues;
- @@ -778,6 +779,8 @@ static OptionInfoRec FlagOptions[] = {
- {0}, FALSE},
- {FLAG_AUTO_ADD_GPU, "AutoAddGPU", OPTV_BOOLEAN,
- {0}, FALSE},
- + {FLAG_AUTO_BIND_GPU, "AutoBindGPU", OPTV_BOOLEAN,
- + {0}, FALSE},
- {FLAG_MAX_CLIENTS, "MaxClients", OPTV_INTEGER,
- {0}, FALSE },
- {FLAG_IGLX, "IndirectGLX", OPTV_BOOLEAN,
- @@ -857,6 +860,22 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
- }
- xf86Msg(from, "%sutomatically adding GPU devices\n",
- xf86Info.autoAddGPU ? "A" : "Not a");
- +
- + if (xf86AutoBindGPUDisabled) {
- + xf86Info.autoBindGPU = FALSE;
- + from = X_CMDLINE;
- + }
- + else if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_BIND_GPU)) {
- + xf86GetOptValBool(FlagOptions, FLAG_AUTO_BIND_GPU,
- + &xf86Info.autoBindGPU);
- + from = X_CONFIG;
- + }
- + else {
- + from = X_DEFAULT;
- + }
- + xf86Msg(from, "%sutomatically binding GPU devices\n",
- + xf86Info.autoBindGPU ? "A" : "Not a");
- +
- /*
- * 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 e962b75..0d1e31b 100644
- --- a/hw/xfree86/common/xf86Globals.c
- +++ b/hw/xfree86/common/xf86Globals.c
- @@ -136,6 +136,7 @@ xf86InfoRec xf86Info = {
- #else
- .autoAddGPU = FALSE,
- #endif
- + .autoBindGPU = TRUE,
- };
-
- const char *xf86ConfigFile = NULL;
- @@ -197,6 +198,7 @@ Bool xf86FlipPixels = FALSE;
- Gamma xf86Gamma = { 0.0, 0.0, 0.0 };
-
- Bool xf86AllowMouseOpenFail = FALSE;
- +Bool xf86AutoBindGPUDisabled = FALSE;
-
- #ifdef XF86VIDMODE
- Bool xf86VidModeDisabled = FALSE;
- diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
- index a544b65..b0cba3d 100644
- --- a/hw/xfree86/common/xf86Init.c
- +++ b/hw/xfree86/common/xf86Init.c
- @@ -76,6 +76,7 @@
- #include "xf86DDC.h"
- #include "xf86Xinput.h"
- #include "xf86InPriv.h"
- +#include "xf86Crtc.h"
- #include "picturestr.h"
-
- #include "xf86Bus.h"
- @@ -298,6 +299,19 @@ xf86PrivsElevated(void)
- }
-
- static void
- +xf86AutoConfigOutputDevices(void)
- +{
- + int i;
- +
- + if (!xf86Info.autoBindGPU)
- + return;
- +
- + for (i = 0; i < xf86NumGPUScreens; i++)
- + RRProviderAutoConfigGpuScreen(xf86ScrnToScreen(xf86GPUScreens[i]),
- + xf86ScrnToScreen(xf86Screens[0]));
- +}
- +
- +static void
- InstallSignalHandlers(void)
- {
- /*
- @@ -871,6 +885,8 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
- for (i = 0; i < xf86NumGPUScreens; i++)
- AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen);
-
- + xf86AutoConfigOutputDevices();
- +
- xf86VGAarbiterWrapFunctions();
- if (sigio_blocked)
- input_unlock();
- @@ -1389,6 +1405,10 @@ ddxProcessArgument(int argc, char **argv, int i)
- xf86Info.iglxFrom = X_CMDLINE;
- return 0;
- }
- + if (!strcmp(argv[i], "-noautoBindGPU")) {
- + xf86AutoBindGPUDisabled = TRUE;
- + return 1;
- + }
-
- /* OS-specific processing */
- return xf86ProcessArgument(argc, argv, i);
- diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
- index c1f8a18..9a3d0df 100644
- --- a/hw/xfree86/common/xf86Priv.h
- +++ b/hw/xfree86/common/xf86Priv.h
- @@ -46,6 +46,7 @@
- extern _X_EXPORT const char *xf86ConfigFile;
- extern _X_EXPORT const char *xf86ConfigDir;
- extern _X_EXPORT Bool xf86AllowMouseOpenFail;
- +extern _X_EXPORT Bool xf86AutoBindGPUDisabled;
-
- #ifdef XF86VIDMODE
- extern _X_EXPORT Bool xf86VidModeDisabled;
- diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
- index c29b3cc..4c5f54b 100644
- --- a/hw/xfree86/common/xf86Privstr.h
- +++ b/hw/xfree86/common/xf86Privstr.h
- @@ -102,6 +102,7 @@ typedef struct {
- MessageType dri2From;
-
- Bool autoAddGPU;
- + Bool autoBindGPU;
- } xf86InfoRec, *xf86InfoPtr;
-
- #ifdef DPMSExtension
- diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
- index 063e81c..42789ca 100644
- --- a/hw/xfree86/common/xf86platformBus.c
- +++ b/hw/xfree86/common/xf86platformBus.c
- @@ -48,6 +48,7 @@
- #include "Pci.h"
- #include "xf86platformBus.h"
- #include "xf86Config.h"
- +#include "xf86Crtc.h"
-
- #include "randrstr.h"
- int platformSlotClaimed;
- @@ -579,6 +580,9 @@ xf86platformAddDevice(int index)
- }
- /* attach unbound to 0 protocol screen */
- AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen);
- + if (xf86Info.autoBindGPU)
- + RRProviderAutoConfigGpuScreen(xf86ScrnToScreen(xf86GPUScreens[i]),
- + xf86ScrnToScreen(xf86Screens[0]));
-
- RRResourcesChanged(xf86Screens[0]->pScreen);
- RRTellChanged(xf86Screens[0]->pScreen);
- diff --git a/hw/xfree86/man/Xorg.man b/hw/xfree86/man/Xorg.man
- index def9bfc..8df6b7d 100644
- --- a/hw/xfree86/man/Xorg.man
- +++ b/hw/xfree86/man/Xorg.man
- @@ -283,6 +283,13 @@ is a comma separated list of directories to search for
- server modules. This option is only available when the server is run
- as root (i.e, with real-uid 0).
- .TP 8
- +.B \-noautoBindGPU
- +Disable automatically setting secondary GPUs up as output sinks and offload
- +sources. This is equivalent to setting the
- +.B AutoBindGPU
- +xorg.conf(__filemansuffix__) file option. To
- +.B false.
- +.TP 8
- .B \-nosilk
- Disable Silken Mouse support.
- .TP 8
- diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
- index 7d0c524..3e596e4 100644
- --- a/hw/xfree86/man/xorg.conf.man
- +++ b/hw/xfree86/man/xorg.conf.man
- @@ -673,6 +673,12 @@ Enabled by default.
- If this option is disabled, then no GPU devices will be added from the udev
- backend. Enabled by default. (May need to be disabled to setup Xinerama).
- .TP 7
- +.BI "Option \*qAutoBindGPU\*q \*q" boolean \*q
- +If enabled then secondary GPUs will be automatically set up as output-sinks and
- +offload-sources. Making e.g. laptop outputs connected only to the secondary
- +GPU directly available for use without needing to run
- +"xrandr --setprovideroutputsource". Enabled by default.
- +.TP 7
- .BI "Option \*qLog\*q \*q" string \*q
- This option controls whether the log is flushed and/or synced to disk after
- each message.
- diff --git a/randr/randrstr.h b/randr/randrstr.h
- index 706e9a7..66999d5 100644
- --- a/randr/randrstr.h
- +++ b/randr/randrstr.h
- @@ -976,6 +976,9 @@ RRProviderLookup(XID id, RRProviderPtr *provider_p);
- extern _X_EXPORT void
- RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider);
-
- +extern _X_EXPORT void
- +RRProviderAutoConfigGpuScreen(ScreenPtr pScreen, ScreenPtr masterScreen);
- +
- /* rrproviderproperty.c */
-
- extern _X_EXPORT void
- diff --git a/randr/rrprovider.c b/randr/rrprovider.c
- index f9df67e..abc5685 100644
- --- a/randr/rrprovider.c
- +++ b/randr/rrprovider.c
- @@ -482,3 +482,25 @@ RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider)
-
- WriteEventsToClient(client, 1, (xEvent *) &pe);
- }
- +
- +void
- +RRProviderAutoConfigGpuScreen(ScreenPtr pScreen, ScreenPtr masterScreen)
- +{
- + rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen);
- + rrScrPrivPtr masterPriv = rrGetScrPriv(masterScreen);
- + RRProviderPtr provider = pScrPriv->provider;
- + RRProviderPtr master_provider = masterPriv->provider;
- +
- + if (!provider || !master_provider)
- + return;
- +
- + if ((provider->capabilities & RR_Capability_SinkOutput) &&
- + (master_provider->capabilities & RR_Capability_SourceOutput)) {
- + pScrPriv->rrProviderSetOutputSource(pScreen, provider, master_provider);
- + RRInitPrimeSyncProps(pScreen);
- + }
- +
- + if ((provider->capabilities & RR_Capability_SourceOffload) &&
- + (master_provider->capabilities & RR_Capability_SinkOffload))
- + pScrPriv->rrProviderSetOffloadSink(pScreen, provider, master_provider);
- +}
- --
- 2.9.3
|