pf-presenter's 120 sites are `ash` calls almost without exception, so 120 independent arguments
would have been 120 restatements of the signature — the exact noise this program exists to remove.
They get the `abi.rs` treatment instead: the Vulkan contract stated once in `lib.rs`, each site
naming which of three shapes it is.
The three are not equal, and separating them is the point. CREATE and RECORD carry no real
precondition — the device is owned, the builders are locals, nothing executes until submit. DESTROY
does: the GPU must not still be using the object, and that is established by the path (a fence wait,
a `queue_wait_idle`, a retired swapchain), not by the call. Those sites say so, because getting it
wrong is a use-after-free no type catches. The contract also tells the next person that a block
outside the three shapes needs a real proof, and that writing "as above" is the signal it doesn't
belong in them.
punktfunk-core's Windows half is finished here too: `qos_windows.rs`'s `GetLastError` reads (called
before anything can reset the thread's error slot) and `udp/windows.rs`'s control-message write,
whose argument is that `ctrl` is sized by `WSA_CMSG_SPACE(4)` — computed two lines up — so header
plus payload cannot run past it, and `write_unaligned` is used because `WSA_CMSG_DATA` offers no
alignment guarantee.
⚠️ THE WINDOWS BLIND SPOT BIT A THIRD TIME. A Linux measurement put this crate pair at 113; the
real number was 129 — `d3d11.rs`, `win32.rs`, `qos_windows.rs`, `udp/windows.rs` are all
`cfg`-hidden. Every crate in this sweep had to be finished on .47 after being "done" on .21. For a
cross-platform crate the Linux number is a lower bound, never the answer.
All three crates now deny `undocumented_unsafe_blocks`, which was the goal: it applied to 8 of 11
crates carrying unsafe, and the three exempt ones held 381 items between them — including the C ABI
surface and the presenter. Verified: Linux .21 fmt + both CI clippy steps rc=0; Windows .47 all four
closed crates clippy `-D warnings` rc=0 plus the full Windows CI clippy set and pf-capture's tests.
Only small crates remain unguarded (75 items total, largest 26).
65 lines
3.3 KiB
Rust
65 lines
3.3 KiB
Rust
//! The Vulkan session presenter (punktfunk-planning `linux-client-rearchitecture.md`,
|
|
//! Phase 1): an SDL3 window + ash swapchain that presents the shared session pump's
|
|
//! decoded frames, captures input on the `ui_stream` state-machine contract, and reports
|
|
//! the unified stats window on stdout. No UI toolkit anywhere in the dependency tree.
|
|
//!
|
|
//! Three frame paths: software (`CpuFrame` RGBA staging upload), Vulkan Video (the
|
|
//! decoder's VkImage on THIS device — plane views + the CICP-driven CSC pass), and on
|
|
//! Linux additionally VAAPI hardware (NV12 dmabuf imported per-plane — `dmabuf.rs`),
|
|
//! all composited by a letterboxed blit. Devices without the import extensions, and any
|
|
//! import/present failure streak, demote the decoder to software via the session pump's
|
|
//! `force_software` contract, same as the GTK presenter.
|
|
//!
|
|
//! Builds on Linux AND Windows; `dmabuf` is Linux-only (DRM-PRIME does not exist on
|
|
//! Windows) and `d3d11` is its Windows counterpart (D3D11VA shared-texture import) —
|
|
//! the decode chain there is Vulkan → D3D11VA → software.
|
|
|
|
// Unsafe-proof program: every `unsafe {}` in this crate carries a `// SAFETY:` proof.
|
|
#![deny(clippy::undocumented_unsafe_blocks)]
|
|
|
|
// THE VULKAN CONTRACT, stated once - most `// SAFETY:` proofs in this crate are an instance of it.
|
|
//
|
|
// Nearly every `unsafe` here is an `ash` call, which is `unsafe` because Vulkan is a C API, not
|
|
// because each call carries its own bespoke obligation. Three shapes recur, and only one of them
|
|
// has a real precondition worth restating per site:
|
|
//
|
|
// * CREATE / ALLOCATE - `create_*`, `allocate_*`. The device is live (this type owns it), and the
|
|
// `vk::*CreateInfo` builders are locals that outlive the synchronous call. The handle returned is
|
|
// owned by the value being constructed and destroyed in its `Drop`.
|
|
// * RECORD - `cmd_*`, `begin/end_command_buffer`, `update_descriptor_sets`. Recorded into a command
|
|
// buffer this code owns and has begun, referencing handles it also owns. Nothing executes until
|
|
// submit, so a recording error is not yet a memory error.
|
|
// * DESTROY - `destroy_*`, `free_*`, `unmap_memory`. THIS is the one with a real obligation: the
|
|
// GPU must not still be using the object. That is established on the path, not by the call - a
|
|
// fence wait, a `queue_wait_idle`, or the swapchain having been retired - and the per-site proofs
|
|
// say so, because getting it wrong is a use-after-free the type system cannot catch.
|
|
//
|
|
// A block doing something OUTSIDE these three shapes gets a real, specific proof; if you add one and
|
|
// find yourself writing "as above", it probably belongs in one of them.
|
|
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod csc;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod cursor;
|
|
#[cfg(windows)]
|
|
pub mod d3d11;
|
|
#[cfg(target_os = "linux")]
|
|
pub mod dmabuf;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod input;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod keymap_sdl;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod overlay;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
mod run;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod touch;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod vk;
|
|
#[cfg(windows)]
|
|
mod win32;
|
|
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub use run::{run_browse, run_session, ActionOutcome, Outcome, SessionOpts};
|