fix(host/windows): NVENC capture on real GPU + HOME-less config dir

Validated live on an RTX 4090 (Windows 11) host streaming to the Rust
reference client over the LAN: SudoVDA virtual display → DXGI Desktop
Duplication (D3D11 zero-copy) → NVENC HEVC → punktfunk/1. 720p60 and
1080p60 both clean (181 / 177 frames, 0 mismatched, p50 1.6 / 3.45 ms
cross-machine), coexisting with Apollo. Two real-hardware bugs the
GPU-less VM couldn't surface:

- DXGI capturer: the SudoVDA virtual monitor's DXGI output is enumerated
  under the GPU that *renders* it (the 4090, LUID 0x15df6), NOT under the
  SudoVDA "adapter" LUID SudoVDA reports (0x23276). Restricting the output
  search to that LUID found nothing → "adapter has no output named
  \\.\DISPLAYn". Now search ALL adapters for the GDI name, bind the D3D11
  device to whichever adapter exposes it (NVENC then shares that device),
  with a settle-retry (the output appears a beat after display creation)
  and topology logging.

- native_pairing / apps: keyed config paths off raw $HOME, which a Windows
  service/scheduled-task context doesn't set → "HOME unset" hard-fail at
  m3-host startup. Route both through gamestream::config_dir(), which falls
  back to %APPDATA% on Windows (cert/paired/apps now under AppData\Roaming).

clippy -D warnings + build green on x86_64-pc-windows-msvc (default and
--features nvenc) and Linux (78/78 tests).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-15 09:18:15 +00:00
parent 84fff71a6d
commit 70536b464a
3 changed files with 89 additions and 31 deletions
+2 -1
View File
@@ -20,7 +20,8 @@ pub struct AppEntry {
}
fn config_path() -> Option<std::path::PathBuf> {
Some(std::path::Path::new(&std::env::var("HOME").ok()?).join(".config/punktfunk/apps.json"))
// `config_dir()` resolves XDG/HOME on Linux and %APPDATA% on Windows (no HOME needed).
Some(super::config_dir().join("apps.json"))
}
fn parse_compositor(s: &str) -> Option<crate::vdisplay::Compositor> {