Playing around with virtio-gpu

Recently I played around with QEMU+KVM and virtio-gpu and am surprised how well it works nowadays, especially with venus (Vulkan).

The setup:
CPU: AMD 7950X3D
RAM: 64GB RAM
GPU: AMD 9070XT 16GB
OS: Arch Linux (Kernel 6.16)

I tried venus and drm_native_context in an Arch and an Ubuntu 25.04 guest.

Sadly kernel 6.16 seems to have an issue so the required drm host_visible feature was not available on Arch and I gave up on that guest system for the time being.

For drm_native_context I had to rebuild virglrenderer + qemu on host and mesa inside the guest system. They all required extra compile configs/patches that I gathered from the QEMU drm_native_context patchsets:

In the end I was able to successfully run accelerated vkcube in the Ubuntu guest but more complex applications crashed I changed to venus.

venus was much simpler and basically worked out of the box with Ubuntu. No patches or anything special needed.

Running Half-Life 2 I got ~300FPS but somehow my mouse look stopped working in-game. This seems to be more of an issue with QEMU and not so much the acceleration, though. Other 3D games also suffered from this issue. Using a passthrough USB mouse works fine, but the cursor is invisible on desktop. Again I think in my case this is an issue with QEMU and not virtio-gpu.

Running llama.cpp with Vulkan backend inside a container on the VM gave me a good boost in token generation (CPU: 1.33t/s, GPU: 27.43t/s) for Qwen3-4B-Instruct-2507-Q8 and it worked really well. The FP16 version still achieved ~20t/s.
At first I thought you have to provide a subset of memory to the VM and QEMU requires it to be a power of 2 so I would be limited to 8GB, but it also did not complain just allowing the full 16GB of my card.

Overall I’m super impressed by the results. I am new to QEMU and KVM and also learned a lot doing this.

2 Likes

I’ve just spent the evening looking into venus for a VM I’m running. What got me started on the path was turning on VirGL for the first time in a few months. I was delighted to see that an issue was solved where the the guest VM was filling the frame buffer of my host pc GPU with garbage data. So I ran a few tests to ensure I wasn’t seeing that behavior anymore. Throughout the process I was running furmark GL with no issue but Furmark VK exits render window immediately. So down the rabbit hole of thread posts I went to discover venus and I am looking forward to a decent primer on getting around the GUI limitations of QEMU. As far as I’ve read the only way to get the venus feature enabled is through the command line injection supported by QEMU. Do you know if that information is still accurate? Is there a more direct way to get the arguments passed into the .xml config of an already configured VM? I’m just curious of what you had to do to get going. Thanks for your post

1 Like

I tried adjusting the XML but it did not work. So for now I simply start the VMs with shell scripts.

#!/bin/env bash
export XDG_RUNTIME_DIR=/run/user/1000
export WAYLAND_DISPLAY=wayland-1

DISK="${DISK:-arch-vm-1.qcow2}"

qemu-system-x86_64 \
  -cpu host \
  -smp $(nproc) \
  -nodefaults \
  -usb \
  -device usb-tablet \
  -netdev bridge,id=vm0,br=br0 \
  -device virtio-net-pci,netdev=vm0 \
  -device virtio-vga-gl,hostmem=8G,blob=on,venus=on \
  -audio driver=sdl,model=virtio \
  -machine q35,accel=kvm,memory-backend=mem1 \
  -object memory-backend-memfd,id=mem1,size=16G \
  -display sdl,gl=on \
  -vga none \
  -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/x64/OVMF_CODE.4m.fd \
  -drive if=pflash,format=raw,file=$HOME/vm/OVMF_VARS.4m.fd \
  -drive file=$HOME/vm/$DISK,format=qcow2,if=virtio \
  $@