#!/usr/bin/env bash # test-virgl-qemu.sh — bounded Mesa virgl runtime validation on QEMU. # # Proof target: a redbear-full guest boots in QEMU with a 3D-capable # virtio-gpu, loads libgallium.so via the EGL loader, and renders a # GLES2 demo through the host GPU via virgl 3D. # # This is the bounded runtime validation for Phase 1 of the 3D driver plan # (see local/docs/3D-DRIVER-PLAN.md). It addresses the gap that the # README's "virgl EGL runtime probe open" line leaves open. # # What this proves: # - The Mesa 26.1.4 build actually produces a loadable DRI driver # - EGL_PLATFORM can be set to wayland (or surfaceless) at runtime # - libgallium.so exports the driver symbols that the loader expects # - The libdrm redox.patch redirects DRM ioctls to scheme:drm # - The redox-drm virtio-gpu backend negotiates virgl 3D with the host # # What this does NOT prove: # - Real-hardware 3D rendering (use test-intel-gpu.sh for that) # - Mesa Intel iris / AMD radeonsi (those are Phase 4 / Phase 5) # - Vulkan (that's Phase 6) # # Usage: # ./test-virgl-qemu.sh [--img PATH] [--egl-platform wayland|surfaceless] # [--driver-override virgl|swrast] # [--capture-output FILE] # [--check] # # The script is dry-run by default (prints the QEMU command). Pass # --check to actually run it (requires QEMU + a built redbear-full image). set -euo pipefail script_dir="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" redbear_root="$(cd -- "${script_dir}/../.." && pwd)" usage() { cat <&2; usage; exit 2 ;; esac done # Default image path if [[ -z "$img_path" ]]; then img_path="${redbear_root}/local/recipes/libs/mesa/target/x86_64-unknown-redox/build/redbear-full/harddrive.img" fi if [[ ! -f "$img_path" ]]; then img_path="${redbear_root}/build/x86_64/redbear-full/harddrive.img" fi # Build the QEMU command. # Crucial: virtio-vga-gl (NOT virtio-gpu/virtio-vga) is the 3D-capable device. # QEMU ≥ 8.0 dropped the legacy `virgl=on` property; `blob=true` is the # modern equivalent and activates the virgl blob-resource path the # redox-drm backend negotiates via VIRTIO_GPU_F_RESOURCE_BLOB. qemu_cmd=( qemu-system-x86_64 -machine q35 -smp "${smp_count}" -m "${ram_mb}" -drive file="${img_path}",format=raw,if=virtio -device virtio-vga-gl,blob=true -display gtk,gl=on -boot d -serial stdio -no-reboot -vga none ) # Inject the Mesa loader env vars via QEMU fw_cfg (or via -append on the # kernel command line for the launch). # `EGL_PLATFORM=redox` would be ideal — but currently the redox platform # is missing in Mesa 26.1.4 (see local/docs/3D-DRIVER-PLAN.md Phase 3). # Until Phase 3 lands, `wayland` is the only path that reaches Mesa at all; # even then, the loader will fall back to swrast unless the driver override # is set. # # These vars are passed via a small script that runs after login. runtime_env=( "EGL_PLATFORM=${egl_platform}" "MESA_LOADER_DRIVER_OVERRIDE=${driver_override}" "MESA_DEBUG=loader" ) # Print the runtime command for transparency. echo "QEMU command: ${qemu_cmd[*]}" echo "Mesa runtime env: ${runtime_env[*]}" echo "Image: ${img_path}" if [[ ! -f "$img_path" ]]; then echo "WARN: image not found at ${img_path}; --check will fail" >&2 fi if [[ ${do_check} -eq 0 ]]; then echo "DRY-RUN: pass --check to actually launch QEMU." exit 0 fi # Real run. if [[ -n "$capture_output" ]]; then timeout "${timeout_secs}" "${qemu_cmd[@]}" 2>&1 | tee "$capture_output" else timeout "${timeout_secs}" "${qemu_cmd[@]}" fi