Files
punktfunk/packaging/windows/pf-vkhdr-layer
enricobuehler 51a005dd43 fix(deps): close the audit gaps, drop unused declarations, declare what is used
Acting on the 2026-08-13 dependency sweep. Every claim below was re-verified against
the tree before acting on it (greps carry a positive control; the advisories were
re-checked with cargo audit 0.22.2).

SECURITY
- event-listener 5.4.1 -> 5.4.2 (RUSTSEC-2026-0221, unsound Send/Sync on StackSlot;
  reaches the tray via zbus and the host via ashpd). This sat unnoticed because
  `cargo audit` reports unsoundness as a WARNING and the job fails only on
  vulnerabilities — audit.toml now says so out loud.
- spin 0.9.8 -> 0.9.9. 0.9.8 is YANKED and was genuinely compiled (flume via mdns-sd
  and relm4, plus lazy_static).
- wayland-scanner 0.31.10 -> 0.31.11, which moves quick-xml 0.39 -> 0.41. That is the
  exact trigger audit.toml documented for RUSTSEC-2026-0194/0195, so both ignores are
  deleted rather than left as permanent exceptions. Only RUSTSEC-2023-0071 (rsa
  Marvin, still unfixed upstream) remains.
- Corrected audit.toml's claim that `paste` arrives "via utoipa-axum": rav1d pulls it
  too, so every client has it through the decode path and dropping utoipa-axum would
  not have cleared it.

TWO CI GATES THAT SCANNED NOTHING
- `cargo audit` only ever reads the ROOT Cargo.lock. The drivers lock was already in
  this job's `paths:` filter, so edits to it triggered a run that then ignored them.
  All four secondary workspaces now get an explicit `--file` (verified: clean, bar the
  known `paste` warning in drivers).
- packaging/windows/pf-vkhdr-layer had NO lockfile at all while shipping as a DLL in
  the host installer, so every build resolved fresh and neither cargo-audit nor
  cargo-about ever saw it. Lockfile generated and committed, and added to `paths:`.

UNUSED / DUPLICATE DECLARATIONS
- punktfunk-host: removed 13 dependencies it never references — the Wayland stack
  (client, protocols{,-wlr,-misc}, scanner, backend), xkbcommon, reis, khronos-egl,
  ash, usbip-sim, parking_lot, bytemuck. The code moved to pf-inject and pf-zerocopy
  in the subsystem extraction and those crates declare them; only the manifest entries
  and their now-false comments stayed. Also dropped four redundant re-declarations
  (tokio/serde_json/futures-util in the Linux block, tower in dev-deps).
- Removed genuinely unused: bytes (punktfunk-core), anyhow (pf-win-display),
  tracing (clients/cli), anyhow (clients/session), serde (clients/windows).
- Removed the high-level `wdk` crate from all five driver crates and the drivers
  workspace: none of them ever referenced `wdk::` (62 `wdk_sys::` uses; pf-umdf-util
  is a full WDF crate that never declared it). `tracing`/`tracing-subscriber` remain
  in that lock afterwards but ONLY as wdk-sys build-dependencies, not in the DLLs.
- pf-win-display took punktfunk-core with `quic` for one type (`Mode`) that lives in
  the ungated `config` module; now `default-features = false`, which keeps
  quinn/tokio/rcgen/opus out of a leaf crate's declared closure.
- pf-encode declared the windows-rs feature `Wdk_Graphics_Direct3D` for a call that
  lives in pf-frame and is resolved via GetProcAddress on gdi32.

LATENT BREAKAGE (compiled only by feature unification)
- pf-inject uses `tokio::select!` without declaring `macros` (borrowed from
  punktfunk-core's quic feature); pf-capture uses `tokio::sync::oneshot` without
  declaring `sync` (borrowed from ashpd->zbus); pf-client-core uses the `minwindef`
  and `winnt` windows-rs headers without declaring them (borrowed from
  clients/windows). Each now declares what it uses, so an unrelated crate changing its
  features cannot break them.
- pf-console-ui took pf-client-core WITHOUT `default-features = false`, unlike every
  other consumer. That default is `pyrowave`, which compiles the vendored PyroWave C++
  — "fatal on Windows ARM64". Only safe today because the ARM64 leg passes
  --no-default-features (which also drops `ui`).

CORRECTED A FALSE INVARIANT
- clients/windows claimed "the workspace builds ONE windows-rs". It does not: wasapi
  pulls the crates.io windows 0.62.2 beside the git-rev copy. The invariant that DOES
  hold is narrower (reactor and that crate share one rev, which is what makes the
  IDXGISwapChain1 hand-off type-check). Comment rewritten, with a warning against
  "fixing" it via a blanket [patch.crates-io] — this rev uses header-named features
  while a dozen other manifests use the old Win32_* namespace ones.

Plus the safe in-compat `cargo update` sweep (no manifest edits).

Verified on macOS: punktfunk-core 385, pf-update-check 32, c_abi 1 (with
LIBRARY_PATH=/opt/homebrew/opt/opus/lib), cargo audit clean bar the two known
unmaintained warnings. Linux and Windows legs follow.
2026-08-13 12:41:47 +02:00
..

pf-vkhdr-layer — HDR Vulkan layer for the virtual display

A tiny Vulkan implicit layer (VK_LAYER_PUNKTFUNK_hdr_inject) that lets Vulkan games enable HDR while streaming over the punktfunk virtual display.

The problem it solves

On Windows, NVIDIA/AMD Vulkan ICDs do not advertise any HDR color space (VK_COLOR_SPACE_HDR10_ST2084_EXT, VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT) for a surface that lives on an IddCx indirect / virtual display — even when Windows "Use HDR" is on and the desktop is composited at 10-bit. So Vulkan games (Doom: The Dark Ages and the rest of id Tech, Indiana Jones and the Great Circle, …) query vkGetPhysicalDeviceSurfaceFormatsKHR, find no HDR color space, and refuse HDR ("This device does not support HDR"). D3D11/D3D12 HDR works on the very same display because the OS compositor drives it — only the Vulkan WSI enumeration is gated.

This was long believed unfixable from outside the GPU driver (the Apollo/Sunshine/Virtual-Display- Driver communities all concluded "it's in Windows's kernel"). It isn't: an on-box experiment proved the ICD happily accepts and presents a forced HDR swapchain on that exact virtual-display surface (vkCreateSwapchainKHR + vkSetHdrMetadataEXT + present all succeed) — it simply won't advertise the format. So the whole fix is to add the HDR surface formats to the enumeration the game queries; once the game requests that swapchain, the ICD honors it. Validated live: Doom: The Dark Ages enables HDR over the virtual display with this layer.

What it does

  • Intercepts vkGetPhysicalDeviceSurfaceFormatsKHR / ...2KHR, calls down to the ICD, and appends {A2B10G10R10_UNORM_PACK32, HDR10_ST2084_EXT} + {R16G16B16A16_SFLOAT, EXTENDED_SRGB_LINEAR_EXT} (deduped — a no-op on real HDR monitors that already list them).
  • Self-gates: it only injects when the surface's monitor actually has Windows advanced-color (HDR) enabled right now (checked via DisplayConfigGetDeviceInfo / GET_ADVANCED_COLOR_INFO). So it does nothing on SDR sessions/displays — no washed-out "SDR-in-HDR". It tracks VkSurfaceKHR → HWND by intercepting vkCreateWin32SurfaceKHR.
  • Everything else is pass-through dispatch chaining (instance + device).

It is shipped as an always-on implicit layer (loads via the registry, so it works regardless of how a game is launched — including via an already-running Steam, which env-based scoping can't guarantee). Because of the self-gate it is inert outside HDR streaming.

Controls

Variable Effect
DISABLE_PF_VKHDR=1 Loader-standard off-switch — disables the whole layer for that process.
PF_VKHDR_EXCLUDE=foo.exe,bar.exe Extra exe basenames to skip (in addition to a small built-in kernel-anti-cheat default list: cs2.exe, rainbowsix.exe, …).
PF_VKHDR_LOG=1 Write a debug log to %TEMP%\pf_vkhdr_layer.log.

Build / install

Standalone crate (own [workspace]), Windows-only cdylib:

cargo build --release           # -> target/release/pf_vkhdr_layer.dll

The host installer (packaging/windows/pack-host-installer.ps1punktfunk-host.iss) builds it, lays pf_vkhdr_layer.dll + pf_vkhdr_layer.json into {app}\vklayer, and registers it under HKLM64\SOFTWARE\Khronos\Vulkan\ImplicitLayers (opt-out task "Install the HDR Vulkan layer").

Manual dev install: drop the DLL + JSON in one directory and add a REG_DWORD value named after the JSON's full path (data 0) under HKLM\SOFTWARE\Khronos\Vulkan\ImplicitLayers (or HKCU\...). Confirm with vulkaninfo (Surface section) — HDR10_ST2084_EXT should appear when the display has HDR enabled.

Notes

  • x64 only (the Windows host is x64 only).
  • Anti-cheat: the layer is benign (it only adds surface formats; it never touches rendering, memory, or input) and is signed, but because it's always-on it is present in every Vulkan process. The built-in exclude list + PF_VKHDR_EXCLUDE + DISABLE_PF_VKHDR cover kernel-anti- cheat titles you'd rather it stay out of.