From 900089c44cf9898d96c10d7a40c864a03dc6f357 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Tue, 16 Jun 2026 14:37:31 +0000 Subject: [PATCH] fix(host/windows): don't pin SudoVDA render adapter by default (Apollo parity) GROUND TRUTH from Apollo streaming live on this exact box (empty config): captures the SudoVDA at 5120x1440@240 on the RTX 4090 with ZERO ACCESS_LOST / born-lost / MODE_CHANGE -- clean, no overlay, no isolation, no render pin. That disproves the independent-flip theory (a sole SudoVDA captures fine here) and points at something WE do that Apollo doesn't. The concrete culprit: we call SET_RENDER_ADAPTER, which this driver IGNORES (logs 'render adapter DIFFERS from pinned add=0x23664 pinned=0x15768') and the IDD ends up rendering on adapter 0x23664 while its DXGI output is enumerated under the 4090 (0x15768) where we create the capture device -- a cross-GPU mismatch that is the real source of the perpetual ACCESS_LOST + MODE_CHANGE_IN_PROGRESS (0x887A0025) storm. Apollo never pins (empty config), so its IDD stays on its natural adapter, aligned with capture. Make the render pin OPT-IN (PUNKTFUNK_RENDER_ADAPTER=); default to NOT pinning, matching Apollo. The startup log now shows the resulting AddOut LUID so we can confirm the IDD lands on the 4090. Co-Authored-By: Claude Opus 4.8 --- crates/punktfunk-host/src/vdisplay/sudovda.rs | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/crates/punktfunk-host/src/vdisplay/sudovda.rs b/crates/punktfunk-host/src/vdisplay/sudovda.rs index 5f7b27e..b134292 100644 --- a/crates/punktfunk-host/src/vdisplay/sudovda.rs +++ b/crates/punktfunk-host/src/vdisplay/sudovda.rs @@ -670,12 +670,23 @@ impl VirtualDisplay for SudoVdaDisplay { device_name, serial: [0u8; 14], }; - // Pin the IDD's RENDER GPU to the NVENC/capture GPU (e.g. the 4090) BEFORE adding the target. - // On a multi-adapter box (SudoVDA IDD + discrete GPU) DXGI otherwise reparents the virtual - // output onto whichever GPU its hybrid-preference path resolves, which storms ACCESS_LOST - // (0x887A0026) on the secure/HDR desktop. Apollo's SET_RENDER_ADAPTER fixes this and MUST be - // issued before ADD. Best-effort: a driver that rejects it just keeps the default render GPU. - let pinned = unsafe { resolve_render_adapter_luid() }; + // SET_RENDER_ADAPTER is OPT-IN. Apollo runs with an EMPTY config and NEVER pins the render + // adapter, yet captures the SudoVDA cleanly at the client mode on the 4090 (verified live on + // this exact box: no ACCESS_LOST, no MODE_CHANGE storm). On this box our pin is IGNORED by the + // driver AND the IDD lands on a DIFFERENT adapter (0x23664) than the one its DXGI output is + // enumerated under (the 4090, where we make the capture device) — a cross-GPU mismatch that is + // the real source of the perpetual ACCESS_LOST + MODE_CHANGE_IN_PROGRESS storm. So default to + // NOT pinning — let the IDD use its natural adapter like Apollo. Opt in with + // PUNKTFUNK_RENDER_ADAPTER= only on a box that genuinely needs steering. + let pinned = if std::env::var("PUNKTFUNK_RENDER_ADAPTER").is_ok() { + unsafe { resolve_render_adapter_luid() } + } else { + tracing::info!( + "SudoVDA SET_RENDER_ADAPTER skipped (Apollo-parity: no render pin — avoids cross-GPU \ + mismatch; set PUNKTFUNK_RENDER_ADAPTER= to force a specific render GPU)" + ); + None + }; if let Some(luid) = pinned { match unsafe { set_render_adapter(self.device, luid) } { Ok(()) => tracing::info!(