Skip to content

Commit 7785872

Browse files
committed
WSLg GPU: NVIDIA userland install + cairo-software fallback toggle
Two coupled changes per operator 2026-05-10 directive ("WSLg + GPU-PV ... NVIDIA Vulkan ICD; option 1 default + option 3 selectable fallback"). 1. /usr/libexec/mios/install-nvidia-wsl-userland.sh (NEW): installs nvidia-driver-libs from NVIDIA's official CUDA repo (developer.download.nvidia.com/compute/cuda/repos/fedoraN). Pulls: * /usr/share/vulkan/icd.d/nvidia_icd.x86_64.json * /usr/lib64/libGLX_nvidia.so.0 + libEGL_nvidia.so.0 * libnvidia-gpucomp / libnvidia-ml RPM versions * egl-wayland / egl-gbm / egl-x11 platform implementations Userland-only -- excludes kmod-nvidia* / akmod-nvidia* (kernel modules don't apply on WSL; /dev/dxg already provides the kernel bridge). Self-detects WSLg via /dev/dxg + /mnt/wslg, exits cleanly on bare-metal / Hyper-V / OCI substrates. Idempotent. Caveat documented inline: NVIDIA's NATIVE Vulkan ICD enumerates no GPU under WSL because it expects /dev/nvidia* device nodes that WSL doesn't expose. Vulkan workloads still go through dzn. Why install anyway: nvidia-smi works; libGLX_nvidia is forward- compatible when WSL2 eventually exposes /dev/nvidia* or NVIDIA ships a /dev/dxg-aware Vulkan ICD; flatpak apps that probe for NVIDIA detection get a real vendor lib to point at. 2. /etc/profile.d/mios-wslg-gpu.sh: added MIOS_GPU_SOFTWARE=1 toggle. Set in shell or ~/.config/environment.d/ to force cairo + llvmpipe (CPU-only rendering). Slow but always produces visible content -- escape hatch for apps where the d3d12 / dzn paths still fail. Default behavior unchanged (d3d12 + GL renderer). build-mios.ps1: added overlay-phase invocation of the install script after the [desktop].flatpaks pass. Runs as root inside the dev VM via wsl.exe; surfaces install-script's [ok]/[skip]/[warn] lines through Log-Ok / Log-Warn so the install summary reflects NVIDIA stack state. Verified live on running podman-MiOS-DEV: install completes, nvidia_icd.x86_64.json + libGLX_nvidia.so.0 land at expected paths. Vulkan loader still picks dzn for actual rendering (per the WSL caveat above) but the stack is in place for the day WSL gains /dev/nvidia* visibility.
1 parent 967c7ae commit 7785872

2 files changed

Lines changed: 119 additions & 0 deletions

File tree

etc/profile.d/mios-wslg-gpu.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@
2323

2424
[ -d /mnt/wslg ] || return 0
2525

26+
# ── Cairo / software-rendering fallback toggle ───────────────────
27+
# Set MIOS_GPU_SOFTWARE=1 to force CPU-only rendering (cairo +
28+
# llvmpipe). Slow but always produces visible content -- useful
29+
# when dzn / d3d12 / NVIDIA paths are all failing for a specific
30+
# app. Operator can flip per-shell or persist via
31+
# ~/.config/environment.d/. Default (unset) = hardware-accelerated
32+
# d3d12 path below.
33+
if [ "${MIOS_GPU_SOFTWARE:-0}" = "1" ]; then
34+
export GALLIUM_DRIVER="${GALLIUM_DRIVER:-llvmpipe}"
35+
export LIBGL_ALWAYS_SOFTWARE=1
36+
export GSK_RENDERER="${GSK_RENDERER:-cairo}"
37+
return 0 2>/dev/null || exit 0
38+
fi
39+
2640
# ── Mesa / GL ────────────────────────────────────────────────────
2741
# d3d12 = the Mesa Gallium driver that targets WSLg's WDDM via
2842
# /dev/dxg. Far more reliable than dzn (Vulkan) for typical GTK
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#!/bin/bash
2+
# /usr/libexec/mios/install-nvidia-wsl-userland.sh
3+
#
4+
# Install NVIDIA's Vulkan ICD + GLX/EGL userspace libs for WSLg
5+
# dev-VM hosts. Called by build-mios.ps1's Quadlet/overlay phase
6+
# AND idempotent-callable from `mios install-gpu` for live re-runs.
7+
#
8+
# What this gets you:
9+
# * /usr/share/vulkan/icd.d/nvidia_icd.x86_64.json
10+
# * /usr/lib64/libGLX_nvidia.so + libEGL_nvidia.so + libGLESv2_nvidia
11+
# * libnvidia-ml + libnvidia-gpucomp (already provided by WSL drop,
12+
# installing the RPM versions is harmless and adds versioned symlinks)
13+
# * egl-wayland + egl-gbm + egl-x11 (EGL platform implementations)
14+
#
15+
# What this does NOT do:
16+
# * NO kernel-module install (kmod-nvidia / akmod-nvidia) -- the
17+
# kernel module isn't applicable on WSL2; /dev/dxg is the kernel-
18+
# mode bridge and it's already there.
19+
# * NOT a full CUDA toolkit install -- libnvidia-ml is enough for
20+
# `nvidia-smi` and PyTorch's CUDA detection. Operators wanting
21+
# the full toolchain run `dnf install cuda-toolkit-X-Y` separately.
22+
#
23+
# Caveat: this installs NVIDIA's NATIVE Vulkan ICD which expects
24+
# /dev/nvidia* device nodes. WSL2 doesn't have those -- it has
25+
# /dev/dxg (WDDM) instead. So the NVIDIA Vulkan ICD doesn't enumerate
26+
# any GPU under WSL; Vulkan workloads still go through Microsoft's
27+
# `dzn` ICD (Direct3D12 translation). Why install NVIDIA libs anyway?
28+
#
29+
# 1. Compute / CUDA workloads work via libcuda + libnvidia-ml
30+
# (Microsoft's WSL drop) regardless of NVIDIA Vulkan availability.
31+
# 2. nvidia-smi becomes available so the operator can verify GPU
32+
# health from inside the dev VM.
33+
# 3. Flatpak apps that bundle libGLX_nvidia detection get a real
34+
# (if non-functional under WSL) vendor lib to point at, avoiding
35+
# "no NVIDIA driver detected" warnings on launch.
36+
# 4. Forward-compatible: when WSL2 eventually exposes /dev/nvidia*
37+
# (or NVIDIA ships a WSL-aware Vulkan ICD that targets /dev/dxg),
38+
# this stack is already in place.
39+
#
40+
# Idempotent + safe to re-run: dnf install of already-present pkgs
41+
# is a no-op; repo add with --overwrite refreshes the .repo file.
42+
#
43+
# Operator override: set MIOS_SKIP_NVIDIA_INSTALL=1 to skip entirely.
44+
45+
set -e
46+
47+
if [ "${MIOS_SKIP_NVIDIA_INSTALL:-0}" = "1" ]; then
48+
echo " [skip] MIOS_SKIP_NVIDIA_INSTALL=1; not installing NVIDIA userland."
49+
exit 0
50+
fi
51+
52+
# Gate on WSLg presence -- this script is for WSLg dev VMs only.
53+
if [ ! -d /mnt/wslg ] && [ ! -c /dev/dxg ]; then
54+
echo " [skip] not WSLg (no /mnt/wslg + no /dev/dxg); NVIDIA WSL userland not applicable."
55+
exit 0
56+
fi
57+
58+
# Detect upstream Fedora version. MiOS-branded os-release sets
59+
# VERSION_ID to the MiOS version; PLATFORM_ID preserves the Fedora
60+
# upstream as "platform:fXX".
61+
fedver=$(. /etc/os-release; echo "$PLATFORM_ID" | sed -E 's/^.*:f([0-9]+)$/\1/')
62+
[ -z "$fedver" ] && fedver=$(. /etc/os-release; echo "${VERSION_ID:-44}")
63+
echo " Fedora upstream: $fedver"
64+
65+
# Probe NVIDIA CUDA repo URLs. Try the detected fedora version first,
66+
# fall back to nearby versions if 404 (NVIDIA publishes per-Fedora-
67+
# version repos on a release-by-release basis).
68+
repo_url=""
69+
for v in "$fedver" 44 43 42 41 40; do
70+
[ -z "$v" ] && continue
71+
cand="https://developer.download.nvidia.com/compute/cuda/repos/fedora${v}/x86_64/cuda-fedora${v}.repo"
72+
code=$(curl -fsI -o /dev/null -w "%{http_code}" "$cand" 2>/dev/null || true)
73+
if [ "$code" = "200" ]; then
74+
echo " NVIDIA CUDA repo: fedora${v} ($cand)"
75+
repo_url="$cand"
76+
break
77+
fi
78+
done
79+
if [ -z "$repo_url" ]; then
80+
echo " [warn] no NVIDIA CUDA repo reachable for Fedora ${fedver} or fallbacks; skipping."
81+
exit 0
82+
fi
83+
84+
dnf config-manager addrepo --from-repofile="$repo_url" --overwrite >/dev/null 2>&1 || true
85+
86+
# Install userland-only. Excludes are defensive against weak-deps
87+
# pulling in a kernel-module package; --setopt=install_weak_deps=False
88+
# is also belt-and-suspenders.
89+
dnf install -y --setopt=install_weak_deps=False \
90+
-x 'kmod-nvidia*' \
91+
-x 'akmod-nvidia*' \
92+
-x 'nvidia-driver-cuda' \
93+
-x 'nvidia-driver-NvFBCOpenGL' \
94+
nvidia-driver-libs 2>&1 | tail -5
95+
96+
# Verify install landed.
97+
if [ -e /usr/share/vulkan/icd.d/nvidia_icd.x86_64.json ] \
98+
&& [ -e /usr/lib64/libGLX_nvidia.so.0 ]; then
99+
echo " [ok] NVIDIA WSL userland installed:"
100+
echo " vulkan ICD: /usr/share/vulkan/icd.d/nvidia_icd.x86_64.json"
101+
echo " GLX/EGL: /usr/lib64/libGLX_nvidia.so.0 + libEGL_nvidia.so.0"
102+
else
103+
echo " [warn] install completed but expected files missing -- inspect dnf output above."
104+
exit 1
105+
fi

0 commit comments

Comments
 (0)