Fixing Laggy External Monitor Using KDE Plasma on Arch Linux

2024-10-12

3 min read

Recently, I encountered severe performance issues when using an external monitor with KDE Plasma on my 2018 laptop, which has an NVIDIA GTX 1060. Despite having no trouble driving a 4K60 display on Windows, on Wayland KDE with Arch Linux, I experienced screen artifacts around the taskbar when switching windows, and the rendering dropped to 1 FPS whenever I shook the large cursor.

TL;DR

If you’re here for the solution, skip to the solution section.


Troubleshooting Steps

  1. First, I blamed the Nvidia driver update, because the problem seemed to only happen after I ran sudo pacman -Syyu. But downgrading the driver didn't resolve the issue.
  2. I suspected my aging laptop (going into its seventh year) might be the problem and the GPU became faulty somehow. But I still decided to exhaust all potential fixes before discarding the machine.
  3. Maybe the resolution was too high (but WHY?), so I cranked down the resolution to 1920x1080. The artifacts went away, but there began to be heavy screen tearing. I switched back to UHD knowing this wasn't the right solution.
  4. Tried installing envycontrol to switch to dedicated GPU rendering mode, but no effect.
  5. I was at this point tempted by re-installing Windows and calling it a day, but eventually gave up because it required too much work.
  6. After a short break, I suddenly realized it might be because the incorrect GPU was rendering the external screen, so I googled it and bang! One of the top solutions fixed my problem.

Solution

It turns out KDE defaults to the iGPU for the rendering even when I plugged in an external monitor, and the weak integrated GPU just couldn't handle a 4k monitor. So I only need to add an environment variable to let the desktop environment use dGPU instead. Link to the post

I would like to say this wasn't the fault of the iGPU. It could carry the daily desktop work of a UHD monitor perfectly fine on Windows. God knows what happened to it on Linux...

Here are the steps:

  1. run lspci to see the PCI address of the two GPUs. In my case, it was 01:00.0 for the Nvidia GPU and 00:02.0 for the iGPU.
$ lspci | grep NVIDIA
01:00.0 VGA compatible controller: NVIDIA Corporation GP106M [GeForce GTX 1060 Mobile] (rev a1)
01:00.1 Audio device: NVIDIA Corporation GP106 High Definition Audio Controller (rev a1)

# Use something other than `Graphics` as the keyword if you can't find anything
$ lspci | grep Graphics
00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-H GT2 [UHD Graphics 630]
  1. Edit /etc/environment and add the KWIN_DRM_DEVICES variable. The variable sets the priorities of GPUs for screen rendering.
KWIN_DRM_DEVICES="/dev/dri/by-path/pci-0000\:01\:00.0-card:/dev/dri/by-path/pci-0000\:00\:02.0-card"
  1. Reboot the laptop, and now the external monitor is fluent AF.

There are still some bugs, though. For example, maximizing Chrome will result in an empty bar at the top of the screen (seems like it was offset by the height of the task bar), but minimizing and re-opening the window fixes the problem. In addition, I can't use the laptop for more than 30 minutes on battery from now on, because the dGPU is always preferred even on a mobile setting. But I'm at least happy with the smooth external monitor experience.