Fix nvidia on hybrid setups

This commit is contained in:
ItsDrike 2024-06-10 13:54:03 +02:00
parent d1e70957f2
commit deee4df653
Signed by: ItsDrike
GPG key ID: FA2745890B7048C0
4 changed files with 60 additions and 16 deletions

View file

@ -59,7 +59,7 @@
virtual-machine = false; virtual-machine = false;
}; };
cpu.type = "amd"; cpu.type = "amd";
gpu.type = "nvidia"; gpu.type = "hybrid-nvidia";
hasTPM = true; hasTPM = true;
}; };

View file

@ -66,4 +66,11 @@
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
# Enable prime-offload
# This machine has AMD igpu + nvidia dgpu, so we need hybrid
hardware.nvidia.prime = {
nvidiaBusId = "PCI:1:0:0";
amdgpuBusId = "PCI:5:0:0";
};
} }

View file

@ -15,12 +15,21 @@ in
}; };
gpu.type = mkOption { gpu.type = mkOption {
type = with types; nullOr (enum [ "nvidia" "amd" "intel" ]); type = with types; nullOr (enum [ "nvidia" "amd" "intel" "hybrid-nvidia" "hybrid-amd" ]);
default = null; default = null;
description = '' description = ''
The manifaturer/type of the primary system GPU. The manifaturer/type of the primary system GPU.
Allows the correct GPU drivers to be loaded, potentially optimizing video output performance. Allows the correct GPU drivers to be loaded, potentially optimizing video output performance.
If you're on a hybrid system (intel/amd igpu + nvidia/amd dgpu) make sure to use
the hybrid options, only specifying the dgpu will not work properly.
Note that if using hybrid-nvidia, you will need to set `hardware.nvidia.prime.nvidiaBusId`
and `intelBusId` (or `amdgpuBusId`) to "PCI:x:y:z". To find the correct bus IDs, you can
use `sudo lshw -c display`. Note that you will need to convert the bus ID format from
hexadecimal to decimal, remove the padding (leading zeroes) and replace the dot with a
colon (so for example 0e:00.0 -> PCI:14:0:0).
''; '';
}; };

View file

@ -1,29 +1,36 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
dev = config.myOptions.device; dev = config.myOptions.device;
isWayland = config.myOptions.home-manager.wms.isWayland;
inherit (lib) mkIf mkDefault mkMerge;
in in
{ {
config = lib.mkIf (dev.gpu.type == "nvidia") { config = mkIf (builtins.elem dev.gpu.type ["nvidia" "hybrid-nvidia"]) {
# Nvidia drivers are unfree software # Nvidia drivers are unfree software
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
# Enable nvidia driver for Xorg and Wayland # Enable nvidia driver for Xorg and Wayland
services.xserver.videoDrivers = ["nvidia"]; services.xserver.videoDrivers = ["nvidia"];
# blacklist nouveau module so that it does not conflict with nvidia drm stuff
# also the nouveau performance is horrible in comparison.
boot.blacklistedKernelModules = ["nouveau"];
hardware = { hardware = {
nvidia = { nvidia = {
# modeestting is required # modeestting is required
modesetting.enable = lib.mkDefault true; modesetting.enable = mkDefault true;
# Nvidia power managerment. Experimental, and can cause sleep/suspend to fail. # Nvidia power managerment. Experimental, and can cause sleep/suspend to fail.
# Enable this if you have graphical corruption issues or application crashes after waking # Enable this if you have graphical corruption issues or application crashes after waking
# up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead of just # up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead of just
# the bare essentials # the bare essentials
powerManagement.enable = lib.mkDefault true; powerManagement.enable = mkDefault true;
# Fine-grained power management. Turns off GPU when not in use. # Fine-grained power management. Turns off GPU when not in use.
# Experimental and only works on modern Nvidia GPUs (Turing or newer) # Experimental and only works on modern Nvidia GPUs (Turing or newer)
powerManagement.finegrained = lib.mkDefault false; powerManagement.finegrained = mkDefault false;
# Use the NVidia open source kernel module (not to be confused with the # Use the NVidia open source kernel module (not to be confused with the
# independent third-party "nouveau" open source driver). # independent third-party "nouveau" open source driver).
@ -32,14 +39,27 @@ in
# #
# Enable this by default, hosts may override this option if their gpu is not # Enable this by default, hosts may override this option if their gpu is not
# supported by the open source drivers # supported by the open source drivers
open = lib.mkDefault true; open = mkDefault true;
# Add the Nvidia settings package, accessible via `nvidia-settings`. # Add the Nvidia settings package, accessible via `nvidia-settings`.
# (useless on NixOS) # (useless on NixOS)
nvidiaSettings = false; nvidiaSettings = mkDefault false;
# This ensures all GPUs stay awake even during headless mode. # This ensures all GPUs stay awake even during headless mode.
nvidiaPersistenced = true; nvidiaPersistenced = true;
# On Hybrid setups, using Nvidia Optimus PRIME is necessary
#
# There are various options/modes prime can work in, this will default to
# using the offload mode, which will default to running everything on igpu
# except apps that run with certain environmental variables set. To simplify
# things, this will also enable the `nvidia-offload` wrapper script/command.
prime.offload = let
isHybrid = dev.gpu.type == "hybrid-nvidia";
in {
enable = isHybrid;
enableOffloadCmd = isHybrid;
};
}; };
# Enable OpenGL # Enable OpenGL
@ -52,10 +72,6 @@ in
}; };
}; };
# blacklist nouveau module so that it does not conflict with nvidia drm stuff
# also the nouveau performance is horrible in comparison.
boot.blacklistedKernelModules = ["nouveau"];
environment = { environment = {
systemPackages = with pkgs; [ systemPackages = with pkgs; [
mesa mesa
@ -67,12 +83,24 @@ in
libva libva
libva-utils libva-utils
glxinfo
]; ];
sessionVariables = { sessionVariables = mkMerge [
LIBVA_DRIVER_NAME = "nvidia"; { LIBVA_DRIVER_NAME = "nvidia"; }
(mkIf isWayland {
WLR_NO_HARDWARE_CURSORS = "1"; WLR_NO_HARDWARE_CURSORS = "1";
}; })
# Run the compositor itself with nvidia GPU?
# Currently disabled
(mkIf (isWayland && (dev.gpu == "hybrid-nvidia")) {
#__NV_PRIME_RENDER_OFFLOAD = "1";
#WLR_DRM_DEVICES = mkDefault "/dev/dri/card1:/dev/dri/card0";
})
];
}; };
}; };
} }