From 59cfdf9050640b9c1dec7d01ce0f445aa0b7602a Mon Sep 17 00:00:00 2001 From: Val Packett Date: Fri, 19 Sep 2025 02:41:37 -0300 Subject: [PATCH] Add CLI flag --gpu=drm|venus|software to support various GPU virtualization modes vDRM is great, but not supported everywhere yet, so on some machines the only way to get GPU acceleration is via Venus. Also, make it possible to use software rendering only while still having working cross-domain Wayland. Signed-off-by: Val Packett --- crates/muvm/src/bin/muvm.rs | 15 +++++++++++++-- crates/muvm/src/cli_options.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/crates/muvm/src/bin/muvm.rs b/crates/muvm/src/bin/muvm.rs index be46e12e..0827e8db 100644 --- a/crates/muvm/src/bin/muvm.rs +++ b/crates/muvm/src/bin/muvm.rs @@ -11,7 +11,8 @@ use krun_sys::{ krun_add_disk, krun_add_virtiofs2, krun_add_vsock_port, krun_add_vsock_port2, krun_create_ctx, krun_set_env, krun_set_gpu_options2, krun_set_log_level, krun_set_passt_fd, krun_set_root, krun_set_vm_config, krun_set_workdir, krun_start_enter, VIRGLRENDERER_DRM, - VIRGLRENDERER_THREAD_SYNC, VIRGLRENDERER_USE_ASYNC_FENCE_CB, VIRGLRENDERER_USE_EGL, + VIRGLRENDERER_NO_VIRGL, VIRGLRENDERER_RENDER_SERVER, VIRGLRENDERER_THREAD_SYNC, + VIRGLRENDERER_USE_ASYNC_FENCE_CB, VIRGLRENDERER_USE_EGL, VIRGLRENDERER_VENUS, }; use log::debug; use muvm::cli_options::options; @@ -184,8 +185,14 @@ fn main() -> Result { .context("Failed to configure the number of vCPUs and/or the amount of RAM"); } + let virgl_mode = match options.gpu_mode.unwrap_or_default() { + muvm::cli_options::GpuMode::Drm => VIRGLRENDERER_DRM, + muvm::cli_options::GpuMode::Venus => VIRGLRENDERER_VENUS | VIRGLRENDERER_RENDER_SERVER, + muvm::cli_options::GpuMode::Software => 0, + }; let virgl_flags = VIRGLRENDERER_USE_EGL - | VIRGLRENDERER_DRM + | VIRGLRENDERER_NO_VIRGL /* Legacy method that we don't support; interferes with software-only mode */ + | virgl_mode | VIRGLRENDERER_THREAD_SYNC | VIRGLRENDERER_USE_ASYNC_FENCE_CB; // SAFETY: Safe as no pointers involved. @@ -436,6 +443,10 @@ fn main() -> Result { env.insert("XAUTHORITY".to_owned(), xauthority); } + if options.gpu_mode == Some(muvm::cli_options::GpuMode::Venus) { + env.insert("MESA_LOADER_DRIVER_OVERRIDE".to_owned(), "zink".to_owned()); + } + let krun_config = KrunBaseConfig { config: KrunConfig { args: muvm_guest_args, diff --git a/crates/muvm/src/cli_options.rs b/crates/muvm/src/cli_options.rs index 7cde5e8b..5080c911 100644 --- a/crates/muvm/src/cli_options.rs +++ b/crates/muvm/src/cli_options.rs @@ -7,6 +7,29 @@ use bpaf::{any, construct, long, positional, OptionParser, Parser}; use crate::types::MiB; use crate::utils::launch::Emulator; +#[derive(Debug, Clone, Copy, Default, PartialEq)] +pub enum GpuMode { + #[default] + Drm, + Venus, + Software, +} + +impl std::str::FromStr for GpuMode { + type Err = String; + fn from_str(s: &str) -> Result + where + Self: Sized, + { + match s { + "drm" => Ok(GpuMode::Drm), + "venus" => Ok(GpuMode::Venus), + "software" => Ok(GpuMode::Software), + x => Err(format!("Expected drm|venus|software, got '{x}'")), + } + } +} + #[derive(Clone, Debug)] pub struct Options { pub cpu_list: Vec>, @@ -19,6 +42,7 @@ pub struct Options { pub interactive: bool, pub tty: bool, pub privileged: bool, + pub gpu_mode: Option, pub publish_ports: Vec, pub emulator: Option, pub init_commands: Vec, @@ -125,6 +149,10 @@ pub fn options() -> OptionParser { This notably does not allow root access to the host fs.", ) .switch(); + let gpu_mode = long("gpu-mode") + .help("Use the given GPU virtualization method") + .argument::("drm|venus|software") + .optional(); let publish_ports = long("publish") .short('p') .help( @@ -169,6 +197,7 @@ pub fn options() -> OptionParser { interactive, tty, privileged, + gpu_mode, publish_ports, emulator, init_commands,