From 8bef4e27f9f18da8d9003bf1f0e75f6a2156cce0 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Wed, 8 Jul 2026 10:49:51 +0200 Subject: [PATCH] fix(client-linux): opt into RADV Vulkan Video decode at session start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mesa gates RADV's video-decode support — the VK_KHR_video_decode_* device extensions AND the decode-capable queue family — behind RADV_PERFTEST=video_decode (Steam Deck / VANGOGH included). Without it the presenter's device advertises no decode queue, Decoder::new's auto chain skips Vulkan Video, and the session silently lands on VAAPI. punktfunk-session now appends the token to RADV_PERFTEST before the driver loads (all streams run through this binary, so every launch path and package is covered). RADV-only knob: other drivers ignore it, and a Mesa where decode is already default just no-ops. Verified on the Deck: decode_qf=2, H264/H265/AV1 caps, first frame path="vulkan-video", 90 fps at 1.9 ms decode. Co-Authored-By: Claude Fable 5 --- clients/linux-session/src/main.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/clients/linux-session/src/main.rs b/clients/linux-session/src/main.rs index 21fd1aca..fbbd1234 100644 --- a/clients/linux-session/src/main.rs +++ b/clients/linux-session/src/main.rs @@ -154,6 +154,30 @@ mod session_main { } } + /// Steam Deck / RADV: Mesa gates Vulkan Video decode — the `VK_KHR_video_decode_*` + /// extensions AND the decode-capable queue family — behind `RADV_PERFTEST=video_decode`. + /// Without it the presenter's device advertises no decode queue, so `Decoder::new`'s + /// `auto` path can't build the Vulkan decoder and the session silently falls back to + /// VAAPI (whose separate-plane dmabuf import shows chroma fringing — green/yellow specks + /// around the cursor — on VanGogh). We want the Vulkan path, so opt in here, before the + /// RADV driver loads (the Vulkan instance is created later, inside `run_session`). + /// + /// RADV-only knob: ANV/NVIDIA/other drivers ignore `RADV_PERFTEST`, and a box where video + /// decode is already the default just no-ops. Append rather than clobber so a user's own + /// `RADV_PERFTEST` survives; `PUNKTFUNK_DECODER=vaapi` still overrides the decoder choice. + fn enable_radv_video_decode() { + const TOKEN: &str = "video_decode"; + match std::env::var("RADV_PERFTEST") { + Ok(v) if v.split(',').any(|t| t == TOKEN) => return, + Ok(v) if !v.is_empty() => std::env::set_var("RADV_PERFTEST", format!("{v},{TOKEN}")), + _ => std::env::set_var("RADV_PERFTEST", TOKEN), + } + tracing::info!( + radv_perftest = %std::env::var("RADV_PERFTEST").unwrap_or_default(), + "opted into RADV Vulkan Video decode (Mesa gates it behind RADV_PERFTEST on the Deck)" + ); + } + pub fn run() -> u8 { // Logs to STDERR — stdout is the machine interface (ready/stats/error lines). tracing_subscriber::fmt() @@ -164,6 +188,10 @@ mod session_main { ) .init(); + // Before any Vulkan call: make RADV expose its video-decode queue + extensions so the + // decoder's `auto` path prefers Vulkan Video over VAAPI (Steam Deck, and any gated RADV). + enable_radv_video_decode(); + // Steam launches its shortcuts with SDL_GAMECONTROLLER_IGNORE_DEVICES naming // every pad Steam Input has virtualized; capturing the Deck's real built-in // controller needs it cleared (same rationale as the GTK client's `app::run`).