diff --git a/.gitea/workflows/deb.yml b/.gitea/workflows/deb.yml index 8173feff..55603107 100644 --- a/.gitea/workflows/deb.yml +++ b/.gitea/workflows/deb.yml @@ -94,7 +94,10 @@ jobs: # Linux NVIDIA; design/linux-direct-nvenc.md). AMD/Intel-safe — NVENC/CUDA is dlopen'd at # runtime (no link-time dep; identical DT_NEEDED to a plain build), and the encoder is only # constructed for a CUDA capture frame + PUNKTFUNK_NVENC_DIRECT, never on VAAPI hosts. - cargo build --release --locked --features punktfunk-host/nvenc \ + # --features punktfunk-host/vulkan-encode: the AMD/Intel twin — raw VK_KHR_video_encode_h265 + # with real RFI (design/linux-vulkan-video-encode.md). Pure Rust ash (no new lib / link dep); + # default on for HEVC (PUNKTFUNK_VULKAN_ENCODE=0 → libav VAAPI), failed open falls back to VAAPI. + cargo build --release --locked --features punktfunk-host/nvenc,punktfunk-host/vulkan-encode \ -p punktfunk-host -p punktfunk-client-linux -p punktfunk-client-session - name: Build + smoke-boot web console (bun preset) diff --git a/crates/punktfunk-host/src/encode.rs b/crates/punktfunk-host/src/encode.rs index 944fbf3e..41308209 100644 --- a/crates/punktfunk-host/src/encode.rs +++ b/crates/punktfunk-host/src/encode.rs @@ -873,18 +873,20 @@ fn nvenc_direct_enabled() -> bool { .unwrap_or(true) } -/// Whether the raw Vulkan Video HEVC encode backend is active for AMD/Intel. **Opt-in for now** -/// (design/linux-vulkan-video-encode.md) — `PUNKTFUNK_VULKAN_ENCODE=1` (also `true`/`yes`/`on`) -/// selects it over libav VAAPI for an HEVC session; it gives real reference-frame invalidation -/// (a clean P-frame recovery anchor via explicit DPB reference slots) that the libavcodec VAAPI -/// path can't express. Will flip to default-on after on-glass validation, like -/// [`nvenc_direct_enabled`]. Only consulted with `--features vulkan-encode`; a failed open falls -/// back to VAAPI, so this can only improve recovery, never break a stream. +/// Whether the raw Vulkan Video HEVC encode backend is active for AMD/Intel. **Default ON** — +/// on-glass validated 2026-07-12 on an AMD RADV 780M with a real Deck-class client: the pipelined +/// encoder ran a rock-solid 1080p@240 HEVC session and healed loss with clean P-frame recovery +/// anchors (never IDR) via explicit DPB reference slots — real reference-frame invalidation the +/// libavcodec VAAPI path can't express (design/linux-vulkan-video-encode.md). `PUNKTFUNK_VULKAN_ENCODE=0` +/// (also `false`/`no`/`off`) is the libav-VAAPI escape hatch. Only consulted with +/// `--features vulkan-encode`, and a failed open falls back to VAAPI, so an unsupported device +/// (e.g. a Mesa without h265 encode, or an untested Intel/ANV where the path misbehaves at open) +/// degrades gracefully to the old backend rather than breaking the stream. #[cfg(all(target_os = "linux", feature = "vulkan-encode"))] fn vulkan_encode_enabled() -> bool { std::env::var("PUNKTFUNK_VULKAN_ENCODE") - .map(|v| matches!(v.trim(), "1" | "true" | "yes" | "on")) - .unwrap_or(false) + .map(|v| !matches!(v.trim(), "0" | "false" | "no" | "off")) + .unwrap_or(true) } /// Cheap, side-effect-free NVIDIA-presence probe for the `auto` backend selector: the NVIDIA diff --git a/crates/punktfunk-host/src/encode/linux/vulkan_video.rs b/crates/punktfunk-host/src/encode/linux/vulkan_video.rs index a92aa680..f067df08 100644 --- a/crates/punktfunk-host/src/encode/linux/vulkan_video.rs +++ b/crates/punktfunk-host/src/encode/linux/vulkan_video.rs @@ -24,10 +24,11 @@ const IMPORT_CACHE_CAP: usize = 16; const CSC_SPV: &[u8] = include_bytes!("rgb2yuv.spv"); /// DPB ring depth (well under the RADV `maxDpbSlots=17`); also the RFI recovery window. const DPB_SLOTS: u32 = 8; -/// In-flight frame ring: how many captures may have GPU work outstanding at once. 3 overlaps a -/// frame's CSC+encode with the next capture (the throughput win) while keeping added latency tiny -/// (backpressure kicks in at the 3rd unread frame). Distinct from `DPB_SLOTS` (reference pool). -const RING_DEFAULT: usize = 3; +/// In-flight frame ring: how many captures may have GPU work outstanding at once. 2 overlaps a +/// frame's CSC+encode with the next capture (the throughput win) at the lowest possible added +/// latency — on-glass validated as rock-solid at 1080p@240, so it is the real-time default; +/// backpressure kicks in at the 2nd unread frame. Distinct from `DPB_SLOTS` (reference pool). +const RING_DEFAULT: usize = 2; /// Resolve the in-flight ring depth: `PUNKTFUNK_VULKAN_INFLIGHT` (clamped 2..=6), else `RING_DEFAULT`. fn ring_depth() -> usize { diff --git a/packaging/arch/PKGBUILD b/packaging/arch/PKGBUILD index 86b0de70..9e2e8dbb 100644 --- a/packaging/arch/PKGBUILD +++ b/packaging/arch/PKGBUILD @@ -73,7 +73,11 @@ build() { # DT_NEEDED as a plain build (no libcuda/libnvidia-encode), so the binary starts fine driver-less # and only touches NVIDIA on a CUDA capture frame (default on NVIDIA; PUNKTFUNK_NVENC_DIRECT=0 # opts back to libav). AMD/Intel never reach it — the `cuda` gate leaves them on VAAPI. - cargo build --release --locked --features punktfunk-host/nvenc \ + # `punktfunk-host/vulkan-encode` is the AMD/Intel twin: a raw VK_KHR_video_encode_h265 backend with + # real RFI (clean P-frame recovery anchor via DPB reference slots; design/linux-vulkan-video-encode.md). + # Pure Rust `ash` (no new lib, no link-time deps); default on for HEVC (PUNKTFUNK_VULKAN_ENCODE=0 + # opts back to libav VAAPI), and a failed open falls back to VAAPI so unsupported devices are safe. + cargo build --release --locked --features punktfunk-host/nvenc,punktfunk-host/vulkan-encode \ -p punktfunk-host -p punktfunk-client-linux -p punktfunk-client-session -p punktfunk-tray # Management web console (opt-in): the Nitro `bun`-preset .output bundle (Bun.serve TLS), # built AND run with bun. diff --git a/packaging/rpm/punktfunk.spec b/packaging/rpm/punktfunk.spec index fccda36e..5d6c1979 100644 --- a/packaging/rpm/punktfunk.spec +++ b/packaging/rpm/punktfunk.spec @@ -180,7 +180,11 @@ export PUNKTFUNK_BUILD_VERSION="%{version}-%{release}" # at runtime (no link-time dep; __requires_exclude already drops libcuda), so the binary starts # driver-less; the encoder engages only on a CUDA frame (default on NVIDIA; PUNKTFUNK_NVENC_DIRECT=0 # opts back to libav) — the `cuda` gate keeps AMD/Intel on VAAPI regardless. -cargo build --release --locked --features punktfunk-host/nvenc \ +# --features punktfunk-host/vulkan-encode: the AMD/Intel twin — a raw VK_KHR_video_encode_h265 backend +# with real RFI (clean P-frame recovery anchor via DPB reference slots; design/linux-vulkan-video-encode.md). +# Pure Rust `ash` (no new lib / no link-time dep); default on for HEVC (PUNKTFUNK_VULKAN_ENCODE=0 opts +# back to libav VAAPI), and a failed open falls back to VAAPI so unsupported devices degrade gracefully. +cargo build --release --locked --features punktfunk-host/nvenc,punktfunk-host/vulkan-encode \ -p punktfunk-host -p punktfunk-client-linux -p punktfunk-client-session -p punktfunk-tray %if %{with web}