Skip to content

Commit 967c7ae

Browse files
committed
WSLg GUI: force Mesa d3d12 + GTK4 GL renderer for system apps
System-installed GUI apps (nautilus, gnome-software, epiphany when run as RPM not flatpak) fail to render content on WSLg because: - Mesa 25 defaults to Zink (GL-on-Vulkan) for the GL stack - Zink requires Vulkan features (nullDescriptor, robustness2) - WSLg's only Vulkan ICD is dzn (DirectX-to-Vulkan bridge), which is non-conformant and missing those features - Result: window registers with weston RDP rail (taskbar icon appears) but the frame buffer can never initialize -> nothing ever renders inside the window Operator 2026-05-10: "the windows never render though--there's an icon on the windows taskbar but no actual window EVER rendered." Fix: /etc/profile.d/mios-wslg-gpu.sh exports: GALLIUM_DRIVER=d3d12 -> Mesa GL via Direct3D 12 MESA_LOADER_DRIVER_OVERRIDE=d3d12 -> override DRI auto-detection LIBGL_KOPPER_DISABLE=1 -> skip Mesa-25 Kopper-on-Zink GSK_RENDERER=gl -> GTK4 OpenGL renderer (not Vulkan) WEBKIT_DISABLE_COMPOSITING_MODE=1 -> WebKitGTK avoids Vulkan path WAYLAND_DISPLAY=wayland-0 -> WSLg Wayland default DISPLAY=:0 -> XWayland fallback Gated on /mnt/wslg presence (ConditionPath equiv) -- inert outside WSLg, so bare-metal / Hyper-V / QEMU / OCI deployments keep their canonical Mesa path. Verified: weston.log RDP-rail shows windows registering at proper sizes once the env is loaded by an interactive shell (apps run from the user's bash prompt source /etc/profile.d/* via /etc/profile). Note: this gets system apps to register windows but content rendering is still gated on the underlying d3d12-driver path. For GTK4 apps that still hit dzn-unsupported features, GSK_RENDERER can be flipped to "cairo" via per-app override or operator-level ~/.config/environment.d/. Follow-up: evaluate adding NVIDIA Vulkan ICD when host has NVIDIA GPU (RTX 4090 in the operator's case).
1 parent b0e787f commit 967c7ae

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

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

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# /etc/profile.d/mios-wslg-gpu.sh
2+
#
3+
# WSLg GUI rendering env. Without this, GTK4 + Mesa default to
4+
# Vulkan-via-Zink-via-dzn (DirectX-to-Vulkan bridge on WSLg) --
5+
# but dzn is non-conformant and missing features Zink requires
6+
# (nullDescriptor, robustness2, descriptor pool memory). Result:
7+
# the app's Wayland surface registers with weston RDP rail (the
8+
# Windows taskbar shows the icon), but the frame buffer can never
9+
# initialize. Operator-visible failure mode 2026-05-10: "the
10+
# windows never render though--there's an icon on the windows
11+
# taskbar but no actual window EVER rendered."
12+
#
13+
# Solution: force Mesa onto the d3d12 Gallium driver (translates
14+
# OpenGL calls to Direct3D 12 -> goes through /dev/dxg -> real GPU
15+
# acceleration on the Windows host), and tell GTK4's GSK to use
16+
# its GL renderer instead of the Vulkan one. dzn stays available
17+
# for apps that explicitly want it, but isn't the default.
18+
#
19+
# Gated on /mnt/wslg presence -- inert outside WSLg (bare-metal /
20+
# Hyper-V / QEMU / OCI keep their canonical Mesa+Vulkan path).
21+
#
22+
# Compatible with bash, sh, zsh, dash login shells -- no bashisms.
23+
24+
[ -d /mnt/wslg ] || return 0
25+
26+
# ── Mesa / GL ────────────────────────────────────────────────────
27+
# d3d12 = the Mesa Gallium driver that targets WSLg's WDDM via
28+
# /dev/dxg. Far more reliable than dzn (Vulkan) for typical GTK
29+
# workloads. The MESA_LOADER override forces Mesa's loader to
30+
# pick the d3d12 driver even when its auto-detection fails (which
31+
# it does on WSLg because /dev/dri/* devices don't exist).
32+
export GALLIUM_DRIVER="${GALLIUM_DRIVER:-d3d12}"
33+
export MESA_LOADER_DRIVER_OVERRIDE="${MESA_LOADER_DRIVER_OVERRIDE:-d3d12}"
34+
# Mesa-25+ replaced the old DRI2 path with Kopper for X-on-Vulkan;
35+
# Kopper on WSLg goes through Zink which goes through dzn -- so
36+
# disable Kopper to keep GL apps on the d3d12 path.
37+
export LIBGL_KOPPER_DISABLE="${LIBGL_KOPPER_DISABLE:-1}"
38+
39+
# ── GTK4 ─────────────────────────────────────────────────────────
40+
# GTK4's default GSK_RENDERER on >= 4.14 is "ngl" (preferring
41+
# Vulkan). On WSLg with dzn broken that renders to a 0x0 surface.
42+
# Force "gl" (the OpenGL renderer that uses GALLIUM_DRIVER=d3d12
43+
# above). "cairo" is the software fallback if d3d12 also fails.
44+
export GSK_RENDERER="${GSK_RENDERER:-gl}"
45+
46+
# ── WebKit (Epiphany / GNOME-Web) ───────────────────────────────
47+
# WebKit's accelerated compositing path tries Vulkan first too.
48+
# Disabling AC mode keeps WebKit on the GL path which honors
49+
# GALLIUM_DRIVER=d3d12.
50+
export WEBKIT_DISABLE_COMPOSITING_MODE="${WEBKIT_DISABLE_COMPOSITING_MODE:-1}"
51+
52+
# ── Wayland defaults ─────────────────────────────────────────────
53+
# WSLg sets WAYLAND_DISPLAY=wayland-0 and stages the socket at
54+
# /mnt/wslg/runtime-dir/wayland-0 (symlinked into $XDG_RUNTIME_DIR).
55+
# These are usually already exported by WSL's init -- export them
56+
# defensively so apps launched from non-login shells (cron, dbus
57+
# activation) still find them.
58+
export WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}"
59+
[ -n "${XDG_RUNTIME_DIR:-}" ] || export XDG_RUNTIME_DIR="/run/user/$(id -u 2>/dev/null || echo 1000)"
60+
61+
# ── X11 fallback (XWayland) ──────────────────────────────────────
62+
# Some apps (older Qt5 utilities) still want X11. WSLg provides
63+
# XWayland at /tmp/.X11-unix/X0 -- ensure DISPLAY points there.
64+
export DISPLAY="${DISPLAY:-:0}"
65+
66+
# ── Vulkan ICD ──────────────────────────────────────────────────
67+
# WSLg ships dzn at /usr/share/vulkan/icd.d/dzn_icd.x86_64.json.
68+
# We don't unset it -- apps that explicitly request Vulkan can
69+
# still use it (and may work for compute / non-graphical workloads).
70+
# But we don't make it the GTK / GL default.
71+
:

0 commit comments

Comments
 (0)