nvidia-xrun solution on hybrid graphic + tearing free

This is a post on setting up nvidia drivers on laptop with hybrid graphic cards.

config:

- OS: Archlinux
- Graphic: nvidia GeForce 960m + Intel HD Graphics 530
- i3 as window manager
- startx  (xorg-xinit)

packages to install:

- nvidia
- bbswitch
- nvidia-xrun or nvidia-xrun-git (AUR)

Before setup /etc/X11/nvidia-xorg.conf.d/30-nvidia.conf

Section "Device"
    Identifier "nvidia"
    Driver "nvidia"
    BusID "PCI:1:0:0"
EndSection

Make sure the BusID matches the result of

$ lspci | grep -i nvidia | awk '{print $1}'

Run Window manager with nvidia-xrun

In my case, I simply modified my .xinitrc file into a shell script and put it somewhere in PATH

it’s something like this:

xinit_i3

#!/usr/bin/sh

# fcitx input
export XIM=fcitx
export XIM_PROGRAM=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export GTK_IM_MODULE=fcitx
fcitx -d 

# swap caps
setxkbmap -option caps:swapescape

# some variables

export TERMINAL="st"
export BROWSER="firefox"
export EDITOR=nvim

# background
fehbg &
xset r rate 300 50 
xrandr --dpi 130


# exec dwm
# prime-offload
exec i3

Now intead of using startx, use command nvidia-xrun xinit_i3 to start X with nvidia graphic card.

Avoid Screen Tearing

for intel graphic only, screen tearing can be avoided by adding or modifying this file:

/etc/X11/xorg.conf.d/20-intel.conf
----------------------------------
Section "Device"
  Identifier "Intel Graphics"
  Driver "intel"
  Option "TearFree" "true"
EndSection

For nvidia, we need to set the parameter modeset of module nvidia_drm to 1.

Sadly, this parameter can not be modified in runtime, which mean the vsync feature can only be tweaked upon loading the nvidia_drm module.

nvidia-xrun loads the nvidia related modules when they are unloaded yet. So modify the nvidia-xrun config file:

/etc/default/nvidia-xrun
---------------------------------
# CHANGE THE LINE "MODULES_LOAD" into:
MODULES_LOAD=(nvidia nvidia_uvm nvidia_modeset "nvidia_drm modeset=1")

Now there is still a problem: before calling nvidia-xrun, the nvidia* modules has already been loaded by OS without the modeset parameter, so the nvidia-xrun will not do anything to the modules.

So there are 2 ways to deal with this

1.add something to modprob config: so that the modeset=1 parameter will be set when loading nvidia_drm.

/lib/modprobe.d/nvidia-drm-modeset.conf
---------------------------------------
options nvidia-drm modeset=1

2.the hacky but easy way: edit the nvidia-xrun script, so that it tries to unload the preloaded modules first, then loads the modules itself with correct parameter.

/usr/bin/nvidia-xrun (PARTIAL)

# >>> unload the preloaded modules first. <<<
unload_modules
load_modules
execute ${COMMAND}
unload_modules

REF

https://wiki.archlinux.org/index.php/NVIDIA
https://wiki.archlinux.org/index.php/NVIDIA_Optimus
https://wiki.archlinux.org/index.php/Nvidia-xrun