Difference between revisions of "Nvidia"

From NixOS Wiki
Jump to: navigation, search
m (Add missing colon)
m (rollback unauthorized mass edits)
Tag: Rollback
(33 intermediate revisions by 18 users not shown)
Line 1: Line 1:
= Installing NVIDIA official drivers on NixOS =
+
= NixOS Manual =
If you're using NixOS, installing and using the official NVIDIA drivers is as simple as,
+
First check out the [https://nixos.org/manual/nixos/stable/#sec-x11-graphics-cards-nvidia method] in the NixOS Manual.
 +
 
 +
= Installing Nvidia Drivers on NixOS =
 +
 
 +
NixOS uses a functional package management approach, which necessitates specific procedures for driver installation. When considering NVIDIA GPU drivers in a Linux environment, the installation process can be more complex compared to AMD and Intel. This complexity arises primarily because NVIDIA's official drivers are closed source and not typically bundled with many distributions. This document outlines the technical steps required to install NVIDIA GPU drivers on NixOS, factoring in both the unique nature of NixOS and the proprietary status of NVIDIA's drivers.
 +
 
 +
== Enable Unfree Software Repositories ==
 +
 
 +
Make sure to allow Unfree Software. The unfree NVIDIA packages include <code>nvidia-x11</code>, <code>nvidia-settings</code>, and <code>nvidia-persistenced</code>.
 +
 
 +
== Determining the Correct Driver Version ==
 +
 
 +
You will next need to determine the appropriate driver version for your card. The following options are available:
 +
 
 +
<syntaxhighlight lang="nix">
 +
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.stable;
 +
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.beta;
 +
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.production;  # (installs 550)
 +
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.vulkan_beta;
 +
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
 +
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_390;
 +
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_340;
 +
</syntaxhighlight>
 +
 
 +
Out of the above, `stable` and `beta` will work for the latest RTX cards and some lower cards so long as they're not considered "legacy" by Nvidia. For "legacy" cards, you can consult the [https://www.nvidia.com/en-us/drivers/unix/legacy-gpu/ Nvidia official legacy driver list] and check whether your device is supported by the 470, 390 or 340 branches. If so, you can use the corresponding <code>legacy_470</code>, <code>legacy_390</code> or <code>legacy_340</code> driver. For a full list of options, consult the [https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/os-specific/linux/nvidia-x11/default.nix nvidia-x11 module repository].
 +
 
 +
{{note|As of early March 2024 the <code>production</code> driver has been updated from <code>535</code> to <code>550</code>. This is a breaking change for some people, especially those on Wayland.
 +
To resolve this follow the steps under [https://nixos.wiki/wiki/Nvidia#Running_the_new_RTX_SUPER_on_nixos_stable Running the new RTX SUPER on nixos stable]}}
 +
 
 +
Once you've determined the correct driver version, note it down; you'll need it in the next step.
 +
 
 +
== Modifying NixOS Configuration ==
 +
 
 +
Ensure that the following is in your NixOS configuration file (customizing as you prefer):
 +
 
 +
{{warning|If you are using a laptop, the below configuration update is not sufficient to get your Nvidia card running! Once you've entered it, please continue reading, as there are important adjustments that must then be made to the configuration''' before your laptop graphics will work properly.}}
 +
 
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{ config, lib, pkgs, ... }:
 
{ config, lib, pkgs, ... }:
 
{
 
{
  
   # Make sure opengl is enabled
+
   # Enable OpenGL
 
   hardware.opengl = {
 
   hardware.opengl = {
 
     enable = true;
 
     enable = true;
Line 12: Line 48:
 
   };
 
   };
  
   # NVIDIA drivers are unfree.
+
   # Load nvidia driver for Xorg and Wayland
  nixpkgs.config.allowUnfreePredicate = pkg:
 
    builtins.elem (lib.getName pkg) [
 
      "nvidia-x11"
 
    ];
 
 
 
  # Tell Xorg to use the nvidia driver
 
 
   services.xserver.videoDrivers = ["nvidia"];
 
   services.xserver.videoDrivers = ["nvidia"];
  
 
   hardware.nvidia = {
 
   hardware.nvidia = {
  
     # Modesetting is needed for most wayland compositors
+
     # Modesetting is required.
 
     modesetting.enable = true;
 
     modesetting.enable = true;
  
     # Use the open source version of the kernel module
+
    # Nvidia power management. Experimental, and can cause sleep/suspend to fail.
     # Only available on driver 515.43.04+
+
    # Enable this if you have graphical corruption issues or application crashes after waking
     open = true;
+
    # up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
 +
    # of just the bare essentials.
 +
    powerManagement.enable = false;
 +
 
 +
    # Fine-grained power management. Turns off GPU when not in use.
 +
    # Experimental and only works on modern Nvidia GPUs (Turing or newer).
 +
    powerManagement.finegrained = false;
 +
 
 +
     # Use the NVidia open source kernel module (not to be confused with the
 +
    # independent third-party "nouveau" open source driver).
 +
    # Support is limited to the Turing and later architectures. Full list of  
 +
    # supported GPUs is at:
 +
    # https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus
 +
     # Only available from driver 515.43.04+
 +
    # Currently alpha-quality/buggy, so false is currently the recommended setting.
 +
     open = false;
  
     # Enable the nvidia settings menu
+
     # Enable the Nvidia settings menu,
 +
# accessible via `nvidia-settings`.
 
     nvidiaSettings = true;
 
     nvidiaSettings = true;
  
Line 40: Line 86:
 
</nowiki>}}
 
</nowiki>}}
  
As noted in the final comment, you'll need to determine the appropriate driver version for your card. For "legacy" cards, you can consult [https://www.nvidia.com/en-us/drivers/unix/legacy-gpu/ nvidia official legacy driver list]. You can consult the set of possible options in the source [https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/os-specific/linux/nvidia-x11/default.nix here].
+
== Laptop Configuration: Hybrid Graphics (Nvidia Optimus PRIME) ==
  
(The <code>services.xserver.videoDrivers</code> setting is also valid for wayland installations despite it's name.)
+
In order to correctly finish configuring your Nvidia graphics driver, you must follow the below steps, which differ depending on whether or not you are using a hybrid graphics setup or not. A laptop with hybrid graphics possesses both an integrated GPU (often from the central processor) and a discrete, more powerful Nvidia GPU, typically for performance-intensive tasks. This dual-GPU setup allows for power-saving during basic tasks and higher graphics performance when needed.
  
= Using GPUs on non-NixOS =
+
'''Nvidia Optimus PRIME''' is a technology developed by Nvidia to optimize the power consumption and performance of laptops equipped with their GPUs. It seamlessly switches between the integrated graphics, usually from Intel, for lightweight tasks to save power, and the discrete Nvidia GPU for performance-intensive tasks like gaming or video editing. By dynamically balancing graphics power and battery life, Optimus provides the best of both worlds, ensuring that users get longer battery life without sacrificing graphical performance.
If you're using Nix-packaged software on a non-NixOS system, you'll need a workaround to get everything up-and-running. The [https://github.com/guibou/nixGL nixGL project] provides wrapper to use GL drivers on non-NixOS systems. You need to have GPU drivers installed on your distro (for kernel modules). With nixGL installed, you'll run <code>nixGL foobar</code> instead of <code>foobar</code>.
 
  
Note that nixGL is not specific to NVIDIA GPUs, and should work with just about any GPU.
+
=== Configuring Optimus PRIME: Bus ID Values (Mandatory) ===
  
= CUDA and using your GPU for compute =
+
Before we can continue, we must mandatorily first determine the Bus ID values for both your Nvidia and Intel GPUs. This step will be essential regardless of which configuration you later adopt.
See the [[CUDA]] wiki page!
 
  
= Using your GPU for graphics =
+
First, install the <code>lshw</code> package in order to be able to use the <code>lshw</code> command, then run:
Please note that, if you are setting up PRIME offloading, you '''must''' set the single value of "nvidia" even though it would be more conceptually correct to also include the driver for your other GPU. Doing otherwise will cause a broken xorg.conf to be generated. This is because NixOS doesn't ''actually'' handle multiple GPUs / GPU drivers properly, as per https://github.com/NixOS/nixpkgs/issues/108018.
 
  
== Determining the type of your GPU ==
+
<code>sudo lshw -c display</code>
  
* MXM / output-providing card (shows as <code>VGA Controller</code> in <code>lspci</code>), i.e. graphics card in desktop computer or in some laptops
+
You will likely get something like this:
* muxless/non-MXM Optimus cards have no display outputs and show as <code>3D Controller</code> in <code>lspci</code> output, seen in most modern consumer laptops
 
  
MXM cards allow you to use the Nvidia card standalone, in Non-Optimus mode. Non-MXM cards ''require'' [https://en.wikipedia.org/wiki/Nvidia_Optimus Optimus], Nvidia's integrated-vs-discrete GPU switching technology.
+
<syntaxhighlight lang="bash">
 +
*-display               
 +
description: i915drmfb
 +
physical id: 0
 +
bus info: pci@0000:0e:00.0
 +
logical name: /dev/fb0
 +
version: a1
 +
width: 64 bits
 +
clock: 33MHz
 +
capabilities: pm msi pciexpress bus_master cap_list rom fb
 +
configuration: depth=32 driver=nvidia latency=0 mode=2560x1600 visual=truecolor xres=2560 yres=1600
 +
resources: iomemory:600-5ff iomemory:620-61f irq:220 memory:85000000-85ffffff memory:6000000000-61ffffffff memory:6200000000-6201ffffff ioport:5000(size=128) memory:86000000-8607ffff
  
== Non-Optimus mode ==
+
*-display
 +
product: i915drmfb
 +
physical id: 2
 +
bus info: pci@0000:00:02.0
 +
logical name: /dev/fb0
 +
version: 04
 +
width: 64 bits
 +
clock: 33MHz
 +
capabilities: pciexpress msi pm bus_master cap_list rom fb
 +
configuration: depth=32 driver=i915 latency=0 resolution=2560,1600
 +
resources: iomemory:620-61f iomemory:400-3ff irq:221 memory:622e000000-622effffff memory:4000000000-400fffffff ioport:6000(size=64) memory:c0000-dffff memory:4010000000-4016ffffff memory:4020000000-40ffffffff
 +
</syntaxhighlight>
  
'''You need an MXM card''' (see above) for Non-Optimus mode. Follow [https://nixos.org/nixos/manual/#sec-x11-graphics-cards-nvidia NVIDIA Graphics Cards] section in official manual.  
+
Note the two values under "bus info" above, which may differ from laptop to laptop. Our Nvidia Bus ID is <code>0e:00.0</code> and our Intel Bus ID is <code>00:02.0</code>. Watch out for the formatting; convert them from hexadecimal to decimal, remove the padding (leading zeroes), replace the dot with a colon, then add them like this:
  
In case of laptop you may also need to use a BIOS option to select which card to use for the internal display.
+
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
+
{
== Optimus ==
+
hardware.nvidia.prime = {
 
+
# Make sure to use the correct Bus ID values for your system!
'''Mostly useful for laptops'''. There are currently two solutions available under NixOS, described in detail below:
+
intelBusId = "PCI:0:2:0";
 
+
nvidiaBusId = "PCI:14:0:0";
* Official solution: Nvidia PRIME (in on-demand "offload" mode, and always-on "sync" mode)
+
};
* Previous open-source solution: Bumblebee (now deprecated)
+
}
 
+
</nowiki>}}
=== Nvidia PRIME ===
 
 
 
The Official solution by nvidia.
 
  
==== offload mode ====
+
=== Optimus PRIME Option A: Offload Mode ===
  
'''Available since 20.09''' (see [https://github.com/NixOS/nixpkgs/pull/66601 #66601]).
+
''Offload Mode is available in NixOS 20.09 and higher, and requires an Nvidia card of the Turing generation or newer, and an Intel chipset from the Coffee Lake generation or newer.''
  
In this mode the Nvidia card is only activated on demand, however a Nvidia card of the Turing generation or newer and an Intel Coffee Lake chipset is required for a complete poweroff of the Nvidia card (see [https://discourse.nixos.org/t/how-to-use-nvidia-prime-offload-to-run-the-x-server-on-the-integrated-board/9091/19?u=moritzschaefer discussion]).
+
Offload mode puts your Nvidia GPU to sleep and lets the Intel GPU handle all tasks, except if you call the Nvidia GPU specifically by "offloading" an application to it. For example, you can run your laptop normally and it will use the energy-efficient Intel GPU all day, and then you can offload a game from Steam onto the Nvidia GPU to make the Nvidia GPU run that game only. For many, this is the most desirable option.
  
Offload mode is enabled by running your program(s) with specific environment variables, i.e., here's a sample script called <code>nvidia-offload</code> that you can run wrapped around your exacutable, for example <code>nvidia-offload glxgears</code>:
+
Offload mode is enabled by running your programs with specific environment variables. Here's a sample script called <code>nvidia-offload</code> that you can run wrapped around your executable, for example <code>nvidia-offload glxgears</code>:
  
 
{{file|nvidia-offload|bash|<nowiki>
 
{{file|nvidia-offload|bash|<nowiki>
Line 94: Line 155:
 
exec "$@"
 
exec "$@"
 
</nowiki>}}
 
</nowiki>}}
 +
 +
To enable offload mode, finish configuring your Nvidia driver by adding the following to your NixOS configuration file:
  
To configure Offload mode, you firstly you need to enable the proprietary Nvidia driver:
 
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{
 
{
  services.xserver.videoDrivers = [ "nvidia" ];
+
hardware.nvidia.prime = {
  ...
+
offload = {
 +
enable = true;
 +
enableOffloadCmd = true;
 +
};
 +
# Make sure to use the correct Bus ID values for your system!
 +
intelBusId = "PCI:0:2:0";
 +
nvidiaBusId = "PCI:14:0:0";
 +
};
 +
}
 
</nowiki>}}
 
</nowiki>}}
 
Note that on '''certain laptops''' and/or if you are using a custom kernel version, you may have issues with your NixOS system finding the primary display. In this case you should use <code>hardware.nvidia.modesetting.enable</code>, i.e.:
 
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
 
{
 
  hardware.nvidia.modesetting.enable = true;
 
  services.xserver.videoDrivers = [ "nvidia" ];
 
  // ...
 
</nowiki>}}
 
 
Then you need to setup the Bus ID's of the cards as seen below.
 
  
''Note: Bus ID is important and needs to be formatted properly''
+
=== Optimus PRIME Option B: Sync Mode ===
  
The Nvidia driver expects the bus ID to be in decimal format;
+
Enabling PRIME sync introduces better performance and greatly reduces screen tearing, at the expense of higher power consumption since the Nvidia GPU will not go to sleep completely unless called for, as is the case in Offload Mode. It may also cause its own issues in rare cases. '''PRIME Sync and Offload Mode cannot be enabled at the same time.'''
There are two ways you can get the bus IDs, one is with <nowiki>lspci</nowiki>, which shows the bus IDs in hexadecimal format and the other with <nowiki>lshw</nowiki>, which shows it in decimal format, as wanted by nixos.
 
  
===== lspci =====
+
PRIME sync may also solve some issues with connecting a display in clamshell mode directly to the GPU.
  
You can convert the value by:
+
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 +
{
 +
  hardware.nvidia.prime = {
 +
    sync.enable = true;
  
* Stripping any leading zeros from the bus numbers or if the number is above 09, convert it to decimal and use that value.
+
    # Make sure to use the correct Bus ID values for your system!
* Replacing any full stops with colons.
+
    nvidiaBusId = "PCI:14:0:0";
* Prefix the final value with "PCI".
+
    intelBusId = "PCI:0:2:0";
 +
  };
 +
}
 +
</nowiki>}}
  
For example:
+
=== Optimus Option C: Reverse Sync Mode (Experimental) ===
  
'''Output from lspci'''
+
This feature is relatively new and may not work properly on all systems ([https://forums.developer.nvidia.com/t/the-all-new-outputsink-feature-aka-reverse-prime/129828 see discussion]). It is also only available on driver 460.39 or newer. Reverse sync also only works with <code>services.xserver.displayManager.setupCommands</code> compatible Display Managers (LightDM, GDM and SDDM).
  
<code>09:1f.0 VGA compatible controller: NVIDIA Corporation Device 1f91 (rev a1)</code>
+
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 +
{
 +
  hardware.nvidia.prime = {
 +
    reverseSync.enable = true;
 +
    # Enable if using an external GPU
 +
    allowExternalGpu = false;
  
'''Converted and correct format'''
+
    # Make sure to use the correct Bus ID values for your system!
 +
    intelBusId = "PCI:0:2:0";
 +
    nvidiaBusId = "PCI:14:0:0";
 +
  };
 +
}
 +
</nowiki>}}
  
<code>PCI:9:31:0</code>
+
== Useful Tips ==
  
===== lshw =====
+
=== Check NixosHardware ===
 +
You should check the  [https://github.com/NixOS/nixos-hardware nixoshardware] GitHub repository. It is possible that someone already wrote a hardware configuration for your device and that usually takes care of drivers. If so, follow the upstream documentation to enable the required modules. 
  
If you don't have <nowiki>lshw</nowiki> installed, you can get it temporarily in a ephemeral shell by running:
+
=== Multiple Boot Configurations ===
 +
Imagine you have a laptop that you mostly use in clamshell mode (docked, connected to an external display and plugged into a charger) but that you sometimes use on the go.
  
<code>nix-shell -p lshw --run "lshw -c display"</code>
+
In clamshell mode, using PRIME Sync is likely to lead to better performance, external display support, etc., at the cost of potentially (but not always) lower battery life. However, when using the laptop on the go, you may prefer to use offload mode.
  
The two bus ID's will be in the corresponding "bus info" field.  
+
NixOS supports "specialisations", which allow you to automatically generate different boot profiles when rebuilding your system. We can, for example, enable PRIME sync by default, but also create a "on-the-go" specialization that disables PRIME sync and instead enables offload mode:
 
 
For example:
 
 
 
<code>
 
bus info: pci@0000:01:00.0
 
</code>
 
 
 
and
 
 
 
<code>
 
bus info: pci@0000:00:02.0
 
</code>
 
 
 
Now you have to take everything after the first colon, and replace the <code>.</code> with another colon.
 
 
 
<code>
 
01:00:0
 
</code>
 
 
 
and  
 
 
 
<code>
 
00:02:0
 
</code>
 
 
 
A possible configuration:
 
  
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{
 
{
  services.xserver.videoDrivers = ["nvidia"];
 
  
   hardware.nvidia.prime = {
+
specialisation = {
     offload = {
+
   on-the-go.configuration = {
       enable = true;
+
    system.nixos.tags = [ "on-the-go" ];
       enableOffloadCmd = true;
+
     hardware.nvidia = {
 +
       prime.offload.enable = lib.mkForce true;
 +
       prime.offload.enableOffloadCmd = lib.mkForce true;
 +
      prime.sync.enable = lib.mkForce false;
 
     };
 
     };
 +
  };
 +
};
  
    intelBusId = "PCI:0:2:0";
 
    nvidiaBusId = "PCI:1:0:0";
 
  };
 
 
}
 
}
 
</nowiki>}}
 
</nowiki>}}
  
==== booting with an external display ====
+
(You can also add other settings here totally unrelated to Nvidia, such as power profiles, etc.)
  
Most Optimus laptops have the HDMI port for an external display wired directly to the Nvidia chip, in which case you need a configuration to use the Nvidia driver directly without offload mode. Fortunately, NixOS has an amazing feature called specialisations which allows you to do this easily. Here is an example configuration:
+
After rebuilding and rebooting, you'll see in your boot menu under each Generation an "on-the-go" option, which will let you boot into the on-to-go specialisation for that generation.
  
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
+
=== Using GPUs on non-NixOS ===
  specialisation = {
+
If you're using Nix-packaged software on a non-NixOS system, you'll need a workaround to get everything up-and-running. The [https://github.com/guibou/nixGL nixGL project] provides wrapper to use GL drivers on non-NixOS systems. You need to have GPU drivers installed on your distro (for kernel modules). With nixGL installed, you'll run <code>nixGL foobar</code> instead of  <code>foobar</code>.
    external-display.configuration = {
 
      system.nixos.tags = [ "external-display" ];
 
      hardware.nvidia = {
 
        prime.offload.enable = lib.mkForce false;
 
        powerManagement.enable = lib.mkForce false;
 
      };
 
    };
 
  };
 
</nowiki>}}
 
 
 
Once you rebuild your configuration, an extra <code>external-display</code> configuration will be built and placed in your boot menu.
 
 
 
To use this, boot your laptop with the lid open, choose the <code>external-display</code> configuration in the boot menu, and continue to keep the lid open until your desktop appears on the external display. At this point you can close the lid.
 
  
==== offloading steam ====
+
Note that nixGL is not specific to Nvidia GPUs, and should work with just about any GPU.
  
First, add this to your <code>~/.bashrc</code> :
+
=== CUDA and using your GPU for compute ===
 +
See the [[CUDA]] wiki page.
  
 +
=== Using Steam in Offload Mode ===
 +
In order to automatically launch Steam in offload mode, you need to add the following to your <code>~/.bashrc</code>:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
export XDG_DATA_HOME="$HOME/.local/share"
 
export XDG_DATA_HOME="$HOME/.local/share"
 
</syntaxhighlight>     
 
</syntaxhighlight>     
.
 
  
For NixOS Steam run:
+
Then, if you are using NixOS Steam, run:
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Line 222: Line 261:
 
sed 's/^Exec=/&nvidia-offload /' /run/current-system/sw/share/applications/steam.desktop > ~/.local/share/applications/steam.desktop
 
sed 's/^Exec=/&nvidia-offload /' /run/current-system/sw/share/applications/steam.desktop > ~/.local/share/applications/steam.desktop
 
</syntaxhighlight>
 
</syntaxhighlight>
.
 
  
For Flatpak Steam run:
+
For Flatpak Steam, run:
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Line 230: Line 268:
 
sed 's/^Exec=/&nvidia-offload /' /var/lib/flatpak/exports/share/applications/com.valvesoftware.Steam.desktop > ~/.local/share/applications/com.valvesoftware.steam.desktop
 
sed 's/^Exec=/&nvidia-offload /' /var/lib/flatpak/exports/share/applications/com.valvesoftware.Steam.desktop > ~/.local/share/applications/com.valvesoftware.steam.desktop
 
</syntaxhighlight>
 
</syntaxhighlight>
.
 
  
Then restart your graphical environment session.
+
Then restart your graphical environment session (or simply reboot).
  
==== sync mode ====
+
=== Running the new RTX SUPER on nixos stable ===
  
In this mode the Nvidia card is turned on constantly, having impact on laptop battery and health.
+
The new RTX Super are not supported by the 545 driver. On Nixos stable, you want to use the 535 driver that come from unstable branch or the 550 (beta).
 +
To do that you need to manually call the driver you want in your config.
 +
Check on this link to choose the driver you want and change your config accordingly :
 +
https://github.com/NixOS/nixpkgs/blob/979a311fbd179b86200e412a3ed266b64808df4e/pkgs/os-specific/linux/nvidia-x11/default.nix#L36
  
Possible issues:
+
{{file|/etc/nixos/nvidia.nix|nix|<nowiki>
* Hangs of applications after resume from suspend
+
{ pkgs, config, libs, ... }:
* Wrong DPI calculation (in this case provide dpi manually <code>services.xserver.dpi = 96;</code>)
 
* Black screen after system upgrade (e.g. <code>nixos-rebuild switch</code>; use <code>nixos-rebuild boot</code> instead and reboot)
 
* No video playback acceleration available (vaapi)
 
  
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
 
{
 
{
  hardware.nvidia.modesetting.enable = true;
 
  services.xserver.videoDrivers = [ "nvidia" ];
 
  hardware.nvidia.prime = {
 
    sync.enable = true;
 
  
     nvidiaBusId = "PCI:1:0:0";
+
# Enable OpenGL
     intelBusId = "PCI:0:2:0";
+
  hardware.opengl = {
 +
    enable = true;
 +
     driSupport = true;
 +
     driSupport32Bit = true;
 
   };
 
   };
}
 
</nowiki>}}
 
  
==== reverse sync mode ====
+
# Load nvidia driver for Xorg and Wayland
Warning: This feature is relatively new, depending on your system this might work poorly. AMD support, especially so. See: https://forums.developer.nvidia.com/t/the-all-new-outputsink-feature-aka-reverse-prime/129828
 
 
 
Only works with <code>services.xserver.displayManager.setupCommands</code> compatible Display Managers (LightDM, GDM and SDDM).
 
 
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{
 
 
   services.xserver.videoDrivers = ["nvidia"];
 
   services.xserver.videoDrivers = ["nvidia"];
 +
 
 +
  hardware.nvidia.modesetting.enable = true;
 +
  hardware.nvidia.powerManagement.enable = false;
 +
  hardware.nvidia.powerManagement.finegrained = false;
 +
  hardware.nvidia.open = false;
 +
  hardware.nvidia.nvidiaSettings = true;
 +
# Special config to load the latest (535 or 550) driver for the support of the 4070 SUPER
 +
  hardware.nvidia.package = let
 +
  rcu_patch = pkgs.fetchpatch {
 +
    url = "https://github.com/gentoo/gentoo/raw/c64caf53/x11-drivers/nvidia-drivers/files/nvidia-drivers-470.223.02-gpl-pfn_valid.patch";
 +
    hash = "sha256-eZiQQp2S/asE7MfGvfe6dA/kdCvek9SYa/FFGp24dVg=";
 +
  };
 +
in config.boot.kernelPackages.nvidiaPackages.mkDriver {
 +
    version = "535.154.05";
 +
    sha256_64bit = "sha256-fpUGXKprgt6SYRDxSCemGXLrEsIA6GOinp+0eGbqqJg=";
 +
    sha256_aarch64 = "sha256-G0/GiObf/BZMkzzET8HQjdIcvCSqB1uhsinro2HLK9k=";
 +
    openSha256 = "sha256-wvRdHguGLxS0mR06P5Qi++pDJBCF8pJ8hr4T8O6TJIo=";
 +
    settingsSha256 = "sha256-9wqoDEWY4I7weWW05F4igj1Gj9wjHsREFMztfEmqm10=";
 +
    persistencedSha256 = "sha256-d0Q3Lk80JqkS1B54Mahu2yY/WocOqFFbZVBh+ToGhaE=";
  
  hardware.nvidia = {
+
    #version = "550.40.07";
     # Modesetting should be enabled to prevent screen tearing
+
    #sha256_64bit = "sha256-KYk2xye37v7ZW7h+uNJM/u8fNf7KyGTZjiaU03dJpK0=";
     modesetting.enable = true;
+
     #sha256_aarch64 = "sha256-AV7KgRXYaQGBFl7zuRcfnTGr8rS5n13nGUIe3mJTXb4=";
 +
     #openSha256 = "sha256-mRUTEWVsbjq+psVe+kAT6MjyZuLkG2yRDxCMvDJRL1I=";
 +
    #settingsSha256 = "sha256-c30AQa4g4a1EHmaEu1yc05oqY01y+IusbBuq+P6rMCs=";
 +
    #persistencedSha256 = "sha256-11tLSY8uUIl4X/roNnxf5yS2PQvHvoNjnd2CB67e870=";
  
     # Reverse sync is not compatible with the open source kernel module
+
     patches = [ rcu_patch ];
    open = false;
+
};
 
 
    prime = {
 
      reverseSync.enable = true;
 
 
 
      #enable if using an external GPU
 
      allowExternalGpu = false;
 
 
 
      intelBusId = "PCI:0:2:0";
 
 
 
      nvidiaBusId = "PCI:1:0:0";
 
    };
 
  };
 
 
}
 
}
 
</nowiki>}}
 
</nowiki>}}
  
=== Bumblebee ===
+
== Troubleshooting ==
  
Deprecated solution. You should use [[Nvidia#offload_mode|offload mode]] instead.
+
=== Booting to Text Mode ===
 +
If you encounter the problem of booting to text mode you might try adding the Nvidia kernel module manually with:
  
Use option <syntaxHighlight lang="nix">hardware.bumblebee.enable = true;</syntaxHighlight>
 
 
 
== Troubleshooting ==
 
===Booting to Terminal===
 
If you encounter the Problem of booting to The Terminal you might try adding the nvidia kernel modul manually with:
 
 
<syntaxHighlight lang="nix">
 
<syntaxHighlight lang="nix">
 
boot.initrd.kernelModules = [ "nvidia" ];
 
boot.initrd.kernelModules = [ "nvidia" ];
Line 302: Line 334:
 
</syntaxHighlight>
 
</syntaxHighlight>
  
=== Fix screen tearing ===
+
=== Screen Tearing Issues ===
You may often incounter screen tearing or artifacts when using proprietary Nvidia drivers. You can fix that by forcing full composition pipeline.
+
 
{{note|This has been reported to reduce the performance of some OpenGL applications and may produce issues in WebGL. It also drastically increases the time the driver needs to clock down after load.}}
+
First, try to switch to PRIME Sync Mode, as described above. If that doesn't work, try forcing a composition pipeline.
 +
 
 +
{{note|Forcing a full composition pipeline has been reported to reduce the performance of some OpenGL applications and may produce issues in WebGL. It also drastically increases the time the driver needs to clock down after load.}}
 +
 
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
hardware.nvidia.forceFullCompositionPipeline = true;
 
hardware.nvidia.forceFullCompositionPipeline = true;
 
</nowiki>}}
 
</nowiki>}}
  
=== Fix app flickering with Picom ===
+
=== Flickering Issues with Picom ===
 
{{file|~/.config/picom/picom.conf|conf|<nowiki>
 
{{file|~/.config/picom/picom.conf|conf|<nowiki>
 
unredir-if-possible = false;
 
unredir-if-possible = false;
Line 316: Line 351:
 
</nowiki>}}
 
</nowiki>}}
  
=== Fix graphical corruption on suspend/resume ===
+
=== Graphical Corruption and System Crashes on Suspend/Resume ===
By default only a small portion of VRAM is saved when suspending the system [https://download.nvidia.com/XFree86/Linux-x86_64/460.73.01/README/powermanagement.html]. This can cause graphical issues in some applications when resuming from suspend. To fix it, enable systemd-based suspend, which will save and restore all of VRAM:
+
<code>powerManagement.enable = true</code> can sometimes fix this, but is itself unstable and is known to cause suspend issues.
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
+
 
hardware.nvidia.powerManagement.enable = true;
 
</nowiki>}}
 
 
If you have a modern Nvidia GPU (Turing [https://en.wikipedia.org/wiki/Turing_(microarchitecture)#Products_using_Turing] or later), you may also want to investigate the <code>hardware.nvidia.powerManagement.finegrained</code> option: [https://download.nvidia.com/XFree86/Linux-x86_64/460.73.01/README/dynamicpowermanagement.html]
 
If you have a modern Nvidia GPU (Turing [https://en.wikipedia.org/wiki/Turing_(microarchitecture)#Products_using_Turing] or later), you may also want to investigate the <code>hardware.nvidia.powerManagement.finegrained</code> option: [https://download.nvidia.com/XFree86/Linux-x86_64/460.73.01/README/dynamicpowermanagement.html]
  
=== Fix black screen on a system with an integrated GPU ===
+
=== Black Screen or Nothing Works on Laptops ===
If you are using non-Optimus mode on a system with an integrated GPU, the kernel module <code>i915</code> for intel or <code>amdgpu</code> for AMD may interfere with the NVIDIA driver. This may result in a black screen when switching to the virtual terminal, or when exiting the X session. A possible workaround is to disable the integrated GPU by blacklisting the module, using the following configuration option (see also [https://discourse.nixos.org/t/nvidia-gpu-and-i915-kernel-module/21307/3]):
+
The kernel module <code>i915</code> for intel or <code>amdgpu</code> for AMD may interfere with the Nvidia driver. This may result in a black screen when switching to the virtual terminal, or when exiting the X session. A possible workaround is to disable the integrated GPU by blacklisting the module, using the following configuration option (see also [https://discourse.nixos.org/t/nvidia-gpu-and-i915-kernel-module/21307/3]):
  
 
<syntaxHighlight lang="nix">
 
<syntaxHighlight lang="nix">
Line 332: Line 365:
 
boot.kernelParams = [ "module_blacklist=amdgpu" ];
 
boot.kernelParams = [ "module_blacklist=amdgpu" ];
 
</syntaxHighlight>
 
</syntaxHighlight>
 +
 +
= Disable Nvidia dGPU completely =
 +
 +
completely disable dGPU, saving battery. Probably not all configurations and module blacklists are required but this worked successfully
 +
 +
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 +
boot.extraModprobeConfig = ''
 +
  blacklist nouveau
 +
  options nouveau modeset=0
 +
'';
 +
 
 +
services.udev.extraRules = ''
 +
  # Remove NVIDIA USB xHCI Host Controller devices, if present
 +
  ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c0330", ATTR{power/control}="auto", ATTR{remove}="1"
 +
  # Remove NVIDIA USB Type-C UCSI devices, if present
 +
  ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c8000", ATTR{power/control}="auto", ATTR{remove}="1"
 +
  # Remove NVIDIA Audio devices, if present
 +
  ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", ATTR{power/control}="auto", ATTR{remove}="1"
 +
  # Remove NVIDIA VGA/3D controller devices
 +
  ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x03[0-9]*", ATTR{power/control}="auto", ATTR{remove}="1"
 +
'';
 +
boot.blacklistedKernelModules = [ "nouveau" "nvidia" "nvidia_drm" "nvidia_modeset" ];
 +
</nowiki>}}
  
 
[[Category:Video]]
 
[[Category:Video]]

Revision as of 10:57, 6 April 2024

NixOS Manual

First check out the method in the NixOS Manual.

Installing Nvidia Drivers on NixOS

NixOS uses a functional package management approach, which necessitates specific procedures for driver installation. When considering NVIDIA GPU drivers in a Linux environment, the installation process can be more complex compared to AMD and Intel. This complexity arises primarily because NVIDIA's official drivers are closed source and not typically bundled with many distributions. This document outlines the technical steps required to install NVIDIA GPU drivers on NixOS, factoring in both the unique nature of NixOS and the proprietary status of NVIDIA's drivers.

Enable Unfree Software Repositories

Make sure to allow Unfree Software. The unfree NVIDIA packages include nvidia-x11, nvidia-settings, and nvidia-persistenced.

Determining the Correct Driver Version

You will next need to determine the appropriate driver version for your card. The following options are available:

hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.stable;
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.beta;
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.production;  # (installs 550)
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.vulkan_beta;
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_390;
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_340;

Out of the above, `stable` and `beta` will work for the latest RTX cards and some lower cards so long as they're not considered "legacy" by Nvidia. For "legacy" cards, you can consult the Nvidia official legacy driver list and check whether your device is supported by the 470, 390 or 340 branches. If so, you can use the corresponding legacy_470, legacy_390 or legacy_340 driver. For a full list of options, consult the nvidia-x11 module repository.

Note: As of early March 2024 the production driver has been updated from 535 to 550. This is a breaking change for some people, especially those on Wayland. To resolve this follow the steps under Running the new RTX SUPER on nixos stable

Once you've determined the correct driver version, note it down; you'll need it in the next step.

Modifying NixOS Configuration

Ensure that the following is in your NixOS configuration file (customizing as you prefer):

Warning: If you are using a laptop, the below configuration update is not sufficient to get your Nvidia card running! Once you've entered it, please continue reading, as there are important adjustments that must then be made to the configuration before your laptop graphics will work properly.
Breeze-text-x-plain.png
/etc/nixos/configuration.nix
{ config, lib, pkgs, ... }:
{

  # Enable OpenGL
  hardware.opengl = {
    enable = true;
    driSupport = true;
    driSupport32Bit = true;
  };

  # Load nvidia driver for Xorg and Wayland
  services.xserver.videoDrivers = ["nvidia"];

  hardware.nvidia = {

    # Modesetting is required.
    modesetting.enable = true;

    # Nvidia power management. Experimental, and can cause sleep/suspend to fail.
    # 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 the bare essentials.
    powerManagement.enable = false;

    # Fine-grained power management. Turns off GPU when not in use.
    # Experimental and only works on modern Nvidia GPUs (Turing or newer).
    powerManagement.finegrained = false;

    # Use the NVidia open source kernel module (not to be confused with the
    # independent third-party "nouveau" open source driver).
    # Support is limited to the Turing and later architectures. Full list of 
    # supported GPUs is at: 
    # https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus 
    # Only available from driver 515.43.04+
    # Currently alpha-quality/buggy, so false is currently the recommended setting.
    open = false;

    # Enable the Nvidia settings menu,
	# accessible via `nvidia-settings`.
    nvidiaSettings = true;

    # Optionally, you may need to select the appropriate driver version for your specific GPU.
    package = config.boot.kernelPackages.nvidiaPackages.stable;
  };
  ...
}


Laptop Configuration: Hybrid Graphics (Nvidia Optimus PRIME)

In order to correctly finish configuring your Nvidia graphics driver, you must follow the below steps, which differ depending on whether or not you are using a hybrid graphics setup or not. A laptop with hybrid graphics possesses both an integrated GPU (often from the central processor) and a discrete, more powerful Nvidia GPU, typically for performance-intensive tasks. This dual-GPU setup allows for power-saving during basic tasks and higher graphics performance when needed.

Nvidia Optimus PRIME is a technology developed by Nvidia to optimize the power consumption and performance of laptops equipped with their GPUs. It seamlessly switches between the integrated graphics, usually from Intel, for lightweight tasks to save power, and the discrete Nvidia GPU for performance-intensive tasks like gaming or video editing. By dynamically balancing graphics power and battery life, Optimus provides the best of both worlds, ensuring that users get longer battery life without sacrificing graphical performance.

Configuring Optimus PRIME: Bus ID Values (Mandatory)

Before we can continue, we must mandatorily first determine the Bus ID values for both your Nvidia and Intel GPUs. This step will be essential regardless of which configuration you later adopt.

First, install the lshw package in order to be able to use the lshw command, then run:

sudo lshw -c display

You will likely get something like this:

*-display                 
description: i915drmfb
physical id: 0
bus info: pci@0000:0e:00.0
logical name: /dev/fb0
version: a1
width: 64 bits
clock: 33MHz
capabilities: pm msi pciexpress bus_master cap_list rom fb
configuration: depth=32 driver=nvidia latency=0 mode=2560x1600 visual=truecolor xres=2560 yres=1600
resources: iomemory:600-5ff iomemory:620-61f irq:220 memory:85000000-85ffffff memory:6000000000-61ffffffff memory:6200000000-6201ffffff ioport:5000(size=128) memory:86000000-8607ffff

*-display
product: i915drmfb
physical id: 2
bus info: pci@0000:00:02.0
logical name: /dev/fb0
version: 04
width: 64 bits
clock: 33MHz
capabilities: pciexpress msi pm bus_master cap_list rom fb
configuration: depth=32 driver=i915 latency=0 resolution=2560,1600
resources: iomemory:620-61f iomemory:400-3ff irq:221 memory:622e000000-622effffff memory:4000000000-400fffffff ioport:6000(size=64) memory:c0000-dffff memory:4010000000-4016ffffff memory:4020000000-40ffffffff

Note the two values under "bus info" above, which may differ from laptop to laptop. Our Nvidia Bus ID is 0e:00.0 and our Intel Bus ID is 00:02.0. Watch out for the formatting; convert them from hexadecimal to decimal, remove the padding (leading zeroes), replace the dot with a colon, then add them like this:

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
{
	hardware.nvidia.prime = {
		# Make sure to use the correct Bus ID values for your system!
		intelBusId = "PCI:0:2:0";
		nvidiaBusId = "PCI:14:0:0";
	};
}


Optimus PRIME Option A: Offload Mode

Offload Mode is available in NixOS 20.09 and higher, and requires an Nvidia card of the Turing generation or newer, and an Intel chipset from the Coffee Lake generation or newer.

Offload mode puts your Nvidia GPU to sleep and lets the Intel GPU handle all tasks, except if you call the Nvidia GPU specifically by "offloading" an application to it. For example, you can run your laptop normally and it will use the energy-efficient Intel GPU all day, and then you can offload a game from Steam onto the Nvidia GPU to make the Nvidia GPU run that game only. For many, this is the most desirable option.

Offload mode is enabled by running your programs with specific environment variables. Here's a sample script called nvidia-offload that you can run wrapped around your executable, for example nvidia-offload glxgears:

Breeze-text-x-plain.png
nvidia-offload
export __NV_PRIME_RENDER_OFFLOAD=1
export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0
export __GLX_VENDOR_LIBRARY_NAME=nvidia
export __VK_LAYER_NV_optimus=NVIDIA_only
exec "$@"


To enable offload mode, finish configuring your Nvidia driver by adding the following to your NixOS configuration file:

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
{
	hardware.nvidia.prime = {
		offload = {
			enable = true;
			enableOffloadCmd = true;
		};
		# Make sure to use the correct Bus ID values for your system!
		intelBusId = "PCI:0:2:0";
		nvidiaBusId = "PCI:14:0:0";
	};
}


Optimus PRIME Option B: Sync Mode

Enabling PRIME sync introduces better performance and greatly reduces screen tearing, at the expense of higher power consumption since the Nvidia GPU will not go to sleep completely unless called for, as is the case in Offload Mode. It may also cause its own issues in rare cases. PRIME Sync and Offload Mode cannot be enabled at the same time.

PRIME sync may also solve some issues with connecting a display in clamshell mode directly to the GPU.

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
{
  hardware.nvidia.prime = {
    sync.enable = true;

    # Make sure to use the correct Bus ID values for your system!
    nvidiaBusId = "PCI:14:0:0";
    intelBusId = "PCI:0:2:0";
  };
}


Optimus Option C: Reverse Sync Mode (Experimental)

This feature is relatively new and may not work properly on all systems (see discussion). It is also only available on driver 460.39 or newer. Reverse sync also only works with services.xserver.displayManager.setupCommands compatible Display Managers (LightDM, GDM and SDDM).

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
{
  hardware.nvidia.prime = {
    reverseSync.enable = true;
    # Enable if using an external GPU
    allowExternalGpu = false;

    # Make sure to use the correct Bus ID values for your system!
    intelBusId = "PCI:0:2:0";
    nvidiaBusId = "PCI:14:0:0";
  };
}


Useful Tips

Check NixosHardware

You should check the nixoshardware GitHub repository. It is possible that someone already wrote a hardware configuration for your device and that usually takes care of drivers. If so, follow the upstream documentation to enable the required modules.

Multiple Boot Configurations

Imagine you have a laptop that you mostly use in clamshell mode (docked, connected to an external display and plugged into a charger) but that you sometimes use on the go.

In clamshell mode, using PRIME Sync is likely to lead to better performance, external display support, etc., at the cost of potentially (but not always) lower battery life. However, when using the laptop on the go, you may prefer to use offload mode.

NixOS supports "specialisations", which allow you to automatically generate different boot profiles when rebuilding your system. We can, for example, enable PRIME sync by default, but also create a "on-the-go" specialization that disables PRIME sync and instead enables offload mode:

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
{

specialisation = {
  on-the-go.configuration = {
    system.nixos.tags = [ "on-the-go" ];
    hardware.nvidia = {
      prime.offload.enable = lib.mkForce true;
      prime.offload.enableOffloadCmd = lib.mkForce true;
      prime.sync.enable = lib.mkForce false;
    };
  };
};

}


(You can also add other settings here totally unrelated to Nvidia, such as power profiles, etc.)

After rebuilding and rebooting, you'll see in your boot menu under each Generation an "on-the-go" option, which will let you boot into the on-to-go specialisation for that generation.

Using GPUs on non-NixOS

If you're using Nix-packaged software on a non-NixOS system, you'll need a workaround to get everything up-and-running. The nixGL project provides wrapper to use GL drivers on non-NixOS systems. You need to have GPU drivers installed on your distro (for kernel modules). With nixGL installed, you'll run nixGL foobar instead of foobar.

Note that nixGL is not specific to Nvidia GPUs, and should work with just about any GPU.

CUDA and using your GPU for compute

See the CUDA wiki page.

Using Steam in Offload Mode

In order to automatically launch Steam in offload mode, you need to add the following to your ~/.bashrc:

export XDG_DATA_HOME="$HOME/.local/share"

Then, if you are using NixOS Steam, run:

mkdir -p ~/.local/share/applications
sed 's/^Exec=/&nvidia-offload /' /run/current-system/sw/share/applications/steam.desktop > ~/.local/share/applications/steam.desktop

For Flatpak Steam, run:

mkdir -p ~/.local/share/applications
sed 's/^Exec=/&nvidia-offload /' /var/lib/flatpak/exports/share/applications/com.valvesoftware.Steam.desktop > ~/.local/share/applications/com.valvesoftware.steam.desktop

Then restart your graphical environment session (or simply reboot).

Running the new RTX SUPER on nixos stable

The new RTX Super are not supported by the 545 driver. On Nixos stable, you want to use the 535 driver that come from unstable branch or the 550 (beta). To do that you need to manually call the driver you want in your config. Check on this link to choose the driver you want and change your config accordingly : https://github.com/NixOS/nixpkgs/blob/979a311fbd179b86200e412a3ed266b64808df4e/pkgs/os-specific/linux/nvidia-x11/default.nix#L36

Breeze-text-x-plain.png
/etc/nixos/nvidia.nix
{ pkgs, config, libs, ... }:

{

# Enable OpenGL
  hardware.opengl = {
    enable = true;
    driSupport = true;
    driSupport32Bit = true;
  };

# Load nvidia driver for Xorg and Wayland
  services.xserver.videoDrivers = ["nvidia"];
  
  hardware.nvidia.modesetting.enable = true;
  hardware.nvidia.powerManagement.enable = false;
  hardware.nvidia.powerManagement.finegrained = false;
  hardware.nvidia.open = false;
  hardware.nvidia.nvidiaSettings = true;
# Special config to load the latest (535 or 550) driver for the support of the 4070 SUPER
  hardware.nvidia.package = let 
  rcu_patch = pkgs.fetchpatch {
    url = "https://github.com/gentoo/gentoo/raw/c64caf53/x11-drivers/nvidia-drivers/files/nvidia-drivers-470.223.02-gpl-pfn_valid.patch";
    hash = "sha256-eZiQQp2S/asE7MfGvfe6dA/kdCvek9SYa/FFGp24dVg=";
  };
in config.boot.kernelPackages.nvidiaPackages.mkDriver {
    version = "535.154.05";
    sha256_64bit = "sha256-fpUGXKprgt6SYRDxSCemGXLrEsIA6GOinp+0eGbqqJg=";
    sha256_aarch64 = "sha256-G0/GiObf/BZMkzzET8HQjdIcvCSqB1uhsinro2HLK9k=";
    openSha256 = "sha256-wvRdHguGLxS0mR06P5Qi++pDJBCF8pJ8hr4T8O6TJIo=";
    settingsSha256 = "sha256-9wqoDEWY4I7weWW05F4igj1Gj9wjHsREFMztfEmqm10=";
    persistencedSha256 = "sha256-d0Q3Lk80JqkS1B54Mahu2yY/WocOqFFbZVBh+ToGhaE=";

    #version = "550.40.07";
    #sha256_64bit = "sha256-KYk2xye37v7ZW7h+uNJM/u8fNf7KyGTZjiaU03dJpK0=";
    #sha256_aarch64 = "sha256-AV7KgRXYaQGBFl7zuRcfnTGr8rS5n13nGUIe3mJTXb4=";
    #openSha256 = "sha256-mRUTEWVsbjq+psVe+kAT6MjyZuLkG2yRDxCMvDJRL1I=";
    #settingsSha256 = "sha256-c30AQa4g4a1EHmaEu1yc05oqY01y+IusbBuq+P6rMCs=";
    #persistencedSha256 = "sha256-11tLSY8uUIl4X/roNnxf5yS2PQvHvoNjnd2CB67e870=";

    patches = [ rcu_patch ];
 };
}


Troubleshooting

Booting to Text Mode

If you encounter the problem of booting to text mode you might try adding the Nvidia kernel module manually with:

boot.initrd.kernelModules = [ "nvidia" ];
boot.extraModulePackages = [ config.boot.kernelPackages.nvidia_x11 ];

Screen Tearing Issues

First, try to switch to PRIME Sync Mode, as described above. If that doesn't work, try forcing a composition pipeline.

Note: Forcing a full composition pipeline has been reported to reduce the performance of some OpenGL applications and may produce issues in WebGL. It also drastically increases the time the driver needs to clock down after load.
Breeze-text-x-plain.png
/etc/nixos/configuration.nix
hardware.nvidia.forceFullCompositionPipeline = true;


Flickering Issues with Picom

Breeze-text-x-plain.png
~/.config/picom/picom.conf
unredir-if-possible = false;
backend = "xrender"; # try "glx" if xrender doesn't help
vsync = true;


Graphical Corruption and System Crashes on Suspend/Resume

powerManagement.enable = true can sometimes fix this, but is itself unstable and is known to cause suspend issues.

If you have a modern Nvidia GPU (Turing [1] or later), you may also want to investigate the hardware.nvidia.powerManagement.finegrained option: [2]

Black Screen or Nothing Works on Laptops

The kernel module i915 for intel or amdgpu for AMD may interfere with the Nvidia driver. This may result in a black screen when switching to the virtual terminal, or when exiting the X session. A possible workaround is to disable the integrated GPU by blacklisting the module, using the following configuration option (see also [3]):

# intel
boot.kernelParams = [ "module_blacklist=i915" ];
# AMD
boot.kernelParams = [ "module_blacklist=amdgpu" ];

Disable Nvidia dGPU completely

completely disable dGPU, saving battery. Probably not all configurations and module blacklists are required but this worked successfully

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
boot.extraModprobeConfig = ''
  blacklist nouveau
  options nouveau modeset=0
'';
  
services.udev.extraRules = ''
  # Remove NVIDIA USB xHCI Host Controller devices, if present
  ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c0330", ATTR{power/control}="auto", ATTR{remove}="1"
  # Remove NVIDIA USB Type-C UCSI devices, if present
  ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c8000", ATTR{power/control}="auto", ATTR{remove}="1"
  # Remove NVIDIA Audio devices, if present
  ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", ATTR{power/control}="auto", ATTR{remove}="1"
  # Remove NVIDIA VGA/3D controller devices
  ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x03[0-9]*", ATTR{power/control}="auto", ATTR{remove}="1"
'';
boot.blacklistedKernelModules = [ "nouveau" "nvidia" "nvidia_drm" "nvidia_modeset" ];