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,