Say which GPU can do Vulkan Video, and why not when it can't #89
Merged
enricobuehler
merged 1 commits from 2026-08-07 10:50:27 +00:00
worktree-vulkan-decode-probe into main
1
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
413a3e3e76 |
feat(client): say which GPU can do Vulkan Video, and why not when it can't
ci / bun-nix (pull_request) Successful in 29s
ci / rust-arm64 (pull_request) Successful in 1m44s
windows / build (aarch64-pc-windows-msvc) (pull_request) Successful in 1m5s
apple / swift (pull_request) Successful in 1m35s
apple / screenshots (pull_request) Skipped
android / android (pull_request) Successful in 3m21s
windows / build (x86_64-pc-windows-msvc) (pull_request) Successful in 2m1s
ci / rust (pull_request) Successful in 4m27s
ci / docs-site (pull_request) Failing after 16m24s
ci / web (pull_request) Failing after 16m25s
Field report from an Intel Arc + NVIDIA laptop: pinning the Vulkan rung on the Arc iGPU silently produced D3D11VA, and there was no way to tell whether the build had tried at all. That ambiguity was ours, in three places. The "unavailable" log printed three of the FIVE conjuncts that gate Vulkan Video. A device with 1.3, the features and a decode queue family — but no codec extension — logged dev_is_13=true features_ok=true decode_family=true next to the word "unavailable" and named nothing actionable. It now prints all five, plus which base extensions are missing, which codec extensions are present, the decode family's own advertised codec operations, and the device name and vendor. It also no longer says "VAAPI/software" on Windows, where the rung below is D3D11VA. The native-vulkan PIN refusal logged `video_decode` alone. On a device that decodes something but not THIS codec, that reads as a contradiction: refused, yet video_decode=true. It now carries the caps mask and the codec bit that was wanted, so "your GPU can't" is distinguishable from "we asked for the wrong thing" — only the second is our bug. And `--probe-decode` is new: per-adapter Vulkan Video capability with no session, no surface and no logical device. For each GPU it answers usable yes/no, the driver's own decode ops, the extensions, and — when the answer is no — which conjunct failed, in words. Separate from --list-adapters, which the desktop shells parse line-by-line for their GPU picker and which therefore keeps printing bare names. The listing is ordered like pick_device (discrete first) and marks entry 0 as the default presenter, because that ordering is very likely the reporter's actual answer: pick_device ranks DISCRETE_GPU above INTEGRATED_GPU, Vulkan Video decodes on the PRESENTER's device by design (that is what makes it zero-copy), and PUNKTFUNK_DECODER does not move the presenter. So on a hybrid laptop, pinning the decoder while the dGPU presents probes the wrong GPU entirely — PUNKTFUNK_VK_DEVICE=<index> is the knob that moves it, and the index printed is that value. To keep the probe honest, VIDEO_BASE and VIDEO_CODECS moved to module scope and the five-way AND became video_decode_gate(), called by both the probe and device creation. A probe holding its own copy of the rule is one that eventually reports a capability the session then refuses — which reads to everyone as a decoder bug rather than a probe bug. Gates: fmt clean; clippy -D warnings over punktfunk-client-session and pf-presenter. The Linux container was unavailable (the host's disk filled and took the docker daemon with it), so this ran on the macOS host target only — the container leg is owed, and CI covers it on the PR. |