Skip to content

Scope LIBVA_DRIVER_NAME=nvidia to NVIDIA-driven displays - #10589

Closed
RibatTRW wants to merge 2 commits into
omacom:quattrofrom
RibatTRW:fm/discord-video-grey-screen-diagnosis-99
Closed

RibatTRW wants to merge 2 commits into
omacom:quattrofrom
RibatTRW:fm/discord-video-grey-screen-diagnosis-99

Conversation

@RibatTRW

@RibatTRW RibatTRW commented Sep 7, 2026

Copy link
Copy Markdown

Summary

Fixes grey/black video playback in Chromium and Electron apps (including the Discord webapp) on hybrid AMD+NVIDIA laptops.

Root cause

default/hypr/nvidia.lua exported LIBVA_DRIVER_NAME=nvidia session-wide on
any machine with a GSP-capable NVIDIA GPU, with no check for which GPU drives
the display. On hybrid laptops whose display runs on the AMD iGPU, Chromium
composites on the AMD render node (--render-node-override=/dev/dri/renderD129)
while VA-API resolves to the NVIDIA driver, so every hardware-decoded frame
fails EGL import (eglCreateImage failed with 0x00003009, Failed to create EGLImage, Unable to initialize binding from pixmap). The video clock keeps
running while the video area renders black (seen as grey in Discord).

Fix

  • New detector bin/omarchy-hw-nvidia-display: claims NVIDIA only when an
    NVIDIA GPU owns boot VGA (i.e. NVIDIA actually drives the display), with a
    back-compat fallback that preserves the old behavior when no boot-VGA info
    exists. Follows the existing sysfs-cached-ID detector style (no PCI
    config-space reads that would wake a suspended dGPU).
  • default/hypr/nvidia.lua: gates only the LIBVA_DRIVER_NAME export on the
    new detector. NVD_BACKEND and __GLX_VENDOR_LIBRARY_NAME are untouched
    (verified harmless: playback is green with them still set).
  • test/shell.d/hw-nvidia-test.sh: extended to 14 cases (hybrid AMD+NVIDIA
    with display on AMD, muxed hybrid with display on NVIDIA, NVIDIA-only with
    and without boot-VGA info, plus all pre-existing cases).

Before/after evidence (headed system Chromium, local files, real pixels)

Test loop: headed Chromium on a <video autoplay muted> page, CDP
Page.captureScreenshot, asserting color pixels plus advancing clock.

Case Before (LIBVA_DRIVER_NAME=nvidia, current default) After (override skipped — the fixed config on AMD-display hybrids)
MP4/H.264 RED: clock runs (t 0 → 2.7 s, rs 4), pixels black (saturation 0.0), 90× eglCreateImage failed GREEN: color video (saturation 0.99)
VP9/WebM RED: same signature (saturation 0.0) GREEN (same mechanism; verified via =radeonsi/unset runs)
YouTube (AV1) plays in color — AV1 software-decodes, immune path unchanged
VP9 over HTTP RED (saturation 0.0) — any VP9 served remotely (incl. YouTube when served VP9) fails the same way GREEN expected (same decode path as fixed local case)

Crashed-vs-plays: no GPU-process or tab crash signature was found in any run
(no crash dumps on disk, all tabs stayed alive, video clock kept advancing).
The reported YouTube "crash" reproduces as the same dead (grey/black) video
surface, not a process crash — no separate fault.

Verification

  • ./test/cli: 112/112 green.
  • ./test/shell: 3162 green; 4 failures are pre-existing on the clean base
    and unrelated (command -v in omarchy-remove-ai-*, missing
    omarchy-pkgs checkout in this environment).
  • New detector checked against live sysfs on an affected hybrid laptop
    (RTX 4060 Mobile + AMD HawkPoint, display on AMD): exits 1, so the fixed
    config skips the override there.

On hybrid GPUs whose display runs on another GPU, forcing the NVIDIA VA-API driver breaks hardware video playback in Chromium and Electron (grey/black video with a running clock). Gate the export on a new boot-VGA detector so NVIDIA-only and muxed NVIDIA-display machines keep the override.
@RibatTRW

RibatTRW commented Sep 7, 2026

Copy link
Copy Markdown
Author

Fixes #10590

@remydw

remydw commented Sep 12, 2026

Copy link
Copy Markdown

Reproduced defect in the detector's fallback on real hardware: with this PR applied, the machine below would still export LIBVA_DRIVER_NAME=nvidia and still render black video.

Machine: ROG Zephyrus G14 GA403WW, Ryzen AI 9 HX 370 (Radeon 890M) + RTX 5080 Max-Q, Omarchy 4.0.3-1, Hyprland 0.56.2, mesa 26.2.2, Chrome 153.

NVIDIA  0000:64:00.0  class 0x030000  boot_vga = 0        driver=nvidia
AMD     0000:65:00.0  class 0x038000  boot_vga = ABSENT   driver=amdgpu
        eDP-2 (internal panel) + DP-3 connected on the AMD card;
        every NVIDIA connector (DP-1, HDMI-A-1, eDP-1) is disconnected

Running bin/omarchy-hw-nvidia-display from this PR unmodified against that sysfs:

$ /tmp/det10589.sh; echo "exit=$?"
exit=0        # claims NVIDIA -> LIBVA_DRIVER_NAME=nvidia is exported -> bug persists

Why the fallback fires. The loop only sets other_boot=true for a display device whose boot_vga file is readable and equals 1. The AMD device is a Display controller (class 0x038000) and exposes no boot_vga attribute at all — the attribute is not registered for every display class — so the loop never observes boot_vga=1, other_boot remains false, and the "no boot-VGA information exists → preserve the previous behaviour" branch returns success. But arbitration information does exist here: the NVIDIA device reports boot_vga=0, which is a definite "not me".

Suggested change. Distinguish "no arbitration information" from "arbitration information that excludes NVIDIA": treat any readable boot_vga on a display device as determinable, i.e. claim NVIDIA only when one reads 1, and fall back to the old behaviour only when no display device exposes the attribute at all. Something like:

saw_boot_attr=false
...
  [[ -r $device/boot_vga ]] || continue
  saw_boot_attr=true
  [[ $(< "$device/boot_vga") == 1 ]] || continue
  [[ $(< "$device/vendor") == 0x10de ]] && exit 0
  other_boot=true
...
[[ $saw_boot_attr == false ]] && exit 0   # undeterminable, old behaviour
exit 1

Separately, and worth deciding before merging either approach: boot VGA is not the same as "drives the display". In @Pieter-Uys' desktop case on #8726 the monitor cable is on the NVIDIA card while boot_vga sits on the iGPU, so a boot-VGA test answers "no" while NVIDIA is in fact the renderer. The connected-connector test in #9483 (omarchy-hw-nvidia-drives-display) returns exit 1 on this machine and gives the verified-good session state; A/B numbers for both the broken and fixed environments are in #8726.

A Display-controller (0x038000) peer exposes no boot_vga file, so the
old-behavior fallback fired even when NVIDIA reported boot_vga=0.
Fall back only when no display device exposes the attribute at all,
and cover the G14 (Radeon 890M + RTX 5080) layout with a regression case.
@RibatTRW
RibatTRW force-pushed the fm/discord-video-grey-screen-diagnosis-99 branch from 353369b to 805b206 Compare September 14, 2026 01:03
@RibatTRW

Copy link
Copy Markdown
Author

Applied the fallback fix to this PR — thank you for the precise reproduction.

What changed (bin/omarchy-hw-nvidia-display): the loop now records saw_boot_attr=true for any display device with a readable boot_vga, and the back-compat fallback fires only when no display device exposes the attribute at all ([[ $saw_boot_attr == "false" ]] && exit 0, previously other_boot). A readable boot_vga=0 on NVIDIA now counts as determinable arbitration info that excludes NVIDIA, so the detector exits 1 and the LIBVA_DRIVER_NAME override is skipped on your G14 layout.

Regression test (test/shell.d/hw-nvidia-test.sh): new case with an AMD 0x038000 device exposing no boot_vga alongside NVIDIA 0x030000 with boot_vga=0, expecting no NVIDIA display claim — verified it fails on the unfixed detector and passes with the fix, with all 14 existing cases unchanged.

Out of scope: a machine exposing no boot_vga on any display device (e.g. 0x0302 NVIDIA dGPU + 0x0380 AMD iGPU) still takes the back-compat fallback — that genuinely-undeterminable case is left for the connector-signal work.

@bjarneo

bjarneo commented Sep 20, 2026

Copy link
Copy Markdown
Member

Automated duplication check: this pull request looks similar to #7851, which covers the same LIBVA-only NVIDIA gating on hybrid-GPU systems. I keep that one open and close this one to consolidate review.

If you feel this is the wrong decision, please open the PR again with a note on the difference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants