Move the NVIDIA support into its own module
Previously all card-specific stuff was scattered across xserver.nix and opengl.nix, which is ugly. Now it can be kept together in a single card-specific module. This required the addition of a few internal options: - services.xserver.drivers: A list of { name, driverName, modules, libPath } sets. - hardware.opengl.package: The OpenGL implementation. Note that there can be only one OpenGL implementation at a time in a system configuration (i.e. no dynamic detection). - hardware.opengl.package32: The 32-bit OpenGL implementation.
This commit is contained in:
parent
3fe96bcca1
commit
02cef04c81
|
@ -10,6 +10,15 @@ let
|
|||
|
||||
videoDrivers = config.services.xserver.videoDrivers;
|
||||
|
||||
makePackage = p: p.buildEnv {
|
||||
name = "mesa-drivers+txc-${p.mesa_drivers.version}";
|
||||
paths =
|
||||
[ p.mesa_drivers
|
||||
p.mesa_noglu # mainly for libGL
|
||||
(if cfg.s3tcSupport then p.libtxc_dxtn else p.libtxc_dxtn_s2tc)
|
||||
];
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
@ -52,73 +61,64 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
hardware.opengl.package = mkOption {
|
||||
type = types.package;
|
||||
internal = true;
|
||||
description = ''
|
||||
The package that provides the OpenGL implementation.
|
||||
'';
|
||||
};
|
||||
|
||||
hardware.opengl.package32 = mkOption {
|
||||
type = types.package;
|
||||
internal = true;
|
||||
description = ''
|
||||
The package that provides the 32-bit OpenGL implementation on
|
||||
64-bit systems. Used when <option>driSupport32Bit</option> is
|
||||
set.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
assertions = pkgs.lib.singleton {
|
||||
assertion = cfg.driSupport32Bit -> pkgs.stdenv.isx86_64;
|
||||
message = "Option driSupport32Bit only makes sens on a 64-bit system.";
|
||||
message = "Option driSupport32Bit only makes sense on a 64-bit system.";
|
||||
};
|
||||
|
||||
system.activationScripts.setup-opengl.deps = [];
|
||||
system.activationScripts.setup-opengl.text = ''
|
||||
rm -f /run/opengl-driver{,-32}
|
||||
${optionalString (pkgs.stdenv.isi686) "ln -sf opengl-driver /run/opengl-driver-32"}
|
||||
system.activationScripts.setup-opengl =
|
||||
''
|
||||
#TODO: The OpenGL driver should depend on what's detected at runtime.
|
||||
+( if elem "nvidia" videoDrivers then
|
||||
''
|
||||
ln -sf ${kernelPackages.nvidia_x11} /run/opengl-driver
|
||||
${optionalString cfg.driSupport32Bit
|
||||
"ln -sf ${pkgs_i686.linuxPackages.nvidia_x11.override { libsOnly = true; kernel = null; } } /run/opengl-driver-32"}
|
||||
''
|
||||
else if elem "nvidiaLegacy173" videoDrivers then
|
||||
"ln -sf ${kernelPackages.nvidia_x11_legacy173} /run/opengl-driver"
|
||||
else if elem "nvidiaLegacy304" videoDrivers then
|
||||
''
|
||||
ln -sf ${kernelPackages.nvidia_x11_legacy304} /run/opengl-driver
|
||||
${optionalString cfg.driSupport32Bit
|
||||
"ln -sf ${pkgs_i686.linuxPackages.nvidia_x11_legacy304.override { libsOnly = true; kernel = null; } } /run/opengl-driver-32"}
|
||||
''
|
||||
else if elem "ati_unfree" videoDrivers then
|
||||
"ln -sf ${kernelPackages.ati_drivers_x11} /run/opengl-driver"
|
||||
else
|
||||
let
|
||||
lib_fun = p: p.buildEnv {
|
||||
name = "mesa-drivers+txc-${p.mesa_drivers.version}";
|
||||
paths = [
|
||||
p.mesa_drivers
|
||||
p.mesa_noglu # mainly for libGL
|
||||
(if cfg.s3tcSupport then p.libtxc_dxtn else p.libtxc_dxtn_s2tc)
|
||||
];
|
||||
};
|
||||
in
|
||||
''
|
||||
${optionalString cfg.driSupport "ln -sf ${lib_fun pkgs} /run/opengl-driver"}
|
||||
${optionalString cfg.driSupport32Bit
|
||||
"ln -sf ${lib_fun pkgs_i686} /run/opengl-driver-32"}
|
||||
''
|
||||
);
|
||||
ln -sfn ${cfg.package} /run/opengl-driver
|
||||
${if pkgs.stdenv.isi686 then ''
|
||||
ln -sfn opengl-driver /run/opengl-driver-32
|
||||
'' else if cfg.driSupport32Bit then ''
|
||||
ln -sfn ${cfg.package32} /run/opengl-driver-32
|
||||
'' else ''
|
||||
rm -f /run/opengl-driver-32
|
||||
''}
|
||||
'';
|
||||
|
||||
environment.variables.LD_LIBRARY_PATH =
|
||||
[ "/run/opengl-driver/lib" "/run/opengl-driver-32/lib" ];
|
||||
|
||||
# FIXME: move this into card-specific modules.
|
||||
hardware.opengl.package = mkDefault
|
||||
(if elem "ati_unfree" videoDrivers then
|
||||
kernelPackages.ati_drivers_x11
|
||||
else
|
||||
makePackage pkgs);
|
||||
|
||||
hardware.opengl.package32 = mkDefault (makePackage pkgs_i686);
|
||||
|
||||
boot.extraModulePackages =
|
||||
optional (elem "nvidia" videoDrivers) kernelPackages.nvidia_x11 ++
|
||||
optional (elem "nvidiaLegacy173" videoDrivers) kernelPackages.nvidia_x11_legacy173 ++
|
||||
optional (elem "nvidiaLegacy304" videoDrivers) kernelPackages.nvidia_x11_legacy304 ++
|
||||
optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions ++
|
||||
optional (elem "ati_unfree" videoDrivers) kernelPackages.ati_drivers_x11;
|
||||
|
||||
boot.blacklistedKernelModules =
|
||||
optionals (elem "nvidia" videoDrivers) [ "nouveau" "nvidiafb" ];
|
||||
|
||||
environment.etc =
|
||||
(optionalAttrs (elem "ati_unfree" videoDrivers) {
|
||||
optionalAttrs (elem "ati_unfree" videoDrivers) {
|
||||
"ati".source = "${kernelPackages.ati_drivers_x11}/etc/ati";
|
||||
})
|
||||
// (optionalAttrs (elem "nvidia" videoDrivers) {
|
||||
"OpenCL/vendors/nvidia.icd".source = "${kernelPackages.nvidia_x11}/lib/vendors/nvidia.icd";
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
54
nixos/modules/hardware/video/nvidia.nix
Normal file
54
nixos/modules/hardware/video/nvidia.nix
Normal file
|
@ -0,0 +1,54 @@
|
|||
# This module provides the proprietary NVIDIA X11 / OpenGL drivers.
|
||||
|
||||
{ config, lib, pkgs, pkgs_i686, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
drivers = config.services.xserver.videoDrivers;
|
||||
|
||||
# FIXME: should introduce an option like
|
||||
# ‘hardware.video.nvidia.package’ for overriding the default NVIDIA
|
||||
# driver.
|
||||
enabled = elem "nvidia" drivers || elem "nvidiaLegacy173" drivers || elem "nvidiaLegacy304" drivers;
|
||||
|
||||
nvidia_x11 =
|
||||
if elem "nvidia" drivers then
|
||||
config.boot.kernelPackages.nvidia_x11
|
||||
else if elem "nvidiaLegacy173" drivers then
|
||||
config.boot.kernelPackages.nvidia_x11_legacy173
|
||||
else if elem "nvidiaLegacy304" videoDrivers then
|
||||
config.boot.kernelPackages.nvidia_x11_legacy304
|
||||
else throw "impossible";
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
config = mkIf enabled {
|
||||
|
||||
services.xserver.drivers = singleton
|
||||
{ name = "nvidia"; modules = [ nvidia_x11 ]; libPath = [ nvidia_x11 ]; };
|
||||
|
||||
services.xserver.screenSection =
|
||||
''
|
||||
Option "RandRRotation" "on"
|
||||
'';
|
||||
|
||||
hardware.opengl.package = nvidia_x11;
|
||||
hardware.opengl.package32 = pkgs_i686.linuxPackages.nvidia_x11.override { libsOnly = true; kernel = null; };
|
||||
|
||||
environment.systemPackages = [ nvidia_x11 ];
|
||||
|
||||
boot.extraModulePackages = [ nvidia_x11 ];
|
||||
|
||||
boot.blacklistedKernelModules = [ "nouveau" "nvidiafb" ];
|
||||
|
||||
services.acpid.enable = true;
|
||||
|
||||
environment.etc."OpenCL/vendors/nvidia.icd".source = "${nvidia_x11}/lib/vendors/nvidia.icd";
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -32,6 +32,7 @@
|
|||
./hardware/opengl.nix
|
||||
./hardware/pcmcia.nix
|
||||
./hardware/video/bumblebee.nix
|
||||
./hardware/video/nvidia.nix
|
||||
./installer/tools/nixos-checkout.nix
|
||||
./installer/tools/tools.nix
|
||||
./misc/assertions.nix
|
||||
|
|
|
@ -11,30 +11,16 @@ let
|
|||
xorg = pkgs.xorg;
|
||||
|
||||
|
||||
# Map video driver names to driver packages.
|
||||
# Map video driver names to driver packages. FIXME: move into card-specific modules.
|
||||
knownVideoDrivers = {
|
||||
ati_unfree = { modules = [ kernelPackages.ati_drivers_x11 ]; driverName = "fglrx"; };
|
||||
nouveau = { modules = [ pkgs.xf86_video_nouveau ]; };
|
||||
nvidia = { modules = [ kernelPackages.nvidia_x11 ]; };
|
||||
nvidiaLegacy173 = { modules = [ kernelPackages.nvidia_x11_legacy173 ]; driverName = "nvidia"; };
|
||||
nvidiaLegacy304 = { modules = [ kernelPackages.nvidia_x11_legacy304 ]; driverName = "nvidia"; };
|
||||
unichrome = { modules = [ pkgs.xorgVideoUnichrome ]; };
|
||||
virtualbox = { modules = [ kernelPackages.virtualboxGuestAdditions ]; driverName = "vboxvideo"; };
|
||||
ati = { modules = [ pkgs.xorg.xf86videoati pkgs.xorg.glamoregl ]; };
|
||||
intel-testing = { modules = with pkgs.xorg; [ xf86videointel-testing glamoregl ]; driverName = "intel"; };
|
||||
};
|
||||
|
||||
driverNames = cfg.videoDrivers;
|
||||
|
||||
needsAcpid =
|
||||
(elem "nvidia" driverNames) ||
|
||||
(elem "nvidiaLegacy173" driverNames) ||
|
||||
(elem "nvidiaLegacy304" driverNames);
|
||||
|
||||
drivers = flip map driverNames
|
||||
(name: { inherit name; driverName = name; } //
|
||||
attrByPath [name] (if (hasAttr ("xf86video" + name) xorg) then { modules = [(getAttr ("xf86video" + name) xorg) ]; } else throw "unknown video driver `${name}'") knownVideoDrivers);
|
||||
|
||||
fontsForXServer =
|
||||
config.fonts.fonts ++
|
||||
# We don't want these fonts in fonts.conf, because then modern,
|
||||
|
@ -79,7 +65,6 @@ let
|
|||
monitors = foldl mkMonitor [] xrandrHeads;
|
||||
in concatMapStrings (getAttr "value") monitors;
|
||||
|
||||
|
||||
configFile = pkgs.stdenv.mkDerivation {
|
||||
name = "xserver.conf";
|
||||
|
||||
|
@ -204,6 +189,15 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
drivers = mkOption {
|
||||
type = types.listOf types.attrs;
|
||||
internal = true;
|
||||
description = ''
|
||||
A list of attribute sets specifying drivers to be loaded by
|
||||
the X11 server.
|
||||
'';
|
||||
};
|
||||
|
||||
vaapiDrivers = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [ ];
|
||||
|
@ -397,9 +391,21 @@ in
|
|||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
hardware.opengl.enable = true;
|
||||
|
||||
hardware.opengl.enable = mkDefault true;
|
||||
|
||||
services.xserver.videoDrivers = mkIf (cfg.videoDriver != null) [ cfg.videoDriver ];
|
||||
|
||||
# FIXME: somehow check for unknown driver names.
|
||||
services.xserver.drivers = flip concatMap cfg.videoDrivers (name:
|
||||
let driver =
|
||||
attrByPath [name]
|
||||
(if (hasAttr ("xf86video" + name) xorg)
|
||||
then { modules = [(getAttr ("xf86video" + name) xorg) ]; }
|
||||
else null)
|
||||
knownVideoDrivers;
|
||||
in optional (driver != null) ({ inherit name; driverName = name; } // driver));
|
||||
|
||||
assertions =
|
||||
[ { assertion = !(config.programs.ssh.startAgent && cfg.startGnuPGAgent);
|
||||
message =
|
||||
|
@ -438,24 +444,18 @@ in
|
|||
pkgs.xterm
|
||||
pkgs.xdg_utils
|
||||
]
|
||||
++ optional (elem "nvidia" driverNames) kernelPackages.nvidia_x11
|
||||
++ optional (elem "nvidiaLegacy173" driverNames) kernelPackages.nvidia_x11_legacy173
|
||||
++ optional (elem "nvidiaLegacy304" driverNames) kernelPackages.nvidia_x11_legacy304
|
||||
++ optional (elem "virtualbox" driverNames) xorg.xrefresh
|
||||
++ optional (elem "ati_unfree" driverNames) kernelPackages.ati_drivers_x11;
|
||||
|
||||
services.acpid.enable = mkIf needsAcpid true;
|
||||
++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh
|
||||
++ optional (elem "ati_unfree" cfg.videoDrivers) kernelPackages.ati_drivers_x11;
|
||||
|
||||
environment.pathsToLink =
|
||||
[ "/etc/xdg" "/share/xdg" "/share/applications" "/share/icons" "/share/pixmaps" ];
|
||||
|
||||
systemd.defaultUnit = mkIf cfg.autorun "graphical.target";
|
||||
|
||||
systemd.services."display-manager" =
|
||||
systemd.services.display-manager =
|
||||
{ description = "X11 Server";
|
||||
|
||||
after = [ "systemd-udev-settle.service" "local-fs.target" ]
|
||||
++ optional needsAcpid "acpid.service";
|
||||
after = [ "systemd-udev-settle.service" "local-fs.target" "acpid.service" ];
|
||||
|
||||
restartIfChanged = false;
|
||||
|
||||
|
@ -463,15 +463,11 @@ in
|
|||
{ FONTCONFIG_FILE = "/etc/fonts/fonts.conf"; # !!! cleanup
|
||||
XKB_BINDIR = "${xorg.xkbcomp}/bin"; # Needed for the Xkb extension.
|
||||
XORG_DRI_DRIVER_PATH = "/run/opengl-driver/lib/dri"; # !!! Depends on the driver selected at runtime.
|
||||
} // optionalAttrs (elem "nvidia" driverNames) {
|
||||
LD_LIBRARY_PATH = "${xorg.libX11}/lib:${xorg.libXext}/lib:${kernelPackages.nvidia_x11}/lib";
|
||||
} // optionalAttrs (elem "nvidiaLegacy173" driverNames) {
|
||||
LD_LIBRARY_PATH = "${xorg.libX11}/lib:${xorg.libXext}/lib:${kernelPackages.nvidia_x11_legacy173}/lib";
|
||||
} // optionalAttrs (elem "nvidiaLegacy304" driverNames) {
|
||||
LD_LIBRARY_PATH = "${xorg.libX11}/lib:${xorg.libXext}/lib:${kernelPackages.nvidia_x11_legacy304}/lib";
|
||||
} // optionalAttrs (elem "ati_unfree" driverNames) {
|
||||
LD_LIBRARY_PATH = "${xorg.libX11}/lib:${xorg.libXext}/lib:${kernelPackages.ati_drivers_x11}/lib:${kernelPackages.ati_drivers_x11}/X11R6/lib64/modules/linux";
|
||||
#XORG_DRI_DRIVER_PATH = "${kernelPackages.ati_drivers_x11}/lib/dri"; # is ignored because ati drivers ship their own unpatched libglx.so !
|
||||
LD_LIBRARY_PATH = concatStringsSep ":" (
|
||||
[ "${xorg.libX11}/lib" "${xorg.libXext}/lib" ]
|
||||
++ optionals (elem "ati_unfree" cfg.videoDrivers)
|
||||
[ "${kernelPackages.ati_drivers_x11}/lib" "${kernelPackages.ati_drivers_x11}/X11R6/lib64/modules/linux" ]
|
||||
++ concatLists (catAttrs "libPath" cfg.drivers));
|
||||
} // cfg.displayManager.job.environment;
|
||||
|
||||
preStart =
|
||||
|
@ -501,7 +497,7 @@ in
|
|||
] ++ optional (!cfg.enableTCP) "-nolisten tcp";
|
||||
|
||||
services.xserver.modules =
|
||||
concatLists (catAttrs "modules" drivers) ++
|
||||
concatLists (catAttrs "modules" cfg.drivers) ++
|
||||
[ xorg.xorgserver
|
||||
xorg.xf86inputevdev
|
||||
];
|
||||
|
@ -537,7 +533,7 @@ in
|
|||
${cfg.serverLayoutSection}
|
||||
# Reference the Screen sections for each driver. This will
|
||||
# cause the X server to try each in turn.
|
||||
${flip concatMapStrings drivers (d: ''
|
||||
${flip concatMapStrings cfg.drivers (d: ''
|
||||
Screen "Screen-${d.name}[0]"
|
||||
'')}
|
||||
EndSection
|
||||
|
@ -551,11 +547,11 @@ in
|
|||
|
||||
# For each supported driver, add a "Device" and "Screen"
|
||||
# section.
|
||||
${flip concatMapStrings drivers (driver: ''
|
||||
${flip concatMapStrings cfg.drivers (driver: ''
|
||||
|
||||
Section "Device"
|
||||
Identifier "Device-${driver.name}[0]"
|
||||
Driver "${driver.driverName}"
|
||||
Driver "${driver.driverName or driver.name}"
|
||||
${if cfg.useGlamor then ''Option "AccelMethod" "glamor"'' else ""}
|
||||
${cfg.deviceSection}
|
||||
${xrandrDeviceSection}
|
||||
|
@ -574,10 +570,6 @@ in
|
|||
DefaultDepth ${toString cfg.defaultDepth}
|
||||
''}
|
||||
|
||||
${optionalString (driver.name == "nvidia") ''
|
||||
Option "RandRRotation" "on"
|
||||
''}
|
||||
|
||||
${optionalString
|
||||
(driver.name != "virtualbox" &&
|
||||
(cfg.resolutions != [] ||
|
||||
|
|
Loading…
Reference in a new issue