An over-declared HEVC level no longer demotes native Vulkan decode, and the Windows client legs build again #181

Merged
enricobuehler merged 4 commits from worktree-vk-level-gate-clamp into main 2026-08-12 16:48:57 +00:00
Owner

A field report (client swapped Intel B580 → RTX 5060, Windows) read "native-vulkan runs only with AV1; HEVC runs d3d11va". The reporter's log had the whole story: their host stamps general_level_idc 6.2 (the codec maximum — AMF's auto does this) on a 4K120 HEVC stream that needs 5.2, the NVIDIA driver reports a 6.1 decode ceiling, and pf-vkdecode's up-front declared-level gate refused every AU — an 81-fail streak, demotion to D3D11VA, and ~1.5 s of "PPS 0 not seen" until the next IDR. The hardware decodes the actual stream trivially; only the declaration was oversized.

The fix (fix(pf-vkdecode)): the H.264/H.265 level gates warn once and proceed, and every VPS/SPS handed to the Vulkan parameters object is clamped to the device's maxLevelIdc (a set above the ceiling is invalid usage). The stream's real demands stay enforced where they are physical facts — coded extent and DPB depth at session build. AV1's gate is untouched. Unit tests pin the clamp (lowers, only lowers, mutates the driver-visible block in place).

Validated on glass on the RTX 4090 box (.173, driver 610.88): with an NVENC host hacked to stamp level 6.2, the pre-fix client reproduces the exact field demotion signature; the fixed client holds native Vulkan HEVC at 60 fps with the single warn line. HEVC and AV1 both decode on the native rung against an unmodified host.

Two Windows-gate breakers fixed en route (main's push runs 17615/17616 at the #177 merge are red at Build; #180's follow-up could only reach the gates its own CI ran):

  • punktfunk-client-session still carries #![forbid(unsafe_code)] over the edition-2024 unsafe { env::set_var } startup writes — two hard errors on every Windows leg. Same resolution #180 gave the GTK shell: forbiddeny plus localized #[allow(unsafe_code)] at the three documented SAFETY sites.
  • pf-presenter win32.rs: clippy 1.96's manual_dangling_ptr fires on the 1 as *const u16 MAKEINTRESOURCE cast (masked on main by the build failing first) — now ptr::without_provenance(1).

Gates run on .173 (x86_64-msvc): cargo clippy -p pf-vkdecode -p pf-client-core -p pf-presenter -p punktfunk-client-session -p punktfunk-client-windows --all-targets -- -D warnings = clean, pf-vkdecode 194/194 (debug; --release fails a pre-existing should_panic-on-debug_assert slots test unrelated to this branch), cargo fmt --all --check clean.

Follow-up not in this PR: the host's ffmpeg AMF/QSV encode paths set no HEVC level, so AMF defaults to 6.2 — stamping the minimal correct level at the source is a host-side ticket.

A field report (client swapped Intel B580 → RTX 5060, Windows) read "native-vulkan runs only with AV1; HEVC runs d3d11va". The reporter's log had the whole story: their host stamps `general_level_idc` **6.2** (the codec maximum — AMF's auto does this) on a 4K120 HEVC stream that needs 5.2, the NVIDIA driver reports a **6.1** decode ceiling, and pf-vkdecode's up-front declared-level gate refused every AU — an 81-fail streak, demotion to D3D11VA, and ~1.5 s of "PPS 0 not seen" until the next IDR. The hardware decodes the actual stream trivially; only the declaration was oversized. **The fix** (`fix(pf-vkdecode)`): the H.264/H.265 level gates warn once and proceed, and every VPS/SPS handed to the Vulkan parameters object is clamped to the device's `maxLevelIdc` (a set above the ceiling is invalid usage). The stream's real demands stay enforced where they are physical facts — coded extent and DPB depth at session build. AV1's gate is untouched. Unit tests pin the clamp (lowers, only lowers, mutates the driver-visible block in place). **Validated on glass** on the RTX 4090 box (.173, driver 610.88): with an NVENC host hacked to stamp level 6.2, the pre-fix client reproduces the exact field demotion signature; the fixed client holds native Vulkan HEVC at 60 fps with the single warn line. HEVC and AV1 both decode on the native rung against an unmodified host. **Two Windows-gate breakers fixed en route** (main's push runs 17615/17616 at the #177 merge are red at Build; #180's follow-up could only reach the gates its own CI ran): - `punktfunk-client-session` still carries `#![forbid(unsafe_code)]` over the edition-2024 `unsafe { env::set_var }` startup writes — two hard errors on every Windows leg. Same resolution #180 gave the GTK shell: `forbid` → `deny` plus localized `#[allow(unsafe_code)]` at the three documented SAFETY sites. - pf-presenter `win32.rs`: clippy 1.96's `manual_dangling_ptr` fires on the `1 as *const u16` MAKEINTRESOURCE cast (masked on main by the build failing first) — now `ptr::without_provenance(1)`. Gates run on .173 (x86_64-msvc): `cargo clippy -p pf-vkdecode -p pf-client-core -p pf-presenter -p punktfunk-client-session -p punktfunk-client-windows --all-targets -- -D warnings` = clean, pf-vkdecode 194/194 (debug; `--release` fails a pre-existing `should_panic`-on-`debug_assert` slots test unrelated to this branch), `cargo fmt --all --check` clean. Follow-up not in this PR: the host's ffmpeg AMF/QSV encode paths set no HEVC level, so AMF defaults to 6.2 — stamping the minimal correct level at the source is a host-side ticket.
enricobuehler added 4 commits 2026-08-12 16:48:33 +00:00
A 2026-08-12 field report (RTX 5060 client): every HEVC session demoted to
D3D11VA with 81 "outside device caps: stream level (Std code point 12) above
the device's maxLevelIdc (H.265 Std level 11)" refusals — the host's AMF
encoder stamps general_level_idc 6.2 (the codec maximum) on a 4K120 stream
that needs 5.2, and NVIDIA's driver caps H.265 decode at 6.1. The hardware
decodes the actual stream trivially; only the declaration was oversized.
AV1 passed the same gate, which is why "native-vulkan runs only with AV1".

The declared level is a claim, and the stream's real demands are enforced
where they are physical facts — coded extent and DPB depth, both checked at
session build. So the up-front level gate (H.264 + H.265) now warns once and
proceeds, and every SPS/VPS handed to the Vulkan parameters object has its
level clamped to the device ceiling (a set above maxLevelIdc is invalid
usage). AV1's gate is untouched: its code space is the bitstream's own and
no over-declaration has been seen in the field.

Verified on .173 (RTX 4090, driver 610.88): HEVC and AV1 both decode on the
native Vulkan rung at 60 fps against an NVENC host; unit tests pin the clamp
(lowers, only lowers, mutates the driver-visible block in place).
The half of the #177 fallout #180's follow-up could not reach: WP20 wrapped
the session bin's single-threaded-startup env writes in the `unsafe {}`
blocks edition 2024 requires — under `#![forbid(unsafe_code)]`, which no
inner attribute can override, so `punktfunk-client-session` fails with two
hard errors on every Windows leg (main push runs 17615/17616 red at Build;
verified on .173). Same resolution as #180 gave the GTK shell: `forbid`
becomes `deny`, and the three documented SAFETY sites carry the localized
`#[allow(unsafe_code)]` pf-update models.
fix(pf-presenter): spell MAKEINTRESOURCE(1) as ptr::without_provenance — clippy 1.96's manual_dangling_ptr reads the integer-ordinal cast as a dangling pointer and fails the Windows -D warnings gate (masked on main by the client bins failing to build first)
windows / build (aarch64-pc-windows-msvc) (pull_request) Successful in 1m16s
ci / bun-nix (pull_request) Successful in 26s
ci / web (pull_request) Failing after 1m35s
apple / swift (pull_request) Successful in 1m42s
apple / screenshots (pull_request) Skipped
ci / docs-site (pull_request) Successful in 1m18s
ci / rust (pull_request) Failing after 2m21s
ci / rust-arm64 (pull_request) Successful in 3m45s
windows / build (x86_64-pc-windows-msvc) (pull_request) Successful in 2m42s
android / android (pull_request) Successful in 4m29s
faefbae830
enricobuehler scheduled this pull request to auto merge when all checks succeed 2026-08-12 16:48:54 +00:00
enricobuehler merged commit 77918674c3 into main 2026-08-12 16:48:57 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unom/punktfunk#181