feat(windows): pf-vdisplay — all-Rust IddCx virtual display (replaces SudoVDA)

P1 done: a pure-Rust UMDF2 IddCx driver, drop-in compatible with the host's
existing vdisplay/sudovda.rs control plane (the {e5bcc234} interface + the
SudoVDA IOCTL ABI), so the host drives it unchanged. Validated streaming on
glass at 5120x1440@240 — steady 240 fps, ~2.4 ms encode, clean teardown, full
parity with SudoVDA.

- Vendored wdf-umdf-sys / wdf-umdf bindgen crates (MIT, from virtual-display-rs)
  + the SDK-version build.rs fix that resolves the IddCxStub lib path by the WDK
  version actually containing um\x64\iddcx, not the max base SDK.
- pf-vdisplay crate: entry/callbacks/context/control/monitor/edid/
  swap_chain_processor. Our OWN 128-byte EDID (manufacturer PNK, product
  punktfunk — no SudoVDA bytes), a real swap-chain drain (faithful vdd port,
  required so DWM keeps compositing), the SudoVDA-compatible IOCTL control plane
  (ADD/REMOVE/PING/GET_WATCHDOG/GET_VERSION/SET_RENDER_ADAPTER) + a watchdog that
  tears down orphaned monitors when the host stops pinging.
- deploy-dev.ps1: stage + sign + stampinf (date.time DriverVer) + Inf2Cat +
  install, codifying the "bump DriverVer or pnputil keeps the old binary" gotcha.
- docs/windows-virtual-display-rust-port.md: investigation, the on-glass
  validation, and the two traps that cost time (Session-0 measurement +
  accumulated device-state needing a reboot).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 21:54:50 +02:00
parent 095540efc2
commit d39da4bc06
35 changed files with 7148 additions and 0 deletions
@@ -0,0 +1,26 @@
# pf-vdisplay — punktfunk Windows virtual display (IddCx), in Rust.
#
# A self-contained driver workspace (NOT built on windows-drivers-rs like the gamepad drivers — IddCx
# functions are direct IddCxStub exports the WDF function-table macro can't reach, so a unified bindgen
# is the cleaner base). The wdf-umdf-sys / wdf-umdf binding crates are vendored from MolotovCherry's
# MIT-licensed virtual-display-rs (see LICENSE.virtual-display-rs); pf-vdisplay is our driver, swapping
# its named-pipe IPC for the SudoVDA-compatible IOCTL control plane our host already speaks.
[workspace]
resolver = "2"
members = ["wdf-umdf-sys", "wdf-umdf", "pf-vdisplay"]
[profile.release]
strip = true
codegen-units = 1
lto = true
[workspace.lints.rust]
unsafe_op_in_unsafe_fn = "deny"
[workspace.lints.clippy]
pedantic = { level = "warn", priority = -1 }
multiple_unsafe_ops_per_block = "deny"
ignored_unit_patterns = "allow"
missing_errors_doc = "allow"
module_inception = "allow"
module_name_repetitions = "allow"