Skip to end of banner
Go to start of banner

Building QEMU with virtio-gpu and rutabaga_gfx

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »

Building QEMU with virtio-gpu and rutabaga_gfx

Date: on 2023-11-22

virtio-gpu-rutabaga device is available in QEMU 8.2 release candidates and later versions.

1. Install Debian host system dependencies

You might have to install more if you haven't built QEMU before on the host.

apt install -y {libpulse,libdrm,libglm,libstb,libegl,libgles,libvulkan,vulkan-validationlayers}-dev 

2. Build qemu

git clone https://gitlab.com/qemu-project/qemu.git

Checkout master or a 8.2 tagged release.

2.1 Build rutabaga/gfxstream dependencies

You will need to build gfxstream and rutabaga_gfx dependencies for QEMU.

Instead of polluting the host root FS, you can put everything under a local prefix folder:

cd qemu
mkdir -p build/deps/prefix
cd build/deps

Here we will build every dependency and install them in prefix/

# Development prefix tree
export PREFIX="$(pwd)"/prefix
export CMAKE_INSTALL_PREFIX="${PREFIX}"
export PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig":"${PREFIX}/usr/local/lib/x86_64-linux-gnu/pkgconfig"

The following rutabaga_gfx build instructions were taken from https://crosvm.dev/book/appendix/rutabaga_gfx.html

2.1.1 - Build aemu

HEAD revision:

qemu/deps/aemu % git log -1
c22a4b0 (HEAD -> main, origin/master, origin/main, origin/HEAD) reland: multidisplay: add isPixelFold method
# from <https://crosvm.dev/book/appendix/rutabaga_gfx.html#build-aemu-base>
git clone https://android.googlesource.com/platform/hardware/google/aemu
cd aemu/
cmake -DAEMU_COMMON_GEN_PKGCONFIG=ON \
      -DAEMU_COMMON_BUILD_CONFIG=gfxstream \
      -DENABLE_VKCEREAL_TESTS=OFF \
      --install-prefix "${PREFIX}" \
      -B build
cmake --build build -j
cmake --install build --prefix "${CMAKE_INSTALL_PREFIX}"

2.1.2 Build gfxstream

HEAD revision:

qemu/deps/gfxstream % git log -1
b5ce9bbd (HEAD -> main, origin/master, origin/main, origin/HEAD) AndroidWorkPool.cpp:248:5: error: control reaches end of non-void function
# from <https://crosvm.dev/book/appendix/rutabaga_gfx.html#build-gfxstream>
git clone https://android.googlesource.com/platform/hardware/google/gfxstream
cd gfxstream/
meson setup -Ddefault_library=static --prefix "${PREFIX}" build/ 
meson install -C build

2.1.3 Build rutabaga FFI

git clone git@github.com:google/crosvm.git

You will also need rust/cargo.

Install the stable channel 1.68.2-{x86_64,aarch64}-unknown-linux-gnu toolchain with rustup if you don't have it already:

rustup toolchain list | grep -q 1.68.2-x86_64-unknown-linux-gnu || rustup toolchain install 1.68.2-x86_64-unknown-linux-gnu

crosvm HEAD revision:

crosvm % git log -1
1eca601ea (HEAD -> main, origin/main, origin/HEAD) Roll recipe dependencies (trivial).
# crosvm HEAD revision: 1eca601ea
export LDFLAGS="${PREFIX}/usr/local/lib/x86_64-linux-gnu/"
export RUSTFLAGS='-Clink-arg=-L='${LDFLAGS}
cd rutabaga_gfx/ffi
make
make prefix="${PREFIX}" install

2.1.4 Build qemu binary

After all that, go back to qemu/build and build QEMU:

cd qemu/build
export CFLAGS="-I${PREFIX}/include -L${PREFIX}/lib" # needed for rutabaga_gfx_ffi.h
../configure --enable-system --enable-tools --enable-vhost-user --enable-slirp --enable-kvm --enable-debug --target-list=x86_64-softmmu --enable-rutabaga-gfx
make -j$(nproc)

3. Run the guest.

I used this QEMU invocation:

#!/bin/zsh
export WAYLAND_SOCK=/run/user/1000/wayland-0
#export WAYLAND_SOCK=/tmp/wayland.sock
GUEST_DATA_IMG=...
./build/qemu-system-x86_64 \
    -m 4G \
    -machine pc,accel=kvm,memory-backend=mem,usb=off \
    -device virtio-scsi-pci,id=scsi0 \
    -device virtio-net-pci,netdev=net0 \
    -D qemu.log \
    -netdev user,id=net0,hostfwd=tcp::8022-:22 \
    -object memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on \
    -audio driver=pa,model=hda,server=/run/user/1000/pulse/native \
    -device virtio-vga-rutabaga,capset_names=gfxstream-vulkan:cross-domain,wayland_socket_path=${WAYLAND_SOCK},hostmem=8G \
    "$GUEST_DATA_IMG"

If you use Wayland, choose WAYLAND_SOCK=/run/user/1000/wayland-0 or similar. If you use weston inside Xorg run weston -S /tmp/wayland.sock and use WAYLAND_SOCK=/tmp/wayland.sock.

3.1 Running graphic apps in guest through sommelier

You will need to build sommelier inside the guest.

Clone the repository:

git clone https://chromium.googlesource.com/chromiumos/platform2
cd platform2/vm_tools/sommelier/

I used the HEAD revision: Mon Aug 14 02:58:30 2023 +0000 40e9663246e784fb4d3abc0385ac2fe717ecf460 Revert "vm_tools/9s: Replace crosvm_base::vsock with vsock crate"

On Debian, you will need the following build dependencies:

apt install -y cmake \
    libdrm{2,-dev} \
    libgbm{1,-dev} \
    libpixman-1-{0,dev} \
    libwayland-bin \
    'libwayland-client*' \
    libwayland-dev \
    libxcb-composite0{,-dev} \
    libxcb1-dev \
    libxkbcommon{0,-dev} \
    meson \
    pkg-config \
    python3 \
    python3-jinja2

Then perform the build:

meson setup build -Dwith_tests=false
meson compile -C build
meson install -C build
# run a weston-terminal
sommelier --virtgpu-channel weston-terminal
# run glmark2 benchmarks
apt install -y glmark2-wayland
sommelier --virtgpu-channel glmark2-wayland

This should open weston-terminal and glmark2-wayland on your host's wayland compositor.

  • No labels