1{ config, lib, pkgs, pkgs_i686, ... }:
2
3with lib;
4
5let
6
7 cfg = config.hardware.opengl;
8
9 kernelPackages = config.boot.kernelPackages;
10
11 videoDrivers = config.services.xserver.videoDrivers;
12
13 makePackage = p: pkgs.buildEnv {
14 name = "mesa-drivers+txc-${p.mesa_drivers.version}";
15 paths =
16 [ p.mesa_drivers
17 (if cfg.s3tcSupport then p.libtxc_dxtn else p.libtxc_dxtn_s2tc)
18 ];
19 };
20
21 package = pkgs.buildEnv {
22 name = "opengl-drivers";
23 paths = [ cfg.package ] ++ cfg.extraPackages;
24 };
25
26 package32 = pkgs.buildEnv {
27 name = "opengl-drivers-32bit";
28 paths = [ cfg.package32 ] ++ cfg.extraPackages32;
29 };
30
31in
32
33{
34 options = {
35
36 hardware.opengl = {
37 enable = mkOption {
38 description = ''
39 Whether to enable OpenGL drivers. This is needed to enable
40 OpenGL support in X11 systems, as well as for Wayland compositors
41 like sway, way-cooler and Weston. It is enabled by default
42 by the corresponding modules, so you do not usually have to
43 set it yourself, only if there is no module for your wayland
44 compositor of choice. See services.xserver.enable,
45 programs.sway.enable, and programs.way-cooler.enable.
46 '';
47 type = types.bool;
48 default = false;
49 };
50
51 driSupport = mkOption {
52 type = types.bool;
53 default = true;
54 description = ''
55 Whether to enable accelerated OpenGL rendering through the
56 Direct Rendering Interface (DRI).
57 '';
58 };
59
60 driSupport32Bit = mkOption {
61 type = types.bool;
62 default = false;
63 description = ''
64 On 64-bit systems, whether to support Direct Rendering for
65 32-bit applications (such as Wine). This is currently only
66 supported for the <literal>nvidia</literal> and
67 <literal>ati_unfree</literal> drivers, as well as
68 <literal>Mesa</literal>.
69 '';
70 };
71
72 s3tcSupport = mkOption {
73 type = types.bool;
74 default = false;
75 description = ''
76 Make S3TC(S3 Texture Compression) via libtxc_dxtn available
77 to OpenGL drivers instead of the patent-free S2TC replacement.
78
79 Using this library may require a patent license depending on your location.
80 '';
81 };
82
83 package = mkOption {
84 type = types.package;
85 internal = true;
86 description = ''
87 The package that provides the OpenGL implementation.
88 '';
89 };
90
91 package32 = mkOption {
92 type = types.package;
93 internal = true;
94 description = ''
95 The package that provides the 32-bit OpenGL implementation on
96 64-bit systems. Used when <option>driSupport32Bit</option> is
97 set.
98 '';
99 };
100
101 extraPackages = mkOption {
102 type = types.listOf types.package;
103 default = [];
104 example = literalExample "with pkgs; [ vaapiIntel libvdpau-va-gl vaapiVdpau intel-ocl ]";
105 description = ''
106 Additional packages to add to OpenGL drivers. This can be used
107 to add OpenCL drivers, VA-API/VDPAU drivers etc.
108 '';
109 };
110
111 extraPackages32 = mkOption {
112 type = types.listOf types.package;
113 default = [];
114 example = literalExample "with pkgs.pkgsi686Linux; [ vaapiIntel libvdpau-va-gl vaapiVdpau ]";
115 description = ''
116 Additional packages to add to 32-bit OpenGL drivers on
117 64-bit systems. Used when <option>driSupport32Bit</option> is
118 set. This can be used to add OpenCL drivers, VA-API/VDPAU drivers etc.
119 '';
120 };
121 };
122
123 };
124
125 config = mkIf cfg.enable {
126
127 assertions = lib.singleton {
128 assertion = cfg.driSupport32Bit -> pkgs.stdenv.isx86_64;
129 message = "Option driSupport32Bit only makes sense on a 64-bit system.";
130 };
131
132 system.activationScripts.setup-opengl =
133 ''
134 ln -sfn ${package} /run/opengl-driver
135 ${if pkgs.stdenv.isi686 then ''
136 ln -sfn opengl-driver /run/opengl-driver-32
137 '' else if cfg.driSupport32Bit then ''
138 ln -sfn ${package32} /run/opengl-driver-32
139 '' else ''
140 rm -f /run/opengl-driver-32
141 ''}
142 '';
143
144 environment.sessionVariables.LD_LIBRARY_PATH =
145 [ "/run/opengl-driver/lib" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/lib";
146
147 environment.variables.XDG_DATA_DIRS =
148 [ "/run/opengl-driver/share" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/share";
149
150 hardware.opengl.package = mkDefault (makePackage pkgs);
151 hardware.opengl.package32 = mkDefault (makePackage pkgs_i686);
152
153 boot.extraModulePackages = optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions;
154 };
155}