For several years I’ve struggled with poor Intel integrated graphics performance on my Dell Precision Mobile 7510 (Intel HD 530 primary and Quadro M2000M discrete via Bumblebee) on Fedora Linux. After starting to experience hard full system locks on video playback requiring a hard power off a few times a week, I have dug into the settings yet another time and finally had a breakthrough.
The symptoms I was experiencing were:
- High baseline idle CPU consumption in Chrome/Chromium and IntelliJ/PyCharm
- Extremely high CPU consumption on video playback in Chrome/Chromium and scrolling
- Extremely high CPU consumption working in IntelliJ/PyCharm with huge typing, scrolling, rendering lag
- Obvious resultant high fan speed/noise
- Obvious resultant poor battery life
- Extremely low framerate on two 4K 60Hz Samsung monitors connected via a Thunderbolt hub with simple window rendering, browsing and video
- Extreme tearing of high resolution video or full-screen 1080p upscaled to 4K video in VLC and Chrome/Chromium
Below is the final configuration that I came up with that resolved all of my issues. While the exact configuration is specific to Fedora and my system, with minor modifications it can be easily applied to all other Linux flavors. Similarly this likely should also apply to other Dell Precision Mobile 5000- and 7000-series laptops as well as the XPS and Inspiron lines. I have also verified this to be working on at least one Intel NUC.
Kernel
Let’s start with kernel configuration. As of writing this Fedora 29 is on kernel 5.0.9 which has an integrated i915 driver maintained by Intel. While the default configuration is usually fine, you can push it further to make sure your video microcode is up-to-date and to optimize power savings.
I have settled on the following settings:
i915.enable_dc=2 i915.disable_power_well=0 i915.enable_fbc=1 i915.enable_guc=3 i915.enable_dpcd_backlight=1
The settings meaning can be looked up via modinfo i915
(output redacted):
parm: enable_dc:Enable power-saving display C-states. (-1=auto [default]; 0=disable; 1=up to DC5; 2=up to DC6) (int) parm: disable_power_well:Disable display power wells when possible (-1=auto [default], 0=power wells always on, 1=power wells disabled when possible) (int) parm: enable_fbc:Enable frame buffer compression for power savings (default: -1 (use per-chip default)) (int) parm: enable_guc:Enable GuC load for GuC submission and/or HuC load. Required functionality can be selected using bitmask values. (-1=auto, 0=disable [default], 1=GuC submission, 2=HuC load) (int) parm: enable_dpcd_backlight:Enable support for DPCD backlight control (default:false) (bool)
In order to make sure these settings are always added to kernel during boot after kernel update, you need to permanently add them to the Grub configuration which can be seen here:
$ cat /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" GRUB_DEFAULT=0 GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="resume=/dev/mapper/fedora-swap rd.lvm.lv=fedora/root rd.lvm.lv=fedora/swap rootflags=discard rhgb rd.driver.blacklist=nouveau i915.enable_dc=2 i915.disable_power_well=0 i915.enable_fbc=1 i915.enable_guc=3 i915.enable_dpcd_backlight=1 l1tf=flush" GRUB_DISABLE_RECOVERY="false"
To rebuild the kernel run sudo grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
if you’re on UEFI system.
X Server
This is probably one of the most important discoveries I made. Some time ago in their X build Fedora started defaulting to "xf86-video-modesetting
driver (aka “modesetting”) that uses glamor
accelerator. Glamor accelerator uses OpenGL/EGL for rendering and for whatever reason on my system it is as slow as cold molasses – atrocious rendering and fill rates. I have no idea whether it’s related to the interaction with a compositor or Mesa drivers, but modesetting was definitely an atrocious laggard. The solution I found is to configure X to use the Intel driver (x86-video-intel), with Intel hardware-specific SNA accelerator and DRI3 for all Intel cards present.
In order to make sure to force X to load the drivers and configuration required I used the following config. Notice, that the order “99” places the config dead last to be loaded to make sure it’s not overwritten with various Bumblebee/Optimus-related configs that may be installed by respective packages:
$ cat /etc/X11/xorg.conf.d/99-intel.conf Section "OutputClass" Identifier "intel" MatchDriver "i915" Driver "intel" Option "AccelMethod" "sna" Option "TearFree" "true" Option "DRI" "3" EndSection
Once you save the file you’ll need to either reboot or log out and log back in to restart X. You should verify that the Intel x86-video-driver is now active and should see something like this:
$ cat /var/log/Xorg.0.log | grep -i intel [ 1957.769] (II) Applying OutputClass "intel" to /dev/dri/card0 [ 1957.769] loading driver: intel [ 1957.769] (==) Matched intel as autoconfigured driver 0 [ 1957.769] (II) LoadModule: "intel" [ 1957.769] (II) Loading /usr/lib64/xorg/modules/drivers/intel_drv.so [ 1957.770] (II) Module intel: vendor="X.Org Foundation" [ 1957.771] (II) intel: Driver for Intel(R) Integrated Graphics Chipsets: [ 1957.771] (II) intel: Driver for Intel(R) HD Graphics [ 1957.771] (II) intel: Driver for Intel(R) Iris(TM) Graphics [ 1957.771] (II) intel: Driver for Intel(R) Iris(TM) Pro Graphics [ 1957.771] (II) intel(0): Using Kernel Mode Setting driver: i915, version 1.6.0 20181204 [ 1957.785] (--) intel(0): Integrated Graphics Chipset: Intel(R) HD Graphics 530 [ 1957.785] (--) intel(0): CPU: x86-64, sse2, sse3, ssse3, sse4.1, sse4.2, avx, avx2; using a maximum of 4 threads [ 1957.785] (II) intel(0): Creating default Display subsection in Screen section [ 1957.786] (==) intel(0): Depth 24, (--) framebuffer bpp 32 [ 1957.786] (==) intel(0): RGB weight 888 [ 1957.786] (==) intel(0): Default visual is TrueColor [ 1957.786] (II) Applying OutputClass "intel" options to /dev/dri/card0 [ 1957.786] (**) intel(0): Option "AccelMethod" "sna" [ 1957.786] (**) intel(0): Option "DRI" "3" [ 1957.786] (**) intel(0): Option "TearFree" "true" [ 1957.787] (II) intel(0): Output eDP1 has no monitor section [ 1957.787] (**) intel(0): Found backlight control interface intel_backlight (type 'raw') for output eDP1 [ 1957.787] (II) intel(0): Enabled output eDP1 [ 1957.787] (II) intel(0): Output DP1 has no monitor section [ 1957.787] (II) intel(0): Enabled output DP1 [ 1957.787] (II) intel(0): Output HDMI1 has no monitor section [ 1957.787] (II) intel(0): Enabled output HDMI1 [ 1957.787] (II) intel(0): Output DP2 has no monitor section [ 1957.788] (II) intel(0): Enabled output DP2 [ 1957.788] (II) intel(0): Output HDMI2 has no monitor section [ 1957.788] (II) intel(0): Enabled output HDMI2 [ 1957.788] (II) intel(0): Output DP3 has no monitor section [ 1957.788] (II) intel(0): Enabled output DP3 [ 1957.788] (II) intel(0): Output HDMI3 has no monitor section [ 1957.788] (II) intel(0): Enabled output HDMI3 [ 1957.788] (--) intel(0): Using a maximum size of 256x256 for hardware cursors [ 1957.788] (II) intel(0): Output VIRTUAL1 has no monitor section [ 1957.788] (II) intel(0): Enabled output VIRTUAL1 [ 1957.789] (--) intel(0): Output eDP1 using initial mode 1920x1080 on pipe 0 [ 1957.789] (--) intel(0): Output DP2 using initial mode 1920x1080 on pipe 1 [ 1957.789] (--) intel(0): Output DP3 using initial mode 1920x1080 on pipe 2 [ 1957.789] (**) intel(0): TearFree enabled [ 1957.789] (==) intel(0): Using gamma correction (1.0, 1.0, 1.0) [ 1957.789] (==) intel(0): DPI set to (96, 96) [ 1957.791] (II) intel(0): SNA initialized with Skylake (gen9) backend [ 1957.791] (==) intel(0): Backing store enabled [ 1957.791] (==) intel(0): Silken mouse enabled [ 1957.792] (II) intel(0): HW Cursor enabled [ 1957.792] (==) intel(0): DPMS enabled [ 1957.792] (==) intel(0): Display hotplug detection enabled [ 1957.792] (II) intel(0): [DRI2] Setup complete [ 1957.792] (II) intel(0): [DRI2] DRI driver: i965 [ 1957.792] (II) intel(0): [DRI2] VDPAU driver: va_gl [ 1957.792] (II) intel(0): direct rendering: DRI2 DRI3 enabled [ 1957.792] (II) intel(0): hardware support for Present enabled [ 1957.818] (II) intel(0): switch to mode [email protected] on eDP1 using pipe 0, position (0, 0), rotation normal, reflection none [ 1957.830] (II) intel(0): switch to mode [email protected] on DP2 using pipe 1, position (0, 0), rotation normal, reflection none [ 1957.831] (II) intel(0): switch to mode [email protected] on DP3 using pipe 2, position (0, 0), rotation normal, reflection none [ 1957.847] (II) intel(0): Setting screen physical size to 508 x 285 ... [ 49915.656] (II) intel(0): resizing framebuffer to 6000x3840 [ 49915.730] (II) intel(0): switch to mode [email protected] on eDP1 using pipe 0, position (2160, 2760), rotation normal, reflection none [ 49915.765] (II) intel(0): switch to mode [email protected] on DP2 using pipe 1, position (0, 0), rotation right, reflection none [ 49917.496] (II) intel(0): switch to mode [email protected] on DP3 using pipe 2, position (2160, 600), rotation normal, reflection none
Compositor
My current settings are below, take them for what they are. Feel free to experiment (I won’t, I’m happy now ;)):
Chromium VAAPI
Default Chrome and Chromium on Fedora are built without VA-API. VA-API stands for Video Acceleration API (surprise!) and Intel has implemented a driver for Intel hardware to allow video de-/en-coding to use various hardware instructions to reduce general CPU load and increase playback/encoding performance. Without this, even the entire 4C/8T CPU will be unable to render a 4K/30fps video in Chromium and it’ll take half of the CPU to play a 1080p one.
Luckily, there is a complete solution to the lack of hardware acceleration in Fedora stock Chromium:
- Install RPM Fusion Free repository.
- Install the following packages
sudo dnf install -y libva libva-intel-driver libva-intel-hybrid-driver libva-utils libva-vdpau-driver chromium-vaapi
. - Verify that VA-API has been successfully installed and you get something like this:
$ vainfo libva info: VA-API version 1.4.1 libva info: va_getDriverName() returns 0 libva info: Trying to open /usr/lib64/dri/i965_drv_video.so libva info: Found init function __vaDriverInit_1_4 libva info: va_openDriver() returns 0 vainfo: VA-API version: 1.4 (libva 2.4.0) vainfo: Driver version: Intel i965 driver for Intel(R) Skylake - 2.3.0 vainfo: Supported profile and entrypoints VAProfileMPEG2Simple : VAEntrypointVLD VAProfileMPEG2Simple : VAEntrypointEncSlice VAProfileMPEG2Main : VAEntrypointVLD ...snip...
- Find your Chromium-VAAPI desktop application, edit it, and in the Application tab change
/usr/bin/chromium-vaapi %U
to/usr/bin/chromium-vaapi --disable-gpu-driver-bug-workarounds --enable-native-gpu-memory-buffers --gpu-rasterization-msaa-sample-count=0 %U
as follows:
- Start Chromium-VAAPI, open
chrome://flags
and setOverride software rendering list
andZero-copy rasterizer
to Enabled. Restart Chromium-VAAPI. - Start Chromium-VAAPI, open
chrome://gpu
and make sure that you see something along these lines:
Hope this helps!