Hybrid graphics

From ArchWiki
Revision as of 11:19, 11 August 2020 by Lahwaacz (talk | contribs) (→‎Using bbswitch: add breakage note)

Hybrid-graphics is a concept involving two graphics cards on same computer. Laptop manufacturers have developed new technologies involving two graphic cards with different abilities and power consumptions on a single computer. Hybrid-graphics has been developed to support both high performance and power saving use cases.

There are a variety of technologies and each manufacturer developed its own solution to this problem. This technology is well supported on Windows but it's still quite experimental with Linux distributions. Here we try to explain a little about each approach and describe some community solutions to the lack of GNU/Linux systems support.

First Generation Hybrid Model (Basic Switching)

This article or section is being considered for removal.

Reason: Outdated, even the Wikipedia article about GPU switching does not describe this approach. Maybe part of this can be left as a historical note in the introduction. (Discuss in Talk:Hybrid graphics)
Note: Unless your notebook is from the last decade, it’s most likely using dynamic switching.

The first generation of notebooks with hybrid graphics follow an approach that involves a two graphic card setup with a hardware multiplexer (MUX). It allows power save and low-end 3D rendering by using an Integrated Graphics Processor (IGP) or a major power consumption with 3D rendering performance using a Dedicated/Discrete Graphics Processor (DGP). This model makes the user choose (at boot time or at login time) between the two power/graphics profiles and is almost fixed throughout the user session. The switch is done in a workflow similar to the following:

  • Turn off the display
  • Turn on the DGP
  • Switch the multiplexer
  • Turn off the IGP
  • Turn the display on again

This switch is somewhat rough and adds some blinks and black screens in laptops that could do it "on the fly". Later approaches made the transition a little more user-friendly.

Dynamic Switching Model

Note: This model is utilized by most manufacturers as of 2016.

Most of the new Hybrid-graphics technologies involve two graphic cards as the basic switching but now the DGP and IGP are plugged to a framebuffer and there is no hardware multiplexer. The IGP is always on and the DGP is switched on/off when there is a need in power-save or performance-rendering. In most cases there is no way to use only the DGP and all the switching and rendering is controlled by software. At startup, the Linux kernel starts using a video mode and setting up low-level graphic drivers which will be used by the applications. Most of the Linux distributions then use X.org to create a graphical environment. Finally, a few other softwares are launched, first a login manager and then a window manager, and so on. This hierarchical system has been designed to be used in most of cases on a single graphic card.

Note: Read NVIDIA Optimus and Bumblebee for details about NVidia using hybrid graphics with NVidia’s proprietary driver. Read PRIME for basically everything else (like AMD Radeon and NVidia GPUs with Nouveau driver).

Fully Power Down Discrete GPU

You may want to turn off the high-performance graphics processor to save battery power.

Using bbswitch

With a NVidia GPU, this can be more safely done using bbswitch, which consists of a kernel package that automatically issues the correct ACPI calls to disable the discrete GPU when not needed, or automatically at boot.

Note: bbswitch does not work with the PCI-E port power management method since kernel 4.8. See Bumblebee#Broken power management with kernel 4.8 for details.

Using acpi_call

Otherwise, and for GPUs not supported by bbswitch, the same can be done manually installing the acpi_call package.

Tip: For kernels not in the Official repositories, the acpi_call-dkms is an alternative. See also DKMS.

Once installed load the kernel module:

# modprobe acpi_call

With the kernel module loaded, download and execute this script: https://raw.githubusercontent.com/mkottman/acpi_call/master/examples/turn_off_gpu.sh

The script will go through all the known data buses and attempt to turn them off. You will get an output similar to the following:

Trying \_SB.PCI0.P0P1.VGA._OFF: failed
Trying \_SB.PCI0.P0P2.VGA._OFF: failed
Trying \_SB_.PCI0.OVGA.ATPX: failed
Trying \_SB_.PCI0.OVGA.XTPX: failed
Trying \_SB.PCI0.P0P3.PEGP._OFF: failed
Trying \_SB.PCI0.P0P2.PEGP._OFF: failed
Trying \_SB.PCI0.P0P1.PEGP._OFF: failed
Trying \_SB.PCI0.MXR0.MXM0._OFF: failed
Trying \_SB.PCI0.PEG1.GFX0._OFF: failed
Trying \_SB.PCI0.PEG0.GFX0.DOFF: failed
Trying \_SB.PCI0.PEG1.GFX0.DOFF: failed
Trying \_SB.PCI0.PEG0.PEGP._OFF: works!
Trying \_SB.PCI0.XVR0.Z01I.DGOF: failed
Trying \_SB.PCI0.PEGR.GFX0._OFF: failed
Trying \_SB.PCI0.PEG.VID._OFF: failed
Trying \_SB.PCI0.PEG0.VID._OFF: failed
Trying \_SB.PCI0.P0P2.DGPU._OFF: failed
Trying \_SB.PCI0.P0P4.DGPU.DOFF: failed
Trying \_SB.PCI0.IXVE.IGPU.DGOF: failed
Trying \_SB.PCI0.RP00.VGA._PS3: failed
Trying \_SB.PCI0.RP00.VGA.P3MO: failed
Trying \_SB.PCI0.GFX0.DSM._T_0: failed
Trying \_SB.PCI0.LPC.EC.PUBS._OFF: failed
Trying \_SB.PCI0.P0P2.NVID._OFF: failed
Trying \_SB.PCI0.P0P2.VGA.PX02: failed
Trying \_SB_.PCI0.PEGP.DGFX._OFF: failed
Trying \_SB_.PCI0.VGA.PX02: failed

See the "works"? This means the script found a bus which your GPU sits on and it has now turned off the chip. To confirm this, your battery time remaining should have increased.

Tip: If you are experiencing trouble hibernating or suspending the system after disabling the GPU, try to enable it again by sending the corresponding acpi_call. See also Suspend/resume service files.
Turning off the GPU automatically

Currently, the chip will turn back on with the next reboot. To get around this, add the kernel module to the array of modules to load at boot:

/etc/modules-load.d/acpi_call.conf
#Load 'acpi_call.ko' at boot.

acpi_call
At boot

To turn off the GPU at boot it is possible to use systemd-tmpfiles.

/etc/tmpfiles.d/acpi_call.conf

w /proc/acpi/call - - - - \\_SB.PCI0.PEG0.PEGP._OFF

The above config will be loaded at boot by systemd. What it does is write the specific OFF signal to the /proc/acpi/call file. Obviously, replace the \_SB.PCI0.PEG0.PEGP._OFF with the one which works on your system (please note that you need to escape the backslash).

After X server initialization

On some systems, turning off the discrete GPU before the X server is initialized may hang the system. In such cases, it may be better to disable the GPU after X server initialization, which is possible with some display managers. In LightDM, for instance, the display-setup-script seat configuration parameter could be used to execute a script as root that disables the GPU.