diff --git a/docs/windows-host.md b/docs/windows-host.md index b39ff9e..9d19c6a 100644 --- a/docs/windows-host.md +++ b/docs/windows-host.md @@ -12,11 +12,15 @@ control interface — **no driver to write or WHQL-sign.** History: scoped 2026-06-10 (4-agent read of the host crate); SudoVDA path 2026-06-11; this concrete plan + dev box + SudoVDA protocol + no-GPU strategy added 2026-06-14 (12-agent research pass). -## Status (2026-06-15) — all host backends landed; runnable on Windows +## Status (2026-06-15) — full pipeline live-validated on an RTX 4090 Every OS-touching backend is implemented behind the existing traits and **builds clean on `x86_64-pc-windows-msvc`** (and Linux unaffected). `serve --native` / `m3-host` **run on Windows** -(identity in `%APPDATA%`/`HOME`, QUIC bound, mDNS advertising, accepting sessions — validated live). +(identity in `%APPDATA%`, QUIC bound, mDNS advertising, accepting sessions). The **full native +pipeline is validated live on a real RTX 4090** (Windows 11): SudoVDA virtual display → DXGI +Desktop Duplication (D3D11 zero-copy) → **NVENC HEVC** → punktfunk/1 → Rust reference client, at +720p60 and 1080p60 (0 mismatched frames, p50 1.6 / 3.45 ms cross-machine, ffmpeg-decodes clean), +coexisting with a running Apollo (two concurrent NVENC sessions). | Backend | State | GPU-less validation on the VM | |---|---|---| @@ -24,8 +28,8 @@ Every OS-touching backend is implemented behind the existing traits and **builds | Input (SendInput) | ✅ done | compiles; live injection needs an interactive session (not SSH) | | Software encode (openh264) | ✅ done | **live: m0 synthetic→openh264→core FEC loopback, 120/120, 0 mismatches** | | Audio (WASAPI loopback) | ✅ done | live: init chain opens (silent VM → no samples) | -| Capture (DXGI Desktop Duplication) | ✅ done | helpers unit-tested; DuplicateOutput needs a GPU-activated monitor | -| NVENC (D3D11, `--features nvenc`) | ✅ compiles+links | needs a GPU at runtime | +| Capture (DXGI Desktop Duplication) | ✅ **live on RTX 4090** | SudoVDA monitor → D3D11 zero-copy duplication; output is enumerated under the *rendering* GPU, not the SudoVDA LUID (search all adapters) | +| NVENC (D3D11, `--features nvenc`) | ✅ **live on RTX 4090** | 720p60 + 1080p60 HEVC end-to-end to the Rust client; ffmpeg-decodes clean; ran alongside Apollo (2 NVENC sessions) | | Run host (serve/m3-host) | ✅ live | m3-host starts + listens; `c_abi_connection_roundtrip` passes | | Gamepad (ViGEm) | ✅ done | compiles incl. rumble back-channel; live needs ViGEmBus + a physical pad | | Host→client audio wiring | ✅ done | builds on MSVC; `m3` `audio_thread` active on Windows (silent VM → no samples to send) | @@ -34,9 +38,26 @@ Every OS-touching backend is implemented behind the existing traits and **builds | Game library (Steam discovery) | ✅ done | Windows Steam roots (Program Files) + VDF other-drive libraries; custom store already cross-platform. Non-default Steam install dir (registry) not yet covered | **Remaining for full parity:** -- **Live GPU/in-session validation** — SudoVDA monitor activation, DXGI capture, NVENC encode, - SendInput injection, and the ViGEm rumble path all need a real GPU and/or an interactive (console) - session + a physical pad, not SSH/Session-0. +- **SendInput injection** — needs the interactive session (works once the host runs in Session 1; + not yet exercised live). +- **ViGEm rumble + gamepad input** — the pad is created live (ViGEmBus connected); the rumble + back-channel + input still need a physical pad to verify. +- **GameStream (Moonlight) path on a GPU box** — not yet run live (its fixed ports collide with + Apollo, so stop Apollo first). +- **Frame pacing on static content** — DXGI duplication is change-driven, so a blank/idle virtual + display delivers only ~12 fps (181/177 frames over ~15 s); a rendering app drives the full rate. + +### Real-GPU test box (RTX 4090, `ssh "Enrico Bühler"@192.168.1.174`) + +Windows 11, RTX 4090 (driver 596.36) + AMD iGPU, SudoVDA + Apollo (sunshine) installed. SSH lands in +**Session 0 (non-interactive)** — DXGI duplication + SendInput need the **interactive Session 1**, so +launch the host there via an Interactive scheduled task (admin SSH session is the same user): +`Register-ScheduledTask -Principal (New-ScheduledTaskPrincipal -UserId (whoami) -LogonType +Interactive -RunLevel Highest)`, then `Start-ScheduledTask`. The host runs with desktop access; read +its redirected log over SSH. `nvEncodeAPI64.dll` ships with the driver, so a VM-built `--features +nvenc` exe runs here as-is (no SDK install). The 4090's Ada NVENC has no consumer session cap, so the +host encodes alongside Apollo. **Gotcha:** the SudoVDA monitor is rendered by — and DXGI-enumerated +under — the 4090, not the SudoVDA adapter LUID (the capturer searches all adapters; see the fix). All Windows backends are `clippy -D warnings` and `rustfmt` clean on `x86_64-pc-windows-msvc` (the Windows-only modules are cfg-excluded from Linux CI, so run clippy on the VM after touching them — its