What *exactly* does "Launch using dedicated graphics card" do?

8,178

Solution 1

I had the exact same question, none of the valiables like __GLX_VENDOR_LIBRARY_NAME=nvidia, __NV_PRIME_RENDER_OFFLOAD=1, __VK_LAYER_NV_optimus=NVIDIA_only, DRI_PRIME=1 produced the same result.

I even tried to search in gnome-shell source code but the functions aren't in gnome-shell repo.

I finally ACCIDENTALLY stumbled upon switechroo-controls package,

I tried switcherooctl launch <command> which replicates the gnome shell behaviour. Then I had an epiphany to search for switcheroo in gnome-shell repo.

❯ grep -ri 'switcheroo' 
Binary file .git/index matches
data/dbus-interfaces/net.hadess.SwitcherooControl.xml:      net.hadess.SwitcherooControl:
data/dbus-interfaces/net.hadess.SwitcherooControl.xml:      check the value of net.hadess.SwitcherooControl.HasDualGpu to see
data/dbus-interfaces/net.hadess.SwitcherooControl.xml:      The object path will be "/net/hadess/SwitcherooControl".
data/dbus-interfaces/net.hadess.SwitcherooControl.xml:  <interface name="net.hadess.SwitcherooControl">
js/ui/appDisplay.js:        this._switcherooNotifyId = global.connect('notify::switcheroo-control',
js/ui/appDisplay.js:        this._switcherooProxy = global.get_switcheroo_control();
js/ui/appDisplay.js:        if (this._switcherooProxy) {
js/ui/appDisplay.js:            let prop = this._switcherooProxy.get_cached_property('HasDualGpu');
src/meson.build:dbus_generated += gnome.gdbus_codegen('switcheroo-control',
src/meson.build:  '../data/dbus-interfaces/net.hadess.SwitcherooControl.xml',
src/shell-app.c:#include "switcheroo-control.h"
src/shell-app.c:  proxy = shell_global_get_switcheroo_control (global);
src/shell-app.c:      g_warning ("Could not apply discrete GPU environment, switcheroo-control not available");
src/shell-app.c:  variant = shell_net_hadess_switcheroo_control_get_gpus (SHELL_NET_HADESS_SWITCHEROO_CONTROL (proxy));
src/shell-app.c:  g_debug ("Could not find discrete GPU in switcheroo-control, not applying environment");
src/shell-global.c:#include "switcheroo-control.h"
src/shell-global.c:  GDBusProxy *switcheroo_control;
src/shell-global.c:  GCancellable *switcheroo_cancellable;
src/shell-global.c:  PROP_SWITCHEROO_CONTROL,
src/shell-global.c:got_switcheroo_control_gpus_property_cb (GObject      *source_object,
src/shell-global.c:        g_debug ("Could not get GPUs property from switcheroo-control: %s", error->message);
src/shell-global.c:  g_dbus_proxy_set_cached_property (global->switcheroo_control, "GPUs", gpus);
src/shell-global.c:  g_object_notify (G_OBJECT (global), "switcheroo-control");
src/shell-global.c:switcheroo_control_ready_cb (GObject      *source_object,
src/shell-global.c:  ShellNetHadessSwitcherooControl *control;
src/shell-global.c:  control = shell_net_hadess_switcheroo_control_proxy_new_for_bus_finish (res, &error);
src/shell-global.c:        g_debug ("Could not get switcheroo-control GDBusProxy: %s", error->message);
src/shell-global.c:  global->switcheroo_control = G_DBUS_PROXY (control);
src/shell-global.c:  g_debug ("Got switcheroo-control proxy successfully");
src/shell-global.c:  cached_props = g_dbus_proxy_get_cached_property_names (global->switcheroo_control);
src/shell-global.c:      g_object_notify (G_OBJECT (global), "switcheroo-control");
src/shell-global.c:  g_dbus_connection_call (g_dbus_proxy_get_connection (global->switcheroo_control),
src/shell-global.c:                          g_dbus_proxy_get_name (global->switcheroo_control),
src/shell-global.c:                          g_dbus_proxy_get_object_path (global->switcheroo_control),
src/shell-global.c:                                         g_dbus_proxy_get_interface_name (global->switcheroo_control),
src/shell-global.c:                          global->switcheroo_cancellable,
src/shell-global.c:                          got_switcheroo_control_gpus_property_cb,
src/shell-global.c:    case PROP_SWITCHEROO_CONTROL:
src/shell-global.c:      g_value_set_object (value, global->switcheroo_control);
src/shell-global.c:switcheroo_appeared_cb (GDBusConnection *connection,
src/shell-global.c:  g_debug ("switcheroo-control appeared");
src/shell-global.c:  shell_net_hadess_switcheroo_control_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
src/shell-global.c:                                                         "net.hadess.SwitcherooControl",
src/shell-global.c:                                                         "/net/hadess/SwitcherooControl",
src/shell-global.c:                                                         global->switcheroo_cancellable,
src/shell-global.c:                                                         switcheroo_control_ready_cb,
src/shell-global.c:switcheroo_vanished_cb (GDBusConnection *connection,
src/shell-global.c:  g_debug ("switcheroo-control vanished");
src/shell-global.c:  g_clear_object (&global->switcheroo_control);
src/shell-global.c:  g_object_notify (G_OBJECT (global), "switcheroo-control");
src/shell-global.c:  global->switcheroo_cancellable = g_cancellable_new ();
src/shell-global.c:                    "net.hadess.SwitcherooControl",
src/shell-global.c:                    switcheroo_appeared_cb,
src/shell-global.c:                    switcheroo_vanished_cb,
src/shell-global.c:  g_cancellable_cancel (global->switcheroo_cancellable);
src/shell-global.c:  g_clear_object (&global->switcheroo_cancellable);
src/shell-global.c:                                   PROP_SWITCHEROO_CONTROL,
src/shell-global.c:                                   g_param_spec_object ("switcheroo-control",
src/shell-global.c:                                                        "switcheroo-control",
src/shell-global.c:                                                        "D-Bus Proxy for switcheroo-control daemon",
src/shell-global.c: * shell_global_get_switcheroo_control:
src/shell-global.c: * Get the global #GDBusProxy instance for the switcheroo-control
src/shell-global.c:shell_global_get_switcheroo_control (ShellGlobal  *global)
src/shell-global.c:  return global->switcheroo_control;
src/shell-global.h:         shell_global_get_switcheroo_control    (ShellGlobal  *global);

Which confirms it, more intuitive proof (I am a fedora user): screenshot of terminal


TLDR

In answer to your exact question: Gnome does it by using a library switcheroo-control.

Practical answer: you can do the same thing with switcherooctl launch <command>


EDIT: I am not sure if the command works on ubuntu, but debian and ubuntu repositories have the package switcheroo-control.

This is the tree of extracted switcheroo-control package (deb).

.
├── etc
│   └── dbus-1
│       └── system.d
│           └── net.hadess.SwitcherooControl.conf
├── lib
│   ├── systemd
│   │   └── system
│   │       └── switcheroo-control.service
│   └── udev
│       └── hwdb.d
│           └── 30-pci-intel-gpu.hwdb
└── usr
    ├── libexec
    │   └── switcheroo-control
    └── share
        └── doc
            └── switcheroo-control
                ├── changelog.Debian.gz
                ├── copyright
                ├── NEWS.gz
                └── README.md

Edit: Ok I found the problem, when setting the variable if you set like VAR=value, this is a regular variable, while export VAR=value makes it accessible to subprocesses (REF)

after this,any one of the variables work for me,export __GLX_VENDOR_LIBRARY_NAME=nvidia,export __NV_PRIME_RENDER_OFFLOAD=1,export __VK_LAYER_NV_optimus=NVIDIA_only,export DRI_PRIME=1 (they have their own different functions)

so use switchrootctl launch <command> or, export above variables and launch the process. you can even create a alias

Ex:

alias dgpu="export __GLX_VENDOR_LIBRARY_NAME=nvidia && export __NV_PRIME_RENDER_OFFLOAD=1 &&"

and then dgpu <command>

this is the environment variables set by switchroot-control (in my case). enter image description here

Solution 2

I'm not sure it's the only effect, but from what I can find on my laptop it sets the DRI_PRIME environment variable for the process that is started.

In my case to DRI_PRIME=pci-0000_01_00_0

I couldn't really find much info on how exactly this has an effect, but some info can be found here.

Share:
8,178

Related videos on Youtube

Kryten
Author by

Kryten

Updated on September 18, 2022

Comments

  • Kryten
    Kryten almost 2 years

    There are a number of questions regarding the "Launch using dedicated graphics card" option in Ubuntu: this one, this one, or this one, for example. But none of them are asking the question I really want to know.

    I want to understand what this option does, especially in the context of my system: the motherboard has integrated Intel graphics and an Nvidia Graphics card. I have three monitors attached to the ports on the Nvidia card and nothing attached to the onboard graphics.

    When I see "Launch using dedicated graphics card", I imagine something like this: the desktop is running on (using the hardware of and being rendered in the memory of) the integrated graphics and the contents of this window I've just opened with this option are running on the other graphics card and somehow the output is piped through the integrated graphics (kind of like "picture-in-picture"?).

    But given that I'm not using the onboard graphics at all, aren't my applications already running on the dedicated graphics card?

    I suspect that my understanding of this option is wrong. Can anyone clarify what this option does?

  • Levente
    Levente about 3 years
    You can find even more about vga_switcheroo here: help.ubuntu.com/community/HybridGraphics
  • Shriraj Hegde
    Shriraj Hegde about 3 years
    @Levente can you search and comment the switcherooctl command analogue for ubuntu?
  • Levente
    Levente about 3 years
    On Ubuntu 20.04, with Intel / AMD dual graphics I do have the switcheroo-control package installed (I did not install it, maybe it's installed by default, or the OS installer automatically brought it in when seeing my hardware setup), but $ switcherooctl --help \ switcherooctl: command not found, in addition, tab-completion for a switche substring does not suggest anything.
  • Levente
    Levente about 3 years
    The only thing I managed ever was analogous with the $ DRI_PRIME=<whatev> applicationName, based on this arch wiki but while it appeared to take effect, led to no joy, because I had to conclude that the open-source radeon driver is incompatible with my specific card, and all applications do with it is crashing or not even starting. And all that what I read about amdgpu_pro made me decide not to risk installing it. So I just roll with intel, and not switcheroo around.
  • Shriraj Hegde
    Shriraj Hegde about 3 years
    check thelast edit