NixOS Config Switching

Posted

After using NixOS for about 3 months I found another benefit of the declarative and unified configuration. My laptop has a multi-GPU setup with Intel+NVIDIA. However the NVIDIA drivers don’t support multi-GPU under Wayland. Wayland is significantly better for my day-to-day use so I stick to the Intel drivers. However when playing games, using the NVIDIA GPU with proprietary drivers provides a significant performance advantage. In order to accommodate these two use cases I find myself switching between the two GPUs. (until my new desktop with an AMD card arrives --my-next-gpu-wont-be-nvidia)

On Arch I would solve this by removing and recreating the nouveau modprobe blacklist and rebooting. This was enough to get the NVIDIA drivers running and I could enjoy my games. This wasn’t too bad to manage as it was only one file but it basically relied on two commands in my shell history. It would also become very annoying if I needed to change more than one thing (for example if I also needed to tweak my X config).

On NixOS I can support both using the same config and mostly declaratively. Here is a simplified version of my config.

{...}: let
	nvidia = builtins.getEnv "NVIDIA" != "";
in {
	services.xserver = {
		enable = true;
		displayManager = {
			gdm.enable = !nvidia;
			lightdm.enable = nvidia;
		};

		videoDrivers = if nvidia then [ "nvidia" ] else [];
	};

	hardware.nvidia.modesetting.enable = true;
	hardware.nvidia.prime = {
		sync.enable = true;

		# Bus IDs are the first three numbers from `lspci`.
		intelBusId = "PCI:0:2:0";
		nvidiaBusId = "PCI:1:0:0";
	};
}

The main thing this this config does is enables the NVIDIA drivers based on the environment variable NVIDIA. However due to a bug, NVIDIA drivers aren’t working on GDM at the moment. In order to sidestep this issue I swap out GDM for lightdm when using the NVIDIA drivers. I might consider adding more customization in the future, such as disabling unnecessary services if it makes a noticeable performance difference.

Now I can simply enter “gaming mode” by running sudo env NVIDIA=1 nixos-rebuild boot && reboot. Then I can go back by rebuilding my system normally.

Another option is to build the “gaming” profile separately like sudo env NVIDIA=1 nixos-rebuild boot -p nvidia. Then I can just select that profile from the boot menu. This has the advantage that is is easier to update the profiles separately. For example I could keep using the gaming profile from before the GDM issue appeared and still regularly update the main profile.

This is quite a simple change, but I can definitely imagine use cases for a gaming mode, streaming mode, work mode and personal mode. Making it this easy to switch between arbitrarily different configurations opens up a lot of posibilities that were unimaginable with the configuration methods of more traditional distributions.