Only force NVIDIA VA-API/GLX env when NVIDIA drives the display

This commit is contained in:
vatsal nadkarni committed 2026-09-13 19:34:17 +05:30
1 parent 692c02cad5
commit 6ecf4bf200
3 files changed
+92 -6

No files matched your search

+45
View File
@@ -0,0 +1,45 @@
#!/bin/bash
# omarchy:summary=Detect whether NVIDIA drives the display (rather than a hybrid iGPU).
# On hybrid laptops the display is usually wired to the integrated GPU while
# the NVIDIA card only handles offloaded rendering. Forcing NVIDIA's VA-API and
# GLX drivers globally then breaks Chromium-based browsers (black video with
# audio still playing), so the Hyprland NVIDIA env only applies when NVIDIA is
# the display GPU.
#
# sysfs exposes which VGA device drives the display via boot_vga. When no
# device claims it (attribute missing or unreadable), assume NVIDIA is the
# display GPU to preserve the current behavior on machines we cannot tell.
#
# Read the cached sysfs IDs rather than lspci, which reads PCI config space and
# resumes runtime-suspended GPUs.
pci_devices_path="${OMARCHY_PCI_DEVICES_PATH:-/sys/bus/pci/devices}"
shopt -s nullglob
nvidia_boot=0
other_boot=0
for device in "$pci_devices_path"/*; do
[[ $(< "$device/class") == 0x03* ]] || continue
boot_vga=0
if [[ -f $device/boot_vga ]]; then
boot_vga=$(< "$device/boot_vga")
fi
if [[ $(< "$device/vendor") == "0x10de" ]]; then
if (( boot_vga == 1 )); then
nvidia_boot=1
fi
else
if (( boot_vga == 1 )); then
other_boot=1
fi
fi
done
if (( other_boot == 1 && nvidia_boot == 0 )); then
exit 1
else
exit 0
fi
+12 -3
View File
@@ -1,6 +1,7 @@
local paths = require("default.hypr.paths")
local nvidia = paths.omarchy_path .. "/bin/omarchy-hw-nvidia"
local nvidia_display = paths.omarchy_path .. "/bin/omarchy-hw-nvidia-display"
local nvidia_gsp = paths.omarchy_path .. "/bin/omarchy-hw-nvidia-gsp"
local nvidia_without_gsp = paths.omarchy_path .. "/bin/omarchy-hw-nvidia-without-gsp"
@@ -8,12 +9,20 @@ local nvidia_without_gsp = paths.omarchy_path .. "/bin/omarchy-hw-nvidia-without
-- lspci reads PCI config space, which resumes a runtime-suspended GPU, and on a
-- hybrid laptop that wake alone outlasts Hyprland's 1.5s config reload budget.
if o.shell_succeeds(o.shell_quote(nvidia)) then
-- On hybrid laptops the display is wired to the iGPU, so forcing NVIDIA's
-- VA-API/GLX drivers globally breaks Chromium-based browsers (black video).
-- Only apply those when NVIDIA actually drives the display.
local nvidia_is_display = o.shell_succeeds(o.shell_quote(nvidia_display))
if o.shell_succeeds(o.shell_quote(nvidia_gsp)) then
hl.env("NVD_BACKEND", "direct")
hl.env("LIBVA_DRIVER_NAME", "nvidia")
hl.env("__GLX_VENDOR_LIBRARY_NAME", "nvidia")
if nvidia_is_display then
hl.env("LIBVA_DRIVER_NAME", "nvidia")
hl.env("__GLX_VENDOR_LIBRARY_NAME", "nvidia")
end
elseif o.shell_succeeds(o.shell_quote(nvidia_without_gsp)) then
hl.env("NVD_BACKEND", "egl")
hl.env("__GLX_VENDOR_LIBRARY_NAME", "nvidia")
if nvidia_is_display then
hl.env("__GLX_VENDOR_LIBRARY_NAME", "nvidia")
end
end
end
+35 -3
View File
@@ -7,7 +7,8 @@ source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
tmp_dir=$(mktemp -d)
trap 'rm -rf "$tmp_dir"' EXIT
# Each argument is a PCI device as "vendor:device:class", in sysfs's own format.
# Each argument is a PCI device as "vendor:device:class[:boot_vga]", in sysfs's
# own format. boot_vga is omitted to simulate firmware that lacks the flag.
write_pci_devices() {
rm -rf "$tmp_dir/devices"
mkdir -p "$tmp_dir/devices"
@@ -18,9 +19,12 @@ write_pci_devices() {
local slot
slot=$(printf '0000:%02x:00.0' "$index")
mkdir -p "$tmp_dir/devices/$slot"
printf '%s\n' "${spec%%:*}" >"$tmp_dir/devices/$slot/vendor"
printf '%s\n' "$(cut -d: -f1 <<<"$spec")" >"$tmp_dir/devices/$slot/vendor"
printf '%s\n' "$(cut -d: -f2 <<<"$spec")" >"$tmp_dir/devices/$slot/device"
printf '%s\n' "${spec##*:}" >"$tmp_dir/devices/$slot/class"
printf '%s\n' "$(cut -d: -f3 <<<"$spec")" >"$tmp_dir/devices/$slot/class"
if [[ $spec == *:*:*:* ]]; then
printf '%s\n' "$(cut -d: -f4 <<<"$spec")" >"$tmp_dir/devices/$slot/boot_vga"
fi
index=$((index + 1))
done
}
@@ -54,6 +58,18 @@ assert_detects() {
pass "$description"
}
assert_display() {
local description="$1" expected="$2"
local actual=no
OMARCHY_PCI_DEVICES_PATH="$tmp_dir/devices" "$ROOT/bin/omarchy-hw-nvidia-display" && actual=yes
[[ $actual == "$expected" ]] ||
fail "$description" "omarchy-hw-nvidia-display: expected $expected, got $actual"
pass "$description"
}
# AMD Cezanne integrated graphics.
write_pci_devices 0x1002:0x15e7:0x030000
assert_detects "a machine without an NVIDIA GPU detects nothing" no no no
@@ -97,3 +113,19 @@ assert_detects "a non-display NVIDIA function is not a GPU" no no no
write_pci_devices
assert_detects "a machine with no PCI devices detects nothing" no no no
# AMD Phoenix iGPU drives the display, NVIDIA RTX 3050 is discrete.
write_pci_devices 0x1002:0x15bf:0x030000:1 0x10de:0x25ac:0x030000:0
assert_display "a hybrid laptop with an AMD display GPU is not NVIDIA-driven" no
# Intel Alder Lake iGPU drives the display, NVIDIA Turing is discrete.
write_pci_devices 0x8086:0x46a6:0x030000:1 0x10de:0x1f91:0x030000:0
assert_display "a hybrid Intel+NVIDIA laptop is not NVIDIA-driven" no
# NVIDIA-only desktop keeps the current behavior.
write_pci_devices 0x10de:0x2c02:0x030000:1
assert_display "an NVIDIA-only machine is NVIDIA-driven" yes
# Fixtures without boot_vga preserve the current behavior.
write_pci_devices 0x10de:0x25ac:0x030000
assert_display "missing boot_vga info assumes NVIDIA drives the display" yes