Skip to content

Hybrid laptops: nvidia.lua sets LIBVA_DRIVER_NAME=nvidia session-wide even when the iGPU is the compositing device, breaking Chromium video #12704

Closed

Description

@ironxp

Summary

On a hybrid laptop where Hyprland and Chromium composite on the Intel iGPU,
default/hypr/nvidia.lua exports LIBVA_DRIVER_NAME=nvidia and
__GLX_VENDOR_LIBRARY_NAME=nvidia for the whole session, based only on "an
NVIDIA GPU exists". Chromium then decodes video through NVDEC on the dGPU but
composites on the iGPU, and cannot import the decoded frames as EGLImages.

Every frame fails, and video playback collapses. Measured on this machine:
~9 fps (193 unique frames out of 1292 in a 21.5 s screen recording of a
Vimeo player that should run at 24–30 fps).

This affects Chromium, Brave, Edge and every Omarchy web app launched through
omarchy-launch-webapp, out of the box. Firefox is unaffected because it uses
native EGL with DMABUF and does not go through the GLX vendor.

Reproduction

Hybrid laptop, Intel iGPU driving the internal panel, NVIDIA dGPU present:

$ lspci -nn | grep -iE "vga|3d"
00:02.0 VGA compatible controller: Intel Arrow Lake-S [8086:7d67]
02:00.0 VGA compatible controller: NVIDIA GB203M / RTX 5080 Max-Q [10de:2c59]

$ printenv LIBVA_DRIVER_NAME __GLX_VENDOR_LIBRARY_NAME
nvidia
nvidia

Chromium picks the iGPU to composite (as reported by chrome://gpu):

GPU0: VENDOR=0x10de, DEVICE=0x2c59, DRIVER_VENDOR=Mesa
GPU1: VENDOR=0x8086, DEVICE=0x7d67, DRIVER_VENDOR=Mesa  *ACTIVE*
Command Line: ... --render-node-override=/dev/dri/renderD129     (= the Intel)

Play any video. The log fills with, per frame:

ERROR:ui/gl/angle_platform_impl.cc:48] ImageEGL.cpp:118 (operator()):
    eglCreateImage failed with 0x00003009
ERROR:ui/gl/scoped_egl_image.cc:23] Failed to create EGLImage: EGL_SUCCESS
ERROR:ui/ozone/common/native_pixmap_egl_binding.cc:76]
    Unable to initialize binding from pixmap
ERROR:gpu/command_buffer/service/shared_image/ozone_image_backing.cc:320]
    OzoneImageBacking::ProduceSkiaGanesh failed to create GL representation
ERROR:gpu/command_buffer/service/shared_image/shared_image_manager.cc:269]
    SharedImageManager::ProduceSkia: Trying to produce a Skia representation
    from an incompatible backing: CompoundImageBacking

0x3009 is EGL_BAD_MATCH: the NVDEC-produced buffer cannot be imported on
the Intel device.

Launching the same Chromium with those variables removed produces zero EGL,
ANGLE, Ozone or Skia errors, and video plays smoothly:

env -u LIBVA_DRIVER_NAME -u NVD_BACKEND -u __GLX_VENDOR_LIBRARY_NAME chromium

Root cause

bin/omarchy-hw-nvidia and bin/omarchy-hw-nvidia-gsp answer only
"does an NVIDIA GPU exist?" — they walk /sys/bus/pci/devices looking for
vendor 0x10de with a display class. Neither asks which device actually
drives the outputs or hosts the compositor.

default/hypr/nvidia.lua then acts on that alone:

if o.shell_succeeds(o.shell_quote(nvidia)) then
  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")
  ...

On a desktop with a single NVIDIA card this is right. On a hybrid laptop with
nvidia-open-dkms and the iGPU compositing, it points VA-API and the GLX
vendor at a device that is not the one presenting frames.

Note that both variables matter independently — verified by elimination on this
machine:

Variables changed Result
__GLX_VENDOR_LIBRARY_NAME unset only still broken, same EGL_BAD_MATCH
LIBVA_DRIVER_NAME=iHD only still broken
all three unset clean logs, smooth playback

Suggested fix

Gate the exports on the NVIDIA GPU actually being the compositing/primary
device, rather than merely present. A cheap check is whether any connected
DRM connector belongs to the NVIDIA PCI device:

for c in /sys/class/drm/card*-*/status; do
  [[ $(< "$c") == connected ]] || continue
  v=$(< "$(dirname "$c")/../device/vendor")
  [[ $v == 0x10de ]] && exit 0     # NVIDIA drives at least one output
done
exit 1

On this machine that distinction is visible and unambiguous:

card0-eDP-2 -> INTEL    (internal panel, and what the compositor runs on)
card1-DP-1  -> NVIDIA   (external monitor)

Even here, with an external monitor on the NVIDIA connector, Chromium still
composites on the Intel — so "an output is wired to the dGPU" is not by itself
a reason to force VA-API onto it.

A narrower alternative: keep __GLX_VENDOR_LIBRARY_NAME as-is but stop
exporting LIBVA_DRIVER_NAME on hybrid systems, letting libva autodetect per
device. That alone was not sufficient here, so the GLX vendor needs handling
too.

Users can work around it today by overriding in their own config, which loads
after the defaults:

-- ~/.config/hypr/autostart.lua
hl.env("LIBVA_DRIVER_NAME", "iHD")
hl.env("__GLX_VENDOR_LIBRARY_NAME", "mesa")

Environment

Omarchy 4.0.4-1
Hyprland 0.56.2 (efb5099)
Kernel 7.2.5-3-omarchy
Machine Lenovo Legion Pro 7 16IAX10H
iGPU Intel Arrow Lake-S 8086:7d67, Mesa 26.2.2
dGPU NVIDIA RTX 5080 Max-Q 10de:2c59, nvidia-open-dkms 610.57.04
Chromium 152.0.7977.82-1
Drivers libva-nvidia-driver, intel-media-driver 26.2.4 both installed

Activity

  1. andyholst commented on Sep 22, 2026

    @andyholst

    Duplicate of #8215 — same root cause (nvidia.lua forces LIBVA_DRIVER_NAME=nvidia on hybrid laptops). See that issue for full details, regression history, and workaround.

    Local fix: browser launchers export LIBVA_DRIVER_NAME=iHD + MESA_LOADER_DRIVER_OVERRIDE=iris scoped to browser processes only (system stays on NVIDIA for games/CUDA).

  2. added
    bugSomething isn't working
    compatibilityMake Omarchy work better on everything!
    on Sep 27, 2026
  3. jandrusk commented on Oct 8, 2026

    @jandrusk

    Thanks for the detailed measurements. This is fixed on quattro by #11690 (merged Sep 24). default/hypr/nvidia.lua now only exports LIBVA_DRIVER_NAME / __GLX_VENDOR_LIBRARY_NAME when omarchy-hw-nvidia-display says NVIDIA actually drives the display. It isn't in 4.0.4 yet, so your autostart.lua override is the workaround until the next release. This is the same issue as #8215, #11173, #12500, #12594 and #12674, which can all be closed along with this one once the fix ships.

  4. omarchybot commented on Oct 12, 2026

    @omarchybot
    Collaborator

    This is fixed on quattro, though not in a release yet, and one question about your machine decides whether that fix is enough for it.

    #11690 (merged 2026-09-25, after v4.0.4) adds bin/omarchy-hw-nvidia-display, and default/hypr/nvidia.lua now exports LIBVA_DRIVER_NAME and __GLX_VENDOR_LIBRARY_NAME only when that detector says NVIDIA drives the display. It decides from sysfs boot_vga: when a non-NVIDIA GPU has boot_vga=1 and no NVIDIA GPU does, both variables are left unset. It does not look at connectors, so your external monitor on the NVIDIA DP-1 does not by itself turn them back on. NVD_BACKEND=direct is still exported unconditionally, on the reasoning that it is only read by the NVIDIA VA-API driver, which libva should no longer load once LIBVA_DRIVER_NAME is unset and Chromium is on the Intel render node. Your elimination table removed all three at once, so it does not tell us whether that reasoning holds on your machine. Two things would settle it:

    1. cat /sys/bus/pci/devices/0000:00:02.0/boot_vga /sys/bus/pci/devices/0000:02:00.0/boot_vga — the fix covers you if the first prints 1 and the second 0.
    2. env -u LIBVA_DRIVER_NAME -u __GLX_VENDOR_LIBRARY_NAME chromium, leaving NVD_BACKEND set, and whether video plays cleanly with no eglCreateImage errors. That is the environment the fix gives you.

    Until the next release, your autostart.lua override remains the workaround. The same bug is tracked with many other hybrid machines in #8215.

    Checked by reading the issue, #8215 and #11690 against quattro at defbf90e8; nothing was run, since this needs your hardware. Classified as a hardware compatibility bug by Claude Opus 5.5 and DeepSeek V4.1 Flash, which agreed. Codex at medium effort reviewed whether this duplicates #8215 and declined to call it one, because your report shows that LIBVA_DRIVER_NAME=iHD alone was not enough and that NVD_BACKEND is the one variable the fix leaves in place; that is why this stays open for your answer rather than being closed.

  5. emirb commented on Oct 18, 2026

    @emirb
    Contributor

    Fixed in Omarchy 4.0.5 by #11690. Update with omarchy update (or Update > Omarchy). If it still happens on 4.0.5, comment here and we'll reopen.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcompatibilityMake Omarchy work better on everything!

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions