Find a GPU driver on hosts without /run/opengl-driver - #1
Merged
pcasaretto merged 1 commit intoSep 25, 2026
Merged
pcasaretto merged 1 commit into
pcasaretto merged 1 commit into
Conversation
A Nix-built vulkan-loader looks for its ICD manifests under
/run/opengl-driver/share/vulkan/icd.d, a path that only NixOS creates, so
on any other distribution the loader found no drivers at all, wgpu came up
with no enabled backend, and the app died in create_surface with "Failed to
create surface for any enabled backend: {}" before a window was shown. The
host's own Mesa cannot fill the gap — its ICD names the vendor library
relatively and Nix's glibc does not read /etc/ld.so.cache, while forcing
the issue with LD_LIBRARY_PATH shadows glibc itself and breaks the process
— so the driver has to come from the closure.
- postFixup now runs addDriverRunpath on the binary, keeping NixOS and
proprietary-NVIDIA hosts working through /run/opengl-driver/lib
- postFixup wraps the binary so this closure's Mesa is offered as an
additional driver source: VK_ADD_DRIVER_FILES for Vulkan,
__EGL_VENDOR_LIBRARY_DIRS and LIBGL_DRIVERS_PATH for GL, all suffixed so
a driver the loader discovers for itself still wins
- addDriverRunpath and makeWrapper join nativeBuildInputs under the
existing isLinux guard
- the comment above postFixup explains driver discovery, not just the
dlopened loaders, and records that NVIDIA's proprietary stack still
needs nixGL
pcasaretto
approved these changes
Sep 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds on your
nix-flakebranch (tobi#26 ontobi/disktree), so it's aimed at your branch rather thanmain— merge it and tobi#26 picks it up.The symptom
On Arch (Omarchy/Hyprland, Radeon 890M, Wayland)
nix run github:pcasaretto/disktree/nix-flakenever draws a window:The empty brace set is the tell: wgpu isn't reporting a backend that failed, it's reporting that it had no backend to try.
Why
The
patchelf --add-rpathinpostFixupis doing its job —dlopen("libvulkan.so.1")resolves to the closure'svulkan-loader. The loader then has to find a driver, which it discovers through an ICD manifest, and a Nix-built loader looks for those under/run/opengl-driver/share/vulkan/icd.d. Only NixOS creates that path. WithVK_LOADER_DEBUG=error:The host's own Mesa can't be borrowed to fix it.
/usr/share/vulkan/icd.d/radeon_icd.jsonnames its library relatively (libvulkan_radeon.so) and Nix's glibc doesn't read/etc/ld.so.cache, so it isn't found; rewriting the manifest with an absolute path then fails onlibLLVM.so.22.1for the same reason; andLD_LIBRARY_PATH=/usr/libshadows glibc itself and kills the process outright (/usr/lib/libc.so.6: undefined symbol: __pointer_chk_guard, version GLIBC_PRIVATE). The driver has to come from the closure.The change
postFixupgains two lines' worth of work:addDriverRunpath $out/bin/disktree— appends/run/opengl-driver/lib, so NixOS and proprietary-NVIDIA hosts keep working exactly as before.wrapProgramoffering this closure's Mesa as an additional driver source:VK_ADD_DRIVER_FILESfor Vulkan,__EGL_VENDOR_LIBRARY_DIRSandLIBGL_DRIVERS_PATHfor GL.Everything is
--suffix, andVK_ADD_DRIVER_FILES(rather thanVK_DRIVER_FILES) is searched after the ICDs the loader discovers for itself — so a working system driver still wins and NixOS behaviour is unchanged.addDriverRunpathandmakeWrapperjoinnativeBuildInputsunder the existingisLinuxguard.A machine driven by the proprietary NVIDIA stack is still out of scope — Mesa cannot drive that card, so those hosts need nixGL. The comment above
postFixupsays so.Verified
nix build .#disktreeon the pinned nixpkgs, then both$out/bin/disktreeandnix run .#disktreeopen the window on Arch with no environment variables set.readelf -don.disktree-wrappedshows/run/opengl-driver/libfirst in the RUNPATH, and the desktop entry'sExecstill resolves to the wrapper rather than the inner binary.Two smaller things I left alone
fontconfig,freetype,libx11,libxcursor,libxiandlibxrandrappear in neitherNEEDEDnor the RUNPATH of the built binary (which wants onlylibxcb,libxkbcommon,libxkbcommon-x11,libgcc_s,libm,libc), and the onlydlopened names in the binary arelibvulkan.so.1,libEGL.so.1andlibwayland-client.so.0. They may well be build-timepkg-configneeds, but if they aren't, dropping them would stop the input list implying an X11 story the RUNPATH doesn't support.$out/bin/disktree --helpexits 0 without a display, so aninstallCheckPhaseone-liner would catch a broken wrapper in future.