Skip to content

Instantly share code, notes, and snippets.

@peppergrayxyz
Last active August 15, 2025 14:29
Show Gist options
  • Save peppergrayxyz/fdc9042760273d137dddd3e97034385f to your computer and use it in GitHub Desktop.
Save peppergrayxyz/fdc9042760273d137dddd3e97034385f to your computer and use it in GitHub Desktop.
QEMU with VirtIO GPU Vulkan Support

QEMU with VirtIO GPU Vulkan Support

With its latest reales qemu added the Venus patches so that virtio-gpu now support venus encapsulation for vulkan. This is one more piece to the puzzle towards full Vulkan support.

An outdated blog post on clollabora described in 2021 how to enable 3D acceleration of Vulkan applications in QEMU through the Venus experimental Vulkan driver for VirtIO-GPU with a local development environment. Following up on the outdated write up, this is how its done today.

Definitions

Let's start with the brief description of the projects mentioned in the post & extend them:

  • QEMU is a machine emulator
  • VirGL is an OpenGL driver for VirtIO-GPU, available in Mesa.
  • Venus is an experimental Vulkan driver for VirtIO-GPU, also available in Mesa.
  • Virglrenderer is a library that enables hardware acceleration to VM guests, effectively translating commands from the two drivers just mentioned to either OpenGL or Vulkan.
  • libvirt is an API for managing platform virtualization
  • virt-manager is a desktop user interface for managing virtual machines through libvirt

Merged Patches:

Work in progress:

Prerequisites

Make sure you have the proper version installed on the host:

  • linux kernel >= 6.13 built with CONFIG_UDMABUF
  • working Vulkan and kvm setup
  • qemu >= 9.2.0
  • virglrenderer with enabled venus support
  • mesa >= 24.2.0

You can verify this like so:

$ uname -r
6.13.0
$ ls /dev/udmabuf
/dev/udmabuf
$ ls /dev/kvm
/dev/kvm
$ qemu-system-x86_64 --version
QEMU emulator version 9.2.0
Copyright (c) 2003-2024 Fabrice Bellard and the QEMU Project developers

Check your distros package sources how they build virglrenderer.

For Vulkan to work you need the proper drivers to be installed for your graphics card.

To verfiy your setup, install vulkan-tools. Make sure mesa >= 24.2.0 and test vkcube:

$ vulkaninfo --summary | grep driverInfo
	driverInfo         = Mesa 24.2.3-1ubuntu1
	driverInfo         = Mesa 24.2.3-1ubuntu1 (LLVM 19.1.0)
...
$ vkcube
Selected GPU x: ..., type: ...

Building qemu

If your distro doesn't (yet) ship and updated version of qemu, you can build it yourself from source:

wget https://download.qemu.org/qemu-9.2.0.tar.xz
tar xvJf qemu-9.2.0.tar.xz
cd qemu-9.2.0
mkdir build && cd build
../configure --target-list=x86_64-softmmu  \
  --enable-kvm                 \
  --enable-opengl              \
  --enable-virglrenderer       \
  --enable-gtk                 \
  --enable-sdl
make -j4

The configuration step will throgh errors if packages are missing. Check the qemu wiki for further info what to install: https://wiki.qemu.org/Hosts/Linux

Create and run an image for QEMU

Create an image & fetch the distro of your choice:

Host

ISO=ubuntu-24.10-desktop-amd64.iso  
wget https://releases.ubuntu.com/oracular/ubuntu-24.10-desktop-amd64.iso  

IMG=ubuntu-24-10.qcow2
qemu-img create -f qcow2 $IMG 16G

Run a live version or install the distro

qemu-system-x86_64                                               \
    -enable-kvm                                                  \
    -M q35                                                       \
    -smp 4                                                       \
    -m 4G                                                        \
    -cpu host                                                    \
    -net nic,model=virtio                                        \
    -net user,hostfwd=tcp::2222-:22                              \
    -device virtio-vga-gl,hostmem=4G,blob=true,venus=true        \
    -vga none                                                    \
    -display gtk,gl=on,show-cursor=on                            \
    -usb -device usb-tablet                                      \
    -object memory-backend-memfd,id=mem1,size=4G                 \
    -machine memory-backend=mem1                                 \
    -hda $IMG                                                    \
    -cdrom $ISO                                                  

Adjust the parameters accordingly:

  • smp: number of cpu cores
  • m: RAM
  • hostmem,size: VRAM

Guest

Install mesa-utilites and vulkan-tools to test the setup:

$ glxinfo -B
$ vkcube
Selected GPU x: ..., type: ...

If the deive is llvmpipe somehting is wrong. The device should be virgl (...).

Troubleshooting

  • (host) add -d guest_errors to show error messages from the guest
  • (guest) try installing vulkan virtio drivers and mesa
  • check the original blog post

Ubuntu 24.10

This is how you do it on Ubuntu

kernel

Install mainline: https://github.com/bkw777/mainline

sudo add-apt-repository ppa:cappelikan/ppa
sudo apt update
sudo apt install mainline

find the latest kernel (>= 6.13), at the time of writing 6.13 is a release candidate, so include those:

$ mainline check --include-rc

Install kernel:

$ sudo mainline install 6.13-rc1

Verfify installed kernels:

$ mainline list-installed
mainline 1.4.10
Installed Kernels:
linux-image-6.11.0-13-generic
linux-image-generic-hwe-24.04
linux-image-unsigned-6.13.0-061300rc1-generic
mainline: done

reboot into new kernel

verify running kernel

$ uname -r
6.13.0-061300rc1-generic

virglrenderer

the ubuntu package is not compiled with the proper flags.

If installed remove it: $ sudo apt-get remove libvirglrenderer-dev

download, build & install from source with venus enabled

wget    https://gitlab.freedesktop.org/virgl/virglrenderer/-/archive/1.1.0/virglrenderer-1.1.0.tar.gz
sudo apt-get install python3-full ninja-build libvulkan-dev libva-dev
python3 -m venv venv
venv/bin/pip install meson
venv/bin/meson build -Dvideo=true -Dvenus=true
ninja -C build
ninja install

qemu

install qemu >= 9.2.0, at the time of writing ubuntu has not yet packaged it

Install build depdencies: https://wiki.qemu.org/Hosts/Linux

sudo apt-get install build-essential pip libslirp-dev slirp
sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-build
sudo apt-get install git-email
sudo apt-get install libaio-dev libbluetooth-dev libcapstone-dev libbrlapi-dev libbz2-dev
sudo apt-get install libcap-ng-dev libcurl4-gnutls-dev libgtk-3-dev
sudo apt-get install libibverbs-dev libjpeg8-dev libncurses5-dev libnuma-dev
sudo apt-get install librbd-dev librdmacm-dev
sudo apt-get install libsasl2-dev libsdl2-dev libseccomp-dev libsnappy-dev libssh-dev
sudo apt-get install libvde-dev libvdeplug-dev libvte-2.91-dev libxen-dev liblzo2-dev
sudo apt-get install valgrind xfslibs-dev 
sudo apt-get install libnfs-dev libiscsi-dev

build and run as described

virt-manager

-- work in progress --

Currently this is work in progress, so there is no option to add vulkan support in virt-manager. There are no fields to configure this. Also xml doesnt work, because libvirt doesn't know about these options either, so xml validation fails. There is however an option for QEMU command-line passthrough which bypasses the validation.

If you setup a default machine with 4G of memory, you can do this:

  <qemu:commandline>
    <qemu:arg value="-device"/>
    <qemu:arg value="virtio-vga-gl,hostmem=4G,blob=true,venus=true"/>
    <qemu:arg value="-object"/>
    <qemu:arg value="memory-backend-memfd,id=mem1,size=4G"/>
    <qemu:arg value="-machine"/>
    <qemu:arg value="memory-backend=mem1"/>
    <qemu:arg value="-vga"/>
    <qemu:arg value="none"/>
  </qemu:commandline>

Which gives this error:

qemu-system-x86_64: virgl could not be initialized: -1

Changing the number from 4G to 4194304k (same as memory) leds to this error:

qemu-system-x86_64: Spice: ../spice-0.15.2/server/red-qxl.cpp:435:spice_qxl_gl_scanout: condition `qxl_state->gl_draw_cookie == GL_DRAW_COOKIE_INVALID' failed

to be further investigated.

@zzyiwei
Copy link

zzyiwei commented Jul 27, 2025

As of now, the pieces left are all in QEMU:

  1. pending qemu maintainer's pull of the venus fencing fix to land in-tree and stable backport: https://lore.kernel.org/all/[email protected]/
  2. KVM_X86_QUIRK_IGNORE_GUEST_PAT has landed in-tree, now pending qemu to opt-out the quirk: https://gitlab.com/qemu-project/qemu/-/issues/2943

An update here: the (1) venus fencing fix has been included in QEMU 10.0.3 stable release (and later).

Small tip: if your app is with x11 and presenting via Xwayland, feel free to add venus_implicit_fencing=true in your app's launch env vars for some robust perf gains.

@hashraf91
Copy link

Hi @zzyiwei , I have been following this thread for quite some time. It has been very helpful to make vulkan graphical working with venus.

Although vulkan graphical is working fine, but I wanted to report one issue for vulkan headless with venus. I am facing this issue:

VK_DRIVER_FILES=/usr/share/vulkan/icd.d/virtio_icd.aarch64.json vkmark --winsys headless
=======================================================
    vkmark 2025.01
=======================================================
    Vendor ID:      0x10DE
    Device ID:      0x1FB9
    Device Name:    Virtio-GPU Venus (Quadro T1000)
    Driver Version: 104857699
    Device UUID:    0c5ea8f4d04d9fe32900576ce04c019e
=======================================================
[vertex] device-local=true:Segmentation fault (core dumped)

I traced it back to this commit in mesa: https://gitlab.freedesktop.org/mesa/mesa/-/commit/e980123293c8b976b7e7139a449858428091eee1. Can you provide some insights what could be causing this? Here is the debug logs for vkmark: https://gist.github.com/hashraf91/cad890a7c784d95cdc2c8baaf9b896a4. Let me know if you need any more details.

My setup:
host: Ubuntu-25
guest: Ubuntu-25
Mesa: 25.2.0-rc2 (both on guest and host)
GPU: Nvidia (Quadro T1000)
CPU: Intel, Ubuntu Kernel 6.14.0-*-generic with patch applied (KVM: VMX: Always honor guest PAT on CPUs that support self-snoop)

@zzyiwei
Copy link

zzyiwei commented Jul 31, 2025

@nuqleo
Copy link

nuqleo commented Aug 15, 2025

Hi,

I have a working Venus configuration with kernel 6.15.9, QEMU 10.0.3, Intel video card on Fedora 43
[ 1.218540] [drm] features: +virgl +edid +resource_blob +host_visible

But with kernel kernel 6.16.0 in this vm the same configuration does not work
[ 1.083102] [drm] features: +virgl +edid +resource_blob -host_visible

In vkcube
MESA-VIRTIO: debug: one of required kernel params (4 or 9) is missing

Has anyone encountered this problem with the new kernel?

@RushingAlien
Copy link

Yes i'm experiencing this as well, might wanna try to downgrade kernel

@zzyiwei
Copy link

zzyiwei commented Aug 15, 2025

Do you mind attaching the dmesg before it claims missing the required host_visible one?

@RushingAlien
Copy link

RushingAlien commented Aug 15, 2025

filtered 10 lines before host_visible

[demo-user@archlinux ~]$ sudo dmesg | grep -B10 host_visible
[    2.057465] systemd-journald[213]: Received client request to flush runtime journal.
[    2.659192] lpc_ich 0000:00:1f.0: I/O space for GPIO uninitialized
[    2.672793] [drm] pci: virtio-vga detected at 0000:00:01.0
[    2.682474] virtio_scsi virtio7: 8/0/0 default/read/poll queues
[    2.683201] input: QEMU Virtio Keyboard as /devices/pci0000:00/0000:00:03.0/0000:0a:00.0/virtio8/input/input1
[    2.685589] input: PC Speaker as /devices/platform/pcspkr/input/input2
[    2.688199] Console: switching to colour dummy device 80x25
[    2.701378] i801_smbus 0000:00:1f.3: Enabling SMBus device
[    2.701468] i801_smbus 0000:00:1f.3: SMBus using PCI interrupt
[    2.703188] virtio-pci 0000:00:01.0: vgaarb: deactivate vga console
[    2.703294] [drm] features: +virgl +edid +resource_blob -host_visible

filtered drm and virtio-vga

[demo-user@archlinux ~]$ sudo dmesg | grep -v virtiofs |grep -E 'drm|virtio-vga' 
[    0.736591] ACPI: bus type drm_connector registered
[    0.748833] simple-framebuffer simple-framebuffer.0: [drm] Registered 1 planes with drm panic
[    0.748838] [drm] Initialized simpledrm 1.0.0 for simple-framebuffer.0 on minor 0
[    0.754522] simple-framebuffer simple-framebuffer.0: [drm] fb0: simpledrmdrmfb frame buffer device
[    1.822447] systemd[1]: Starting Load Kernel Module drm...
[    1.914138] systemd[1]: [email protected]: Deactivated successfully.
[    1.914348] systemd[1]: Finished Load Kernel Module drm.
[    2.672793] [drm] pci: virtio-vga detected at 0000:00:01.0
[    2.703294] [drm] features: +virgl +edid +resource_blob -host_visible
[    2.703298] [drm] features: +context_init
[    2.708449] [drm] number of scanouts: 1
[    2.708456] [drm] number of cap sets: 3
[    2.717072] [drm] cap set 0: id 1, max-version 1, max-size 308
[    2.717436] [drm] cap set 1: id 2, max-version 2, max-size 1408
[    2.717511] [drm] cap set 2: id 4, max-version 0, max-size 160
[    2.727616] virtio-pci 0000:00:01.0: [drm] Registered 1 planes with drm panic
[    2.727622] [drm] Initialized virtio_gpu 0.1.0 for 0000:00:01.0 on minor 1
[    2.732792] fbcon: virtio_gpudrmfb (fb0) is primary device
[    2.755994] virtio-pci 0000:00:01.0: [drm] fb0: virtio_gpudrmfb frame buffer device

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