8e87e617dfac4ac8cb314d907b99f5ed1f666820
13 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f6490f4c28 |
fix: complete the docs/→design/ and openapi→api/ rename references
The file moves (docs/ → design/, docs/api/openapi.json → api/openapi.json) landed
in
|
||
|
|
3e7c9bd059 |
fix(host): remove unsound unsafe impl Sync for HelperRelay
apple / swift (push) Failing after 0s
release / apple (push) Failing after 0s
apple / screenshots (push) Has been skipped
windows-drivers / probe-and-proto (push) Successful in 29s
audit / cargo-audit (push) Failing after 1m20s
windows-drivers / driver-build (push) Successful in 1m14s
android / android (push) Failing after 2m5s
ci / web (push) Successful in 46s
ci / docs-site (push) Successful in 1m3s
windows-host / package (push) Successful in 6m46s
ci / bench (push) Successful in 4m34s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 1m25s
ci / rust (push) Successful in 8m36s
decky / build-publish (push) Successful in 22s
windows-msix / package (x64, C:\Users\Public\ffmpeg, x86_64-pc-windows-msvc, C:\t) (push) Successful in 1m11s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 59s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 2m37s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 1m3s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 29s
deb / build-publish (push) Successful in 7m50s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 2m52s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m5s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 2m33s
flatpak / build-publish (push) Successful in 3m56s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 8m46s
docker / deploy-docs (push) Successful in 22s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 8m26s
The one genuine soundness defect the unsafe-proof program surfaced (flagged SUSPECT in program 3/N). `HelperRelay` holds an `rx: Receiver<RelayAu>`, which is `!Sync` (std mpsc is single-consumer), so asserting `Sync` claimed more than the fields support — an `Arc<HelperRelay>` recv'd from two threads would compile and be UB. It was never live-exploited, and it turns out `Sync` is also unnecessary: the relay is a single-owner `mut relay` local in the punktfunk1 two-process mux loop (recv_timeout/try_recv/request_keyframe all called on the owning thread; no `Arc`, no `thread::spawn` capturing it). So the fix is simply to delete the impl — the struct keeps its sound `unsafe impl Send` (needed for the raw `HANDLE` fields), which is all the code uses. Box-verified: cargo clippy -p punktfunk-host --features nvenc --target x86_64-pc-windows-msvc -- -D warnings stays green without the Sync impl. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
7aa787a789 |
docs(host): prove the last 3 files + crate-root deny (unsafe-proof program 4/N, final)
Completes the unsafe-proof program now that the parallel WIP has landed: - idd_push.rs (25 sites), nvenc.rs (7), punktfunk1.rs (21): a SAFETY proof on every unsafe block — D3D11/DXGI COM (same-device textures, immediate-context single-thread, keyed-mutex-held convert), the NVENC SDK table (versioned POD, register/map/lock-bitstream pairing), cross-process shm reads (atomic magic/generation handshake), and the C-ABI harness (each call cross-checked against its abi.rs `# Safety` doc). No SUSPECT (UB) blocks. - capture.rs / encode.rs: the parent-module deny is restored (their WIP children are now proven), and main.rs gains a crate-root #![deny(clippy::undocumented_unsafe_blocks)] — the permanent catch-all gate so no future unsafe block anywhere in the crate can land without a proof. - Fixed 4 blocks the agents missed: unsafe blocks nested inside `assert_eq!(...)` macro args (the comment-above-statement didn't associate) — hoisted to a `let`. - rustfmt-canonicalized the Windows files (the agents' SAFETY comments + some pre-existing 1.9.0 drift) so `cargo fmt --all --check` is clean. Verified: cargo clippy -p punktfunk-host --all-targets -- -D warnings AND cargo fmt -p punktfunk-host --check both green with the crate-root deny active. Windows cfg(windows) re-verified on the box next. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
3514702d8c |
feat(windows-host): IDD-push encodes native NV12/P010 (skip NVENC's SM-side CSC)
GPU-contention work (host-latency plan §5.A): the IDD-push output ring now hands NVENC native YUV instead of RGB, so NVENC skips its internal RGB→YUV colour conversion on the SM/3D engine the running game saturates. - idd_push.rs: out_ring is now NV12 (SDR, BT.709 limited) via a D3D11 VIDEO-engine BGRA→NV12 VideoConverter (keeps the CSC off the contended 3D/compute engine), or P010 (HDR, BT.2020 PQ limited) via the FP16→P010 shader (NVIDIA's VideoProcessor can't do RGB→P010). The ring drops its per-slot RTV (textures only), matching the WGC YUV ring; converters rebuild on a size/HDR flip. - nvenc.rs: NV12 input forces bit_depth=8 so an HDR→SDR toggle (or a 10-bit- negotiated client on an SDR display) re-inits the session at the matching depth — NV12 can't feed a 10-bit session (register_resource rejects it). - punktfunk1.rs: per-stage latency instrumentation under PUNKTFUNK_PERF (cap=try_latest, submit=encode_picture, wait=lock_bitstream µs p50/p99/max) to pinpoint where capture→encoded latency goes under GPU saturation. |
||
|
|
327a5fa828 |
docs(host): prove unsafe blocks in the Windows + cross-platform files + gate them (unsafe-proof program 3/N)
Continues the unsafe-proof program across the Windows/cross-platform host files
(~75 blocks, 21 files), each with a SAFETY proof of the real invariant and a
per-file #![deny(clippy::undocumented_unsafe_blocks)] gate:
capture/windows: dxgi.rs, wgc_relay.rs, wgc.rs, desktop_watch.rs, composed_flip.rs
(windows-rs COM: interface validity, same-D3D11-device textures,
immediate-context single-thread, borrowed args outlive the call)
windows: service.rs (SCM/token/CreateProcessAsUserW/event handles — OwnedHandle
liveness, no double-close/signal race), win_display, wgc_helper, interactive
vdisplay/windows: manager.rs, pf_vdisplay.rs (SwDeviceCreate/IddCx/ioctl handle
liveness via the OnceLock VDM singleton + OwnedHandle)
encode/windows: ffmpeg_win.rs (full AVBufferRef refcount audit — balanced, NO leaks,
unlike the vaapi sibling), sw.rs
cross-platform: gamestream/audio.rs (libopus), gamestream/stream.rs (sendmmsg),
inject/windows/sendinput.rs, audio/windows/wasapi_mic.rs,
session_tuning.rs, vdisplay.rs
Two findings (handled separately):
- wgc_relay.rs `unsafe impl Sync for HelperRelay` is UNSOUND (its mpsc Receiver is
!Sync) though not live-exploited — marked SUSPECT inline; fix pending box check
(it touches the in-flight punktfunk1.rs).
- capture.rs / encode.rs (PARENT modules of the WIP idd_push.rs / nvenc.rs) do NOT
get the file deny yet — it would propagate the lint into the undocumented WIP
children. The deny lands there once those are documented (after the WIP commits).
Linux-visible parts verified green (cargo clippy -p punktfunk-host --all-targets
-- -D warnings). The cfg(windows) deny gates are box-verified next.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
bd05bc8c30 |
fix(windows): clippy/build cleanups the on-glass build surfaced (-D warnings)
Built the host crate (`cargo clippy --features nvenc -D warnings`) and the driver workspace (`cargo build`) on the RTX box — the project's intended Windows gate, which `cargo check` (what the goal1/§2.5 work used) never runs. It surfaced lint issues accumulated across the goal1 / §2.5 / this-session Windows work: - 9× redundant `as *mut c_void` after `.as_raw_handle()` (already `*mut c_void`): idd_push.rs (3, this session), service.rs (3, this session), manager.rs (3, pre-existing §2.5 — my OwnedHandle work copied the idiom). Removed the casts + the now-unused `use std::ffi::c_void` in idd_push.rs / manager.rs (service still uses it). - `if_same_then_else` in session_plan.rs::resolve_topology (pre-existing goal1 stage 3): collapsed the two `false` arms into one condition (behavior identical). - `unused_unsafe` in the driver `pod_init!` macro: it expands at call sites already inside an `unsafe` block, where its own `unsafe` is redundant — `#[allow( unused_unsafe)]` (needed at the non-unsafe sites, redundant at the nested ones). After these, BOTH builds are clean on the box — validating the whole session's blind Windows + driver work compiles + passes clippy on real hardware. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
658564353c |
refactor(windows-host): KeyedMutexGuard RAII for the IDD-push consume hot loop (Goal-3, hw-validated)
The IDD-push consume loop acquired the slot's keyed mutex by hand (`AcquireSync(0,8)` … work … `ReleaseSync(0)`), with a comment warning that a `?`-return between acquire and release would leak the lock and stall the driver on that slot — the reason the HDR converter is built *before* the acquire. Replace with a `KeyedMutexGuard` RAII (acquire → `ReleaseSync` on drop), scoped to JUST the convert/copy block so the lock releases at the EXACT same point as before (the driver gets the slot back immediately; not held across the rest of `try_consume`). Now the release can't be skipped on any early return/panic — the leak footgun is gone by construction, and the hot loop has no raw `ReleaseSync`. Behavior/latency-equivalent (same acquire params, same release point). Windows- only (CI + on-glass gated); to be validated on the RTX box (host clippy build + a PERF=1 latency A/B vs the shipping binary — the change should show no delta). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
011607ec10 |
refactor(windows-host): RAII for IDD-push handles/views — fix a leak (Goal-3 unsafe reduction #1)
The IDD-push capturer held raw `HANDLE`s for the shared header mapping, the
frame-ready event, the debug section, and each ring slot's shared texture, with
manual `CloseHandle` scattered across two `Drop` impls — and the MapViewOfFile
VIEWS (header/dbg_block) were never UnmapViewOfFile'd (a real view leak).
- New `MappedSection { handle: OwnedHandle, view }` RAII: `Drop` UnmapViewOfFile's
the view THEN the `OwnedHandle` closes the mapping (unmap-before-close).
- `map`+`header` → `section: MappedSection` (+ a cached `header` ptr borrowing into
it, declared after `section` for drop order); same for `dbg_map`+`dbg_block`.
- `event: HANDLE` → `OwnedHandle` (borrowed as `HANDLE(as_raw_handle() as *mut
c_void)` for WaitForSingleObject); `HostSlot.shared` → `OwnedHandle` (its manual
`Drop` deleted). Removed the manual `CloseHandle`s + the `CloseHandle` import.
Net: deletes two `Drop` impls' worth of manual handle/view teardown and fixes the
view leak — fewer unsafe ops, RAII-correct. Behavior preserved (recreate_ring
writes the header in place; the keepalive still drops last so REMOVE is last).
Windows-only (CI-gated); adversarially reviewed (no double-free / UAF / dangling
header; handle interop matches manager.rs). Linux check unaffected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
00cf51d610 |
refactor: rename pf-vdisplay-proto -> pf-driver-proto (it spans all drivers)
The shared host<->driver ABI crate already contains more than the virtual display: the IDD-push frame ring + control plane AND the gamepad shared-memory layouts (XusbShm / PadShm). "pf-vdisplay-proto" was a misnomer — the name now represents all the drivers it serves. Mechanical rename, no behavior change: - git mv crates/pf-vdisplay-proto -> crates/pf-driver-proto (package name + path-deps in the host crate and the driver workspace). - pf_vdisplay_proto -> pf_driver_proto across host + driver Rust, both Cargo.lock files, the workspace members, the CI path triggers (windows-drivers.yml), and the docs/INF comments. The runtime Global\pfvd-* shared-object names are a SEPARATE contract and are deliberately untouched (host<->driver name matching). - The pf-vdisplay DRIVER crate + its INF service name (Root\pf_vdisplay, UmdfService=pf_vdisplay, pf_vdisplay.dll) are unchanged — only the full `pf_vdisplay_proto` token was replaced, never the `pf_vdisplay` driver name. Linux-verified: cargo test -p pf-driver-proto (const size-asserts compile) + cargo clippy -p punktfunk-host -D warnings clean; Cargo.lock regenerated. The driver-workspace side (path-dep + imports + its Cargo.lock) is Windows-CI-gated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
84a3b95f17 |
refactor(windows-host): delete the SudoVDA backend — pf-vdisplay is the sole vdisplay (Goal 2)
Goal 2 ("drop every trace of SudoVDA") is done. The SudoVDA driver is no longer
shipped (only pf-vdisplay; the old vdisplay-driver tree was deleted in
|
||
|
|
0255a8289c |
docs(windows-host): consolidate 5 scattered docs into one current source of truth
The Windows-host docs were scattered across a design plan, a staged-refactor plan, an audit, an audit-remediation tracker, and a game-capture-bug analysis — several badly stale (the audit/remediation predate the Goal-1 branch landing and call DONE items "not started"). Verified the true state of every audit finding / goal / milestone against current code+git (4-agent workflow), then rewrote windows-host-rewrite.md as ONE consolidated, accurate doc: - §1 Status scorecard (Goals 1-3, M0-M6, GB1, audit P0/P1/P2) with DONE/PARTIAL/ OPEN + commit evidence. - §2 Architecture as-built (layering, HostConfig→SessionPlan→SessionContext, the VirtualDisplayManager ownership model, IDD-push-primary capture incl. secure desktop + GB1 recovery, encode/EncoderCaps, pf-vdisplay-proto, the driver, service/packaging). - §3 Validated invariants (the jewels). - §4 Prioritized open tasks (the genuine remaining work). - §5 Operations (RTX-box recipe, CI, env, build). - §6 Deep reference (/INTEGRITYCHECK answer, the 6 iddcx bindgen knobs, the driver port checklist, resolved decisions). Deleted the four now-redundant docs (content folded in; history in git): windows-host-goal1-plan.md, windows-host-rewrite-audit.md, windows-host-rewrite-remediation.md, windows-host-rewrite-game-capture-bug.md. Repointed the 6 code/proto/driver doc-comment refs that targeted them at the consolidated windows-host-rewrite.md sections. Linux cargo check clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
15202011c1 |
refactor(windows-host): §2.5 step 1 — delete the dead/write-only monitor-lifecycle code
Removes the cruft the §2.5 ownership-model rewrite would otherwise carry forward, and corrects a
false invariant the docs described:
* CURRENT_MON_GEN (sudovda) — the "current monitor generation" global was WRITE-ONLY. It was
stored on every mgr_acquire (both backends) but its only reader, idd_push's `my_gen`, was set
and NEVER read. The "session capturer re-checks the monitor gen each frame and bails on a
reconnect" behaviour the doc describes was never wired — per-frame staleness is the SEPARATE
ring FrameToken.generation / IDD_GENERATION mechanism (which works and is untouched). So the
monitor-gen-via-WinCaptureTarget carry the design proposed is unnecessary. Deleted the static,
its stores in both backends, the pf_vdisplay import, and idd_push's dead `my_gen` field/read.
(MON_GEN — the lease-generation counter behind the stale-lease no-op — is REAL and kept.)
* IDD_PERSIST + open_or_reuse + IddReuseHandle (idd_push) — a persistent-capturer reuse path
from an early prototype, defined but with ZERO callers across the crate. Deleted, plus the now
-orphaned `use std::sync::Mutex` and the now-dead `set_client_10bit` setter.
Windows-only; grep confirms no remaining references to any deleted symbol. Box build to follow.
First of the incremental §2.5 steps (user-approved OnceLock VirtualDisplayManager design).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
38c68c33e5 |
refactor(windows-host): confine platform code under windows/ + linux/ folders (Goal-1 stage 6)
Move 36 platform-specific files into per-module `windows/` and `linux/` subfolders (and the
shared HID codecs into `inject/proto/`):
capture/{windows,linux}/ encode/{windows,linux}/ inject/{windows,linux,proto}/
audio/{windows,linux}/ vdisplay/{windows,linux}/
src/windows/ (service, wgc_helper, win_adapter, win_display)
src/linux/ (dmabuf_fence, drm_sync, zerocopy/)
Done with `#[path]`, NOT a module rename: every file moves into its folder while the
`crate::*::*` module names stay FLAT, so all caller paths and every internal `super::`/`crate::`
reference are unchanged — only the parent `mod` decls gained `#[path = "..."]`. This is the
codebase's existing pattern (inject's gamepad_windows) and makes the move byte-identical in
behaviour with ZERO reference churn, far lower risk than collapsing to a single
`crate::capture::windows::` namespace (that deeper rename is an optional follow-on; this delivers
the cfg-sprawl folder confinement the stage is about). Done LAST, after the semantic stages, so
the path churn didn't fight them.
Verified: Linux cargo check + clippy (-D warnings) clean; my mod-decl changes fmt-clean (the 3
remaining fmt diffs are pre-existing local-rustfmt-version skew that moved with their files); all
36 `#[path]` targets exist; no internal `#[path]`/`include!`/file-child-mod in any moved file
(the inline `mod X {` blocks are self-contained). Box build to follow.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|