Files
appsandbox/tools/linux/wsl-mesa/appsandbox-gpu
T
James Stringer 194cadeaa6 NVENC/NVDEC userspace path + nvidia-smi shortcut
- systemd-user environment generator and appsandbox-gpu wrapper both
  append /usr/lib/wsl/lib to LD_LIBRARY_PATH. ldconfig has the .so.1
  entries cached, but the 9P mount is read-only so the unversioned
  symlinks ldconfig wants to create can't be written. dlopen() of
  unversioned names (libcuda.so, libnvidia-encode.so, libnvcuvid.so)
  needs the path on LD_LIBRARY_PATH — without it ffmpeg's h264_nvenc /
  h264_cuvid plugins fail with 'Cannot load libcuda.so.1'.

- setup.sh: symlink /usr/lib/wsl/lib/nvidia-smi to /usr/local/bin so
  the bare command works without env tweaks. Created unconditionally
  because the symlink target is resolved at exec time — the file
  appears under the agent's 9P mount on first boot regardless of when
  the symlink was created.
2026-05-19 22:09:52 -04:00

57 lines
2.3 KiB
Bash

#!/bin/sh
# appsandbox-gpu — run a command with host-GPU acceleration via /dev/dxg.
#
# Probes for the GPU partition device and the custom Mesa build. When both
# are present, sets the Mesa loader + Vulkan ICD env vars so OpenGL goes
# through the d3d12 gallium driver and Vulkan goes through the dzn driver,
# both of which talk to /dev/dxg and run shader workloads on the host GPU.
#
# When the VM has no GPU partition attached, this is a no-op pass-through:
# the command runs with stock Mesa (llvmpipe / lavapipe) unchanged.
#
# Usage:
# appsandbox-gpu <cmd> [args...]
#
# Example:
# appsandbox-gpu glxinfo -B
# appsandbox-gpu vulkaninfo --summary
# appsandbox-gpu ./FurMark_GUI
set -e
WSL_MESA=/opt/wsl-mesa
WSL_MESA_LIB="$WSL_MESA/lib/x86_64-linux-gnu"
WSL_MESA_VK_ICD="$WSL_MESA/share/vulkan/icd.d/dzn_icd.x86_64.json"
WSL_LIB=/usr/lib/wsl/lib
if [ -e /dev/dxg ] && [ -d "$WSL_MESA_LIB" ]; then
# LD_LIBRARY_PATH covers two needs:
# - $WSL_MESA_LIB picks Mesa's d3d12 gallium + dzn Vulkan over stock.
# - $WSL_LIB lets apps that dlopen the WSL NVIDIA userspace libs by
# unversioned SONAME (libcuda.so, libnvidia-encode.so, libnvcuvid.so)
# find them. ldconfig caches only the .so.1 entries — the 9P mount
# is read-only so the unversioned symlinks can't be created.
# NVENC (h264_nvenc, hevc_nvenc) + NVDEC (h264_cuvid, etc.) need this.
export LD_LIBRARY_PATH="$WSL_MESA_LIB:$WSL_LIB${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
export __GLX_VENDOR_LIBRARY_NAME=mesa
# Both env vars are needed:
# GALLIUM_DRIVER controls direct gallium selection (used by GLX/X11).
# MESA_LOADER_DRIVER_OVERRIDE controls the DRI loader (used by EGL,
# Wayland clients). Setting one without the other gives accelerated
# GLX but llvmpipe-on-EGL (or vice versa).
export GALLIUM_DRIVER=d3d12
export MESA_LOADER_DRIVER_OVERRIDE=d3d12
# Vulkan: load only the microsoft-experimental (dzn) ICD. Without
# VK_DRIVER_FILES set, the loader would also pick up lavapipe + Ubuntu's
# stock ICDs (intel/nouveau/etc) and adapter selection is unreliable.
# File is dzn_icd.x86_64.json — the wsl-mesa README mentions
# microsoft_icd.x86_64.json but Mesa 25.3 ships it as dzn_icd.
if [ -e "$WSL_MESA_VK_ICD" ]; then
export VK_DRIVER_FILES="$WSL_MESA_VK_ICD"
fi
fi
exec "$@"