Files
RedBear-OS/local/scripts/test-virgl-qemu.sh
T
vasilito 7fde222194 test-virgl-qemu.sh: switch to blob=true for QEMU \u22658.0
QEMU \u22658.0 dropped the legacy 'virgl=on' device property in favour of
the more general 'blob=true' which enables the VIRTIO_GPU_F_RESOURCE_BLOB
feature negotiated by the redox-drm virtio backend. Without this,
the device property was silently dropped and the guest received
2D-only KMS without any 3D acceleration.

The new 'blob=true' activates the virgl blob-resource path, matching
the VIRTIO_GPU_F_RESOURCE_BLOB bit that redox-drm already negotiates
on the host-guest boundary.
2026-07-26 20:56:17 +09:00

151 lines
5.4 KiB
Bash
Executable File

#!/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 <<USAGE
Usage: test-virgl-qemu.sh [options]
Bounded Mesa virgl runtime validation on QEMU.
Options:
--img PATH Path to redbear-full build (default: build/x86_64/redbear-full/harddrive.img)
--egl-platform NAME EGL_PLATFORM to set (default: wayland)
--driver-override D MESA_LOADER_DRIVER_OVERRIDE value (default: virgl)
--capture-output FILE Write QEMU output to FILE (default: stdout)
--check Actually run the QEMU launch (requires QEMU + image)
--timeout SECONDS QEMU timeout in seconds (default: 60)
--ram MB RAM in MB for QEMU (default: 2048)
--smp N vCPU count for QEMU (default: 4)
--help Show this message
Without --check, the script prints the qemu-system-x86_64 command that would be
launched and exits 0. With --check, the command is executed and the script
captures the guest's guest-side Mesa loader output via the kernel log.
This honors the policy from local/docs/MESA-VIRGL-RUNTIME.md (Phase 1
acceptance criteria): the build must produce a loadable DRI driver and
the EGL_PLATFORM must select virgl in a QEMU guest with a 3D-capable
virtio-gpu device.
USAGE
}
img_path=""
egl_platform="wayland"
driver_override="virgl"
capture_output=""
do_check=0
timeout_secs=60
ram_mb=2048
smp_count=4
while [[ $# -gt 0 ]]; do
case "$1" in
--img) img_path="${2:-}"; shift 2 ;;
--egl-platform) egl_platform="${2:-}"; shift 2 ;;
--driver-override) driver_override="${2:-}"; shift 2 ;;
--capture-output) capture_output="${2:-}"; shift 2 ;;
--check) do_check=1; shift ;;
--timeout) timeout_secs="${2:-}"; shift 2 ;;
--ram) ram_mb="${2:-}"; shift 2 ;;
--smp) smp_count="${2:-}"; shift 2 ;;
--help|-h) usage; exit 0 ;;
*) echo "Unknown option: $1" >&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