|
28 | 28 | configFile = settingsFormat.generate "moonshine-config.toml" cfg.settings; |
29 | 29 |
|
30 | 30 | runtimeDir = "/run/user/${toString cfg.uid}"; |
| 31 | + |
| 32 | + # The Vulkan implicit-layer manifest on its own, for the driver path below. |
| 33 | + # Everything in hardware.graphics.extraPackages is merged into |
| 34 | + # /run/opengl-driver, and programs.steam puts that lib/ on Steam's FHS |
| 35 | + # library path, so the whole package has no business being in there. The |
| 36 | + # manifest names the layer library by absolute store path, so it is all that |
| 37 | + # needs to go. |
| 38 | + wsiLayer = pkgs.runCommand "moonshine-wsi-layer" { } '' |
| 39 | + install -Dm644 \ |
| 40 | + ${cfg.package}/share/vulkan/implicit_layer.d/VkLayer_moonshine_wsi.json \ |
| 41 | + $out/share/vulkan/implicit_layer.d/VkLayer_moonshine_wsi.json |
| 42 | + ''; |
31 | 43 | in |
32 | 44 | { |
33 | 45 | options.services.moonshine = { |
|
120 | 132 | } |
121 | 133 | ]; |
122 | 134 |
|
123 | | - # Besides the binary, the package carries the Vulkan implicit-layer |
124 | | - # manifest (share/vulkan/implicit_layer.d) that the loader must be able |
125 | | - # to find; it only engages for apps moonshine launches |
126 | | - # (ENABLE_MOONSHINE_WSI=1), so it is inert for everything else. |
| 135 | + # Puts `moonshine` on PATH for the healthcheck and pairing subcommands, and |
| 136 | + # is how the polkit rule below gets picked up. |
127 | 137 | environment.systemPackages = [ cfg.package ]; |
128 | 138 |
|
| 139 | + # The moonshine-wsi Vulkan layer routes a game's swapchain frames into |
| 140 | + # moonshine's compositor. It is an *implicit* layer, so the loader has to |
| 141 | + # find its manifest by scanning, and a store path is only scanned when it |
| 142 | + # is listed in XDG_DATA_DIRS. Nothing here has that: a systemd system |
| 143 | + # service gets no XDG_DATA_DIRS, and neither does the user instance that |
| 144 | + # launches the games when it was started by lingering rather than by a |
| 145 | + # graphical login. Without it everything silently falls back to rendering |
| 146 | + # through XWayland. |
| 147 | + # |
| 148 | + # nixpkgs builds the loader with SYSCONFDIR=/run/opengl-driver/share, which |
| 149 | + # it always scans, environment or not. So install the layer there: the |
| 150 | + # NixOS counterpart of the /etc/vulkan/implicit_layer.d drop that upstream's |
| 151 | + # install script does on atomic distributions. Only the 64-bit driver path, |
| 152 | + # because the layer is built for the host architecture and there is no |
| 153 | + # 32-bit build to put in extraPackages32. Nothing is lost: where the |
| 154 | + # manifest sits in an arch-agnostic directory (/usr/share on deb/rpm), a |
| 155 | + # 32-bit loader finds it and skips it over the ELF class anyway. |
| 156 | + hardware.graphics = { |
| 157 | + # Needed regardless of the layer: this option is what creates |
| 158 | + # /run/opengl-driver, which is where the package resolves its Vulkan |
| 159 | + # loader and the NVIDIA userspace driver from. |
| 160 | + enable = true; |
| 161 | + extraPackages = [ wsiLayer ]; |
| 162 | + }; |
| 163 | + |
129 | 164 | # Grants the `input` group + active-seat ACLs on /dev/uinput and |
130 | 165 | # /dev/uhid, which inputtino uses to create the virtual |
131 | 166 | # gamepad/keyboard/mouse. |
|
0 commit comments