Robert Foss
February 12, 2018
Reading time:
Virtualized GPU access is becoming common in the containerized and virtualized application space. Let's have a look at why and how.
For the past few years a clear trend of containerization of applications and services has emerged. Having processes containerized is beneficial in a number of ways. It both improves portability and strengthens security, and if done properly the performance penalty can be low.
In order to further improve security containers are commonly run in virtualized environments. This provides some new challenges in terms of supporting the accelerated graphics usecase.
Currently Collabora and Google are implementing OpenGL ES 2.0 support. OpenGL ES 2.0 is the lowest common denominator for many mobile platforms and as such is a requirement for Virgil3D to be viable on the those platforms.
That is is the motivation for making Virgil3D work on OpenGL ES hosts.
This stack is commonly referred to as Virgil3D, since all of the parts originated from a project with that name.
There are a few parts to this implementation.
QEMU, virglrenderer and virtio-gpu. The way it works is by letting the guest applications speak unmodified OpenGL to the Mesa. But instead of Mesa handing commands over to the hardware it is channeled through virtio-gpu on the guest to QEMU on the host.
QEMU then receives the raw graphics stack state (Gallium state) and interprets it using virglrenderer from the raw state into an OpenGL form, which can be executed as entirely normal OpenGL on the host machine.
The host OpenGL stack does not even have to be Mesa, and could for example be the proprietary nvidia stack.
First of all, let's have a look at the development environment. When doing graphical development I find it quite helpful to set up a parallel graphics stack in order to not pollute or depend on the stack of the host machine more than we have to.
function add_export_env { local VAR="$1" shift local VAL=$(eval echo "\$$VAR") if [ "$VAL" ]; then VAL=$(concatenate_colon "$@" "$VAL"); else VAL=$(concatenate_colon "$@"); fi eval "export $VAR=\"$VAL\"" } function prefix_setup { local PREFIX="$1" add_export_env PATH "$PREFIX/bin" add_export_env LD_LIBRARY_PATH "$PREFIX/lib" add_export_env PKG_CONFIG_PATH "$PREFIX/lib/pkgconfig/" "$PREFIX/share/pkgconfig/" add_export_env MANPATH "$PREFIX/share/man" export ACLOCAL_PATH="$PREFIX/share/aclocal" mkdir -p "$ACLOCAL_PATH" export ACLOCAL="aclocal -I $ACLOCAL_PATH" } function projectshell { case "$1" in virgl | virglrenderer) export ALT_LOCAL="/opt/local/virgl" mkdir -p "$ALT_LOCAL" prefix_setup "$ALT_LOCAL" ;; esac }
The above snippet is something that I would put in my .bashrc or .zshrc. Don't forget so run source ~/.bashrc or the equivalent after making changes.
To enter the environment I simply type projectshell virgl.
libepoxy is a library for managing OpenGL function pointers for you. And it is a dependency of virglrenderer, which we'll get to below.
git clone https://github.com/anholt/libepoxy.git cd libepoxy ./autogen.sh --prefix=$ALT_LOCAL make -j$(nproc --ignore=1) make install
Virgilrenderer is the component that QEMU uses to provide accelerated rendering.
It receives Gallium states from the guest kernel via its virtio-gpu interface, which are then translated into OpenGL on the host. It also translates shaders from the TGSI format used by Gallium into the GLSL format used by OpenGL.
git clone git://anongit.freedesktop.org/virglrenderer cd virglrenderer ./autogen.sh --prefix=$ALT_LOCAL make -j$(nproc --ignore=1) make install
libpciaccess is a library for simplifying accessing devices on the PCI bus.
It is a dependency of Mesa, which we'll get to below.
git clone git://git.freedesktop.org/git/xorg/lib/libpciaccess cd libpciaccess ./autogen.sh --prefix=$ALT_LOCAL make -j$(nproc --ignore=1) make install
# Fetch dependencies
sudo sed -i 's/\#deb-src/deb-src/' /etc/apt/sources.list
sudo apt update
sudo apt-get build-dep mesa
# Actually build Mesa
git clone https://anongit.freedesktop.org/git/mesa/mesa.git
cd mesa
./configure \
--prefix=$ALT_LOCAL \
--enable-driglx-direct \
--enable-gles1 \
--enable-gles2 \
--enable-glx-tls \
--with-egl-platforms='drm x11 wayland' \
--with-dri-drivers="i915 i965 nouveau" \
--with-gallium-drivers="nouveau swrast radeonsi"
make -j$(nproc --ignore=1)
make install
git clone git://git.qemu.org/qemu.git
cd qemu
./configure \
--prefix=$ALT_LOCAL \
--target-list=x86_64-softmmu \
--enable-kvm \
--disable-werror \
--enable-virglrenderer
make -j$(nproc --ignore=1)
make install
As a guest we're going to use Ubuntu 17.10, but just use the latest release of whatever distro you like. The kernel has have been built with the appropriate virtio-gpu Kconfig options though.
wget http://releases.ubuntu.com/17.10/ubuntu-17.10.1-server-amd64.iso
qemu-img create -f qcow2 ubuntu.qcow2 35G
qemu-system-x86_64 \
-enable-kvm -M q35 -smp 2 -m 4G \
-hda ubuntu.qcow2 \
-net nic,model=virtio \
-net user,hostfwd=tcp::2222-:22 \
-vga virtio \
-display sdl,gl=on \
-boot d -cdrom ubuntu-17.10.1-desktop-amd64.iso
qemu-system-x86_64 \
-enable-kvm -M q35 -smp 2 -m 4G \
-hda ubuntu.qcow2 \
-net nic,model=virtio \
-net user,hostfwd=tcp::2222-:22 \
-vga virtio \
-display sdl,gl=on
Et Voila! Your guest should now have GPU acceleration!
Hopefully this guide will have helped you to build all of the software needed to set up your very own virglrenderer enabled graphics stack.
Visit Robert's blog.
02/03/2026
Get the recap of Nicolas Frattaroli's FOSDEM talk detailing Rockchip’s mainline progress, including Vulkan 1.4 and NPU support as a vital…
02/12/2025
As an active member of the freedesktop community, Collabora was busy at XDC 2025. Our graphics team delivered five talks, helped out in…
24/11/2025
LE Audio introduces a modern, low-power, low-latency Bluetooth® audio architecture that overcomes the limitations of classic Bluetooth®…
17/11/2025
Collabora’s long-term leadership in KernelCI has delivered a completely revamped architecture, new tooling, stronger infrastructure, and…
11/11/2025
Collabora extended the AdobeVFR dataset and trained a FasterViT-2 font recognition model on millions of samples. The result is a state-of-the-art…
31/10/2025
Collabora has advanced Monado's accessibility by making the OpenXR runtime supported by Google Cardboard and similar mobile VR viewers so…
Add a Comment