Video accelation va-api on core22

How can i get gpu access for video acceleration inside a snap? I have am building a snap of a flutter application that has widget to play video, but basically i’m having trouble accessing the right video drivers/devices. I already have plugs for opengl/desktop/desktop-classic and using the gnome extension.

I got most of it working, but the error I have indicates that video library that the widget uses (libmpv) wants to access some nvidia vdpau driver that is not available, and so it’s basically just not rendering/displaying the video at this point. I’m using wsl2/wslg for testing and to my understanding default uses a pseudo-driver to translate graphic commands to d3d12 and pass them forward to the windows host.

Because of the pseudo-driver, the driver that mpv was specifically looking for isn’t actually installed on the host nor inside of the snap. Various sources confirm that wsl doesn’t need anything, so I’ve been trying to figure out how i can setup the software to instead use the pseudo-driver (since flutter renders just fine itself). One msdn article (https://devblogs.microsoft.com/commandline/d3d12-gpu-video-acceleration-in-the-windows-subsystem-for-linux-now-available/) stated that video acceleration is was released for vaapi and is working.

I understand that libmpv can be configured to use a specific driver or backend, so I’ve gotten to a point where I’ve configured it to use vaapi by manipulating VDPAU_DRIVER_PATH, HWDEC, LIBVA_DRIVER_NAME.

However the problem I get with that is that it still cannot access the device,

on wsl i can execute this LIBVA_DRIVER_NAME=d3d12 vainfo --display drm --device /dev/dri/card0 and get output similiar to what the msdn article explains, inside of my snap container it tells that it cannot allocate a resource.

libva info: VA-API version 1.14.0
libva info: User environment variable requested driver 'd3d12'
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/d3d12_drv_video.so
libva info: Found init function __vaDriverInit_1_14
libva error: /usr/lib/x86_64-linux-gnu/dri/d3d12_drv_video.so init failed
libva info: va_openDriver() returns 2
vaInitialize failed with error code 2 (resource allocation failed),exit

I’m just not really sure what i can try, anybody have any suggestions?

You might want to check out:

@Lin-Buo-Ren I did check that out, I was quite curious if they did something that i missed but all i see them do is basically install software like libmesa (mesa-core22/snap/snapcraft.yaml at main · canonical/mesa-core22 · GitHub).

But the problem I’m having is that i can’t use valinfo on the d3d12 driver, it works on wsl, but not in the snap container. It might have something do with dynamic module dependencies, wsl stores a bunch of additional modules in /usr/lib/wsl and /lib/wsl

Edit:

So i ended up checking it out with the graphics-test-tools, bind it against the default provider so this gives a very easy reproducable test case. Just spin up wsl, and run this command.

LIBVA_DRIVER_NAME=d3d12 snap run graphics-test-tools.vainfo --display drm --device /dev/dr
i/card0
libva info: VA-API version 1.14.0
libva info: User environment variable requested driver 'd3d12'
libva info: Trying to open /snap/graphics-test-tools/581/graphics/usr/lib/x86_64-linux-gnu/dri//d3d12_drv_video.so
libva info: Found init function __vaDriverInit_1_14
libva error: /snap/graphics-test-tools/581/graphics/usr/lib/x86_64-linux-gnu/dri//d3d12_drv_video.so init failed
libva info: va_openDriver() returns 2
vaInitialize failed with error code 2 (resource allocation failed),exit
Interface                 Plug                                 Slot                         Notes
content[graphics-core22]  graphics-test-tools:graphics-core22  mesa-core22:graphics-core22  -
opengl                    graphics-test-tools:opengl           :opengl                      -
wayland                   graphics-test-tools:wayland          :wayland                     -
x11                       graphics-test-tools:x11              :x11                         -
ls /snap/graphics-test-tools/581/graphics/usr/lib/x86_64-linux-gnu/dri/
crocus_dri.so       i915_dri.so        iris_dri.so        nouveau_drv_video.so  r600_drv_video.so      swrast_dri.so            vmwgfx_dri.so
d3d12_dri.so        i965_drv_video.so  kms_swrast_dri.so  r300_dri.so           radeonsi_dri.so        virtio_gpu_dri.so        zink_dri.so
d3d12_drv_video.so  iHD_drv_video.so   nouveau_dri.so     r600_dri.so           radeonsi_drv_video.so  virtio_gpu_drv_video.so

so it has the same problem I’ve been trying to pin-point so using graphics slot isn’t the awnser, the problem as far as I understand it, is that there’s no guarentee that drivers that are pulled inside of the snap actually match with whatever there is on the host system.

I would check the output of dmesg for apparmor denials or maybe try to strace. If it works without confinement it must be apparmor of cgroups.

As far as i know, the galium driver of wsl2 works fine outside of snap. I am not really that familair with snap/snapcraft to deternine what happens exactly.

I believe though that happens because the galium driver of wsl is a rather unique element and clearly files at non-standard locations, apparmor wont allow access to it, but likely also these paths arent even considered in the base snaps when they recreate a new root.

To my understanding direct host va-api in particulair and to same extend direct host graphics drivers has been requested before, but with graphics snaps (content plugs with drivers) filling in some of the use-cases it just never seem to have happened.

Of course I am always happy to help collect more data, but this is very trivial to reproduce, so might be better that somebody more expierenced just takes a look.

Did you also integrate it into your snap following the instructions in the README ?

It’s been over a month when I first posted the problem but as far as I remember, yes I integrated according to the readme. I’ve tried many different approaches for multiple days in a row.

As mentioned before, I even tested the gpu snaps as-is without integrating it into my own application/snap. The gpu snaps have two “components”: one snap that packs all common gpu drivers and uses the opengl interface to access devices in /dev in addition to that there is also a testbed snap that has common tools that you can use to verify that an gpu snap works.

So a very simple test I ran, manipulating environment variables to select the galium driver and run some va-api info command in the official testbed is enough to fail which on the host works. I traced dlopen calls, comparing those from host and testbed I identified some wsl specific libraries that arent available in the snap.

This already indicates to me that it was broken/restricted on a much lower level than I have access to, i double checked opengl interface code on github and none of the wsl related files are passed through.

The other things I have tried, use opengl interface myself, installing all the drivers and libmesa and galium into my snap, layout remapping to host system using hostfs to make additional wsl folders available.

Just to clarify even documentation of gpu-snap states The graphics-core22 Snap interface

But to support graphical applications, userspace drivers matching the hardware used, and sometimes the kernel, are necessary.

The long-term solution is for SnapD (the daemon managing snaps on your system) to have explicit support for this, and other hardware-specific pieces of software (kernel modules, firmware, udev rules etc.). While this is being worked on, we’ve designed a content interface that allows application snaps to use the graphics hardware by providing the userspace drivers and environment in a content snap.

I believe that these passages directly reflect on my wsl use cases, where you have specific operating system modifications in order for the galium driver to interop with windows/directx, and these need to have matching versions, os modifications, apparmor rules. With a content snap you are just installing and replicating the software, drivers, kind of a temporary solution and the real solution is to actually forward the actual host drivers/binaries.

Well, did you try what alfonso suiggested above and either watched dmesg or used snappy-debug while you try to run vainfo to actually see the potential issues with apparmor rules or host bits ? The kernel will print them for you …

I dont believe I’ve used any of the built-in tools like snappy-debug, i can give that a shot tomorrow.

Can you let me know what your line of thought is on what I should do, basically put gpu snap’s testbed in devmode or classic made and then run va info right, while having snappy-debug active.

@ogra @abeato I had to reinstall my machine so now I’m using a fresh Ubuntu 24.04 with wslg and I did a simple test with sudo snap install --devmode graphics-test-tools. The galium driver instructions followed per msdn I mentioned before.

Here’s a test where I run vainfo that is directly installed on the host ( so no confinment, apparmor, cgroup, chroots etc).

MESA_D3D12_DEFAULT_ADAPTER_NAME=nvidia GALLIUM_DRIVER=d3d12 LIBVA_DRIVER_NAME=d3d12 LD_LIBRARY_PATH=/usr/lib/wsl/lib vainfo --display drm --device /dev/dri/card0
libva info: VA-API version 1.20.0
Xlib:  extension "DRI2" missing on display ":0".
libva info: User environment variable requested driver 'd3d12'
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/d3d12_drv_video.so
libva info: Found init function __vaDriverInit_1_20
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.20 (libva 2.12.0)
vainfo: Driver version: Mesa Gallium driver 25.2.4 - kisak-mesa PPA for D3D12 (NVIDIA GeForce RTX 3060 Laptop GPU)
vainfo: Supported profile and entrypoints
      VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointEncSlice
      VAProfileH264High               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointEncSlice
      VAProfileHEVCMain               : VAEntrypointVLD
      VAProfileHEVCMain               : VAEntrypointEncSlice
      VAProfileHEVCMain10             : VAEntrypointVLD
      VAProfileHEVCMain10             : VAEntrypointEncSlice
      VAProfileVP9Profile0            : VAEntrypointVLD
      VAProfileVP9Profile2            : VAEntrypointVLD
      VAProfileAV1Profile0            : VAEntrypointVLD
      VAProfileNone                   : VAEntrypointVideoProc

And here’s the comparision with vainfo from graphics-test-tools to check for hardware acceleration (provided by gpu-snap, installed in devmode).

MESA_D3D12_DEFAULT_ADAPTER_NAME=nvidia GALLIUM_DRIVER=d3d12 LIBVA_DRIVER_NAME=d3d12 LD_LIBRARY_PATH=/usr/lib/wsl/lib snap run graphics-test-tools.vainfo --display drm --device /dev/dri/card0
libva info: VA-API version 1.20.0
Xlib:  extension "DRI2" missing on display ":0".
libva info: User environment variable requested driver 'd3d12'
libva info: Trying to open /snap/graphics-test-tools/580/gpu-2404/usr/lib/x86_64-linux-gnu/dri//d3d12_drv_video.so
libva info: Found init function __vaDriverInit_1_20
libva error: /snap/graphics-test-tools/580/gpu-2404/usr/lib/x86_64-linux-gnu/dri//d3d12_drv_video.so init failed
libva info: va_openDriver() returns 2
vaInitialize failed with error code 2 (resource allocation failed),exit

Same environment variables, different outcomes. sudo snappy-debug and sudo journalctl -k | grep apparmor shows no messages at all, not when I run the commands and follow the output, not when I try to read it back in the logs. sudo dmesg -w shows this but the messages don’t seem to generate when I run the application, so I think they are just host related.

[ 4248.917656] WSL (263) ERROR: CheckConnection: getaddrinfo() failed: -5
[ 4248.946580] WSL (263) ERROR: CheckConnection: connect() failed: 101

Here’s a test of running mpv directly on the host, and you can see it basically has no problem requesting and obtaining hardware acceleration.

MESA_D3D12_DEFAULT_ADAPTER_NAME=nvidia GALLIUM_DRIVER=d3d12 LIBVA_DRIVER_NAME=d3d12 mpv 5103988-hd_1920_1080_30fps.mp4
 (+) Video --vid=1 (*) (h264 1920x1080 29.970fps)
libEGL warning: failed to get driver name for fd -1

libEGL warning: MESA-LOADER: failed to retrieve device information

libEGL warning: failed to get driver name for fd -1

VO: [gpu] 1920x1080 yuv420p
Exiting... (Quit)
V: 00:00:06 / 00:00:17 (39%)Segmentation fault (core dumped)

Here’s a test that uses normal mpv from a snap, you see it basically fails on hardware acceleration and falls back to software rendering.

MESA_D3D12_DEFAULT_ADAPTER_NAME=nvidia GALLIUM_DRIVER=d3d12 LIBVA_DRIVER_NAME=d3d12  sudo snap run mpv 5103988-hd_1920_1080_30fps.mp4
● Video  --vid=1  (h264 1920x1080 29.97 fps) [default]
[vo/gpu/libplacebo] Found no suitable device, giving up.
[vo/gpu/libplacebo] Failed initializing vulkan device
libEGL warning: DRI3: Screen seems not DRI3 capable
libEGL warning: DRI3: Screen seems not DRI3 capable
MESA: error: ZINK: failed to choose pdev
libEGL warning: egl: failed to create dri2 screen
[vo/gpu/opengl] Suspected software renderer or indirect context.
[vo/gpu/drm] VT_GETMODE failed: Inappropriate ioctl for device
[vo/gpu/drm] Failed to set up VT switcher. Terminal switching will be unavailable.
[vo/gpu/drm] No primary DRM device could be picked!
[vo/gpu/drm] Failed to find a usable DRM primary node!
[vo/gpu-next/libplacebo] Found no suitable device, giving up.
[vo/gpu-next/libplacebo] Failed initializing vulkan device
libEGL warning: DRI3: Screen seems not DRI3 capable
libEGL warning: DRI3: Screen seems not DRI3 capable
MESA: error: ZINK: failed to choose pdev
libEGL warning: egl: failed to create dri2 screen
[vo/gpu-next/opengl] Suspected software renderer or indirect context.
[vo/gpu-next/drm] Can't handle VT release - signal already used
[vo/gpu-next/drm] Failed to set up VT switcher. Terminal switching will be unavailable.
[vo/gpu-next/drm] No primary DRM device could be picked!
[vo/gpu-next/drm] Failed to find a usable DRM primary node!
Failed to open VDPAU backend libvdpau_nvidia.so: cannot open shared object file: No such file or directory
[vo/vdpau] Error when calling vdp_device_create_x11: 1
[vo/xv] No Xvideo support found.
[vaapi] libva: vaGetDriverNames() failed with unknown libva error
[vaapi] Failed to initialize VAAPI: unknown libva error
[vo/x11] Warning: this legacy VO has bad performance. Consider fixing your graphics drivers, or not forcing the x11 VO.
[vaapi] libva: /snap/mpv/233/gpu-2404/usr/lib/x86_64-linux-gnu/dri//d3d12_drv_video.so init failed
[ffmpeg/video] h264: Device does not support the VK_KHR_video_decode_queue extension!
[ffmpeg/video] h264: Failed setup for format vulkan: hwaccel initialisation returned error.
Failed to open VDPAU backend libvdpau_nvidia.so: cannot open shared object file: No such file or directory
VO: [x11] 1920x1080 yuv420p

(process:75750): GLib-GIO-CRITICAL **: 21:45:26.963: g_dbus_connection_emit_signal: assertion 'G_IS_DBUS_CONNECTION (connection)' failed
V: 00:00:03 / 00:00:17 (21%)
Exiting... (Quit)

(process:75750): GLib-GIO-CRITICAL **: 21:45:30.323: g_dbus_connection_emit_signal: assertion 'G_IS_DBUS_CONNECTION (connection)' failed

(process:75750): GLib-GIO-CRITICAL **: 21:45:30.323: g_dbus_connection_unregister_object: assertion 'G_IS_DBUS_CONNECTION (connection)' failed

(process:75750): GLib-GIO-CRITICAL **: 21:45:30.323: g_dbus_connection_unregister_object: assertion 'G_IS_DBUS_CONNECTION (connection)' failed

@ogra @abeato any suggestions?