Field report (2026-08-08, end user on a Steam Deck): "Sometimes I got an error saying that the decoder was not found and then it fell back to h264, but other times it worked."
Two separate defects, one of which explains the report and one of which would have sent the triage the wrong way.
1. The 4:4:4 advertisement was a promise nothing checked
VIDEO_CAP_444 rode the "Full chroma" setting alone, with a comment saying the software rung was the floor underneath it. M8 removed that floor — there is no permissively licensed software HEVC decoder, so software_decodable_codecs() is H264 | AV1. The host grants 4:4:4 on HEVC only, and answers the resolved chroma in the Welcome before the client builds a decoder.
So on a device with no 4:4:4 decode, the toggle did not cost crispness — it cost the entire codec:
Welcome resolves 4:4:4 → Vulkan rung refuses the shape at construction
→ VAAPI refuses it too → no CPU rung for HEVC
→ NoSoftwareRung → reconnect advertising H.264 only
→ "HEVC decoding failed on this device — reconnecting"
AMD has no HEVC 4:4:4 decode on any silicon (verified two independent ways — see the vendor matrix work), the Deck included. H.264 never shows this symptom because it has a CPU rung underneath it.
Why it looked intermittent:enable_444 is per-profile and defaults off — "a 'Work' profile wants it; 'Game' usually doesn't". Same Deck, same host, same session: the Work profile loses HEVC where Game keeps it. A second source of variance is the host's own 4:4:4 encode probe, which only NVIDIA passes.
The fix
Gated on hevc_444_hardware_decodable, which asks the driver through the same code the rung uses at construction (VkH265Decoder::probe_stream_support) — so the advertisement and the rung that has to honour it cannot disagree. It costs a handful of capability queries, no session, no images, no submits, and && short-circuits so a box that never enabled Full chroma pays nothing.
Both depths are required, not either. With HDR on the host may resolve 4:4:4 10-bit, and a device offering YUV444_8 but not YUV444_10 would land in exactly the hole this closes.
Answering from the Vulkan rung alone is exact, not approximate — it is the only rung in this build that implements 4:4:4 at all: pf_vaadec::profile_for maps only chroma_format_idc == 1 and errors UnsupportedShape on 3; pf_dxvadec's config refuses "anything but 4:2:0" by construction; the CPU rung is 8-bit 4:2:0. That is also why an Intel box — whose hardware has done HEVC 4:4:4 since Ice Lake — is still false here: our DXVA/VAAPI rungs do not implement it, so advertising it would be a lie about us, not about the GPU.
The user is not left guessing: a warn names the setting, the reason, and PyroWave as the 4:4:4 path that works on any GPU.
One deliberate non-change: VIDEO_CAP_10BIT / VIDEO_CAP_HDR
These are advertised unprobed for the same reason 4:4:4 was, and I left them alone on purpose. The asymmetry is real: all three hardware rungs implement 10-bit 4:2:0 (profile_for maps (H265, 1, 10) and (Av1, 1, 10); pf-dxvadec carries P010), so a Vulkan-only probe there would answer false on boxes whose VAAPI/DXVA rung decodes 10-bit perfectly and would silently withdraw HDR from them — a visible regression bought against a case never observed. Gating 10-bit honestly needs a libva/D3D11 probe this path cannot afford, for the same reason av1_hardware_decodable does not consult VAAPI. Measured on a Deck: HEVC Main and Main 10 both offer the full format set, so 10-bit was never this bug.
2. --probe-decode described a different device from the one that streams
The RADV video-decode opt-in sat after the --list-adapters / --probe-decode / --list-audio / --pair early exits, so the triage tool never had it. Measured on a Deck (canary e22af40f), same binary, back to back:
invocation
verdict
--probe-decode
vulkan video decode: no · driver decode ops: none (0x0) · no queue family advertises VIDEO_DECODE
RADV_PERFTEST=video_decode … --probe-decode
vulkan video decode: YES · H.264, H.265, AV1, VP9 (0xF)
The tool exists to be believed. Any Deck triage that consulted it reached the opposite of the truth — including, briefly, this one. Hoisted to the top of run, ahead of every early exit; nothing touches Vulkan before it (main calls run directly).
Shape of the change
The bit arithmetic moves into video::video_caps_for — a pure function — so the part that was actually wrong is testable without a GPU, a host or a Hello, in the spirit of last_rung_verdict. The device question stays with the caller, which owns the expensive probe and logs its own refusal with the user's setting in hand.
Verification
Run in the pf-lxcheck2 Linux container (pf-client-core does not build on macOS at all):
cargo fmt --all -- --check — clean
cargo build (plain, not only --all-targets — that hides "dead outside tests") — clean
cargo clippy --all-targets -- -D warnings — clean
cargo test -p pf-client-core — 185 passed, 0 failed
The new test is verified non-vacuous: planting the original defect (if want_444 → if true) fails it with exactly the intended assertion — a 4:4:4 promise this device cannot keep costs HEVC entirely, left: 4, right: 0.
Re-run green after rebasing onto e22082ac; no overlap with anything that landed meanwhile.
What is NOT verified
⏳The fixed binary has never run on a Deck. Fix 2's outcome is bracketed by the two real Deck measurements above plus std::env::set_var → setenv(3) and verified ordering, so it is determined rather than guessed — but the on-glass confirmation is owed. It needs new packages in a dev container, so it was left rather than done half-way.
⏳ Fix 1's Some(vk) arm needs a GPU and has no test; only the None arm and the bit arithmetic are covered here.
⏳ The reporting user's log and settings were never obtained, so which mechanism fired for them is unconfirmed. The confirming evidence would be: whether their profile had Full chroma on, and which host they dialled.
Field report (2026-08-08, end user on a Steam Deck): *"Sometimes I got an error saying that the decoder was not found and then it fell back to h264, but other times it worked."*
Two separate defects, one of which explains the report and one of which would have sent the triage the wrong way.
## 1. The 4:4:4 advertisement was a promise nothing checked
`VIDEO_CAP_444` rode the "Full chroma" setting alone, with a comment saying the software rung was the floor underneath it. **M8 removed that floor** — there is no permissively licensed software HEVC decoder, so `software_decodable_codecs()` is `H264 | AV1`. The host grants 4:4:4 on **HEVC only**, and answers the resolved chroma in the Welcome *before* the client builds a decoder.
So on a device with no 4:4:4 decode, the toggle did not cost crispness — it cost the entire codec:
```
Welcome resolves 4:4:4 → Vulkan rung refuses the shape at construction
→ VAAPI refuses it too → no CPU rung for HEVC
→ NoSoftwareRung → reconnect advertising H.264 only
→ "HEVC decoding failed on this device — reconnecting"
```
AMD has **no HEVC 4:4:4 decode on any silicon** (verified two independent ways — see the vendor matrix work), the Deck included. H.264 never shows this symptom because it has a CPU rung underneath it.
**Why it looked intermittent:** `enable_444` is **per-profile** and defaults off — *"a 'Work' profile wants it; 'Game' usually doesn't"*. Same Deck, same host, same session: the Work profile loses HEVC where Game keeps it. A second source of variance is the host's own 4:4:4 encode probe, which only NVIDIA passes.
### The fix
Gated on `hevc_444_hardware_decodable`, which asks the driver through the **same code the rung uses at construction** (`VkH265Decoder::probe_stream_support`) — so the advertisement and the rung that has to honour it cannot disagree. It costs a handful of capability queries, no session, no images, no submits, and `&&` short-circuits so a box that never enabled Full chroma pays nothing.
**Both depths are required, not either.** With HDR on the host may resolve 4:4:4 **10-bit**, and a device offering `YUV444_8` but not `YUV444_10` would land in exactly the hole this closes.
**Answering from the Vulkan rung alone is exact, not approximate** — it is the only rung in this build that implements 4:4:4 at all: `pf_vaadec::profile_for` maps only `chroma_format_idc == 1` and errors `UnsupportedShape` on 3; `pf_dxvadec`'s config refuses "anything but 4:2:0" by construction; the CPU rung is 8-bit 4:2:0. That is also why an Intel box — whose *hardware* has done HEVC 4:4:4 since Ice Lake — is still `false` here: our DXVA/VAAPI rungs do not implement it, so advertising it would be a lie about **us**, not about the GPU.
The user is not left guessing: a `warn` names the setting, the reason, and PyroWave as the 4:4:4 path that works on any GPU.
### One deliberate non-change: `VIDEO_CAP_10BIT` / `VIDEO_CAP_HDR`
These are advertised unprobed for the same reason 4:4:4 was, and I left them alone **on purpose**. The asymmetry is real: all three hardware rungs implement 10-bit 4:2:0 (`profile_for` maps `(H265, 1, 10)` and `(Av1, 1, 10)`; pf-dxvadec carries P010), so a Vulkan-only probe there would answer `false` on boxes whose VAAPI/DXVA rung decodes 10-bit perfectly and would **silently withdraw HDR from them** — a visible regression bought against a case never observed. Gating 10-bit honestly needs a libva/D3D11 probe this path cannot afford, for the same reason `av1_hardware_decodable` does not consult VAAPI. Measured on a Deck: HEVC Main **and** Main 10 both offer the full format set, so 10-bit was never this bug.
## 2. `--probe-decode` described a different device from the one that streams
The RADV video-decode opt-in sat *after* the `--list-adapters` / `--probe-decode` / `--list-audio` / `--pair` early exits, so the triage tool never had it. Measured on a Deck (canary `e22af40f`), **same binary, back to back**:
| invocation | verdict |
|---|---|
| `--probe-decode` | `vulkan video decode: no` · `driver decode ops: none (0x0)` · `no queue family advertises VIDEO_DECODE` |
| `RADV_PERFTEST=video_decode … --probe-decode` | `vulkan video decode: YES` · `H.264, H.265, AV1, VP9 (0xF)` |
The tool exists to be believed. Any Deck triage that consulted it reached the opposite of the truth — including, briefly, this one. Hoisted to the top of `run`, ahead of every early exit; nothing touches Vulkan before it (`main` calls `run` directly).
## Shape of the change
The bit arithmetic moves into `video::video_caps_for` — a pure function — so the part that was actually wrong is testable without a GPU, a host or a Hello, in the spirit of `last_rung_verdict`. The device question stays with the caller, which owns the expensive probe and logs its own refusal with the user's setting in hand.
## Verification
Run in the `pf-lxcheck2` Linux container (`pf-client-core` does not build on macOS at all):
- `cargo fmt --all -- --check` — clean
- `cargo build` (plain, **not** only `--all-targets` — that hides "dead outside tests") — clean
- `cargo clippy --all-targets -- -D warnings` — clean
- `cargo test -p pf-client-core` — **185 passed, 0 failed**
The new test is **verified non-vacuous**: planting the original defect (`if want_444` → `if true`) fails it with exactly the intended assertion — `a 4:4:4 promise this device cannot keep costs HEVC entirely`, `left: 4, right: 0`.
Re-run green after rebasing onto `e22082ac`; no overlap with anything that landed meanwhile.
## What is NOT verified
- ⏳ **The fixed binary has never run on a Deck.** Fix 2's outcome is bracketed by the two real Deck measurements above plus `std::env::set_var` → `setenv(3)` and verified ordering, so it is determined rather than guessed — but the on-glass confirmation is owed. It needs new packages in a dev container, so it was left rather than done half-way.
- ⏳ Fix 1's `Some(vk)` arm needs a GPU and has no test; only the `None` arm and the bit arithmetic are covered here.
- ⏳ The reporting user's log and settings were never obtained, so *which* mechanism fired for **them** is unconfirmed. The confirming evidence would be: whether their profile had Full chroma on, and which host they dialled.
Two Steam Deck findings from a field report of "the decoder was not found, it
fell back to H.264 — but sometimes HEVC worked".
**The 4:4:4 advertisement was a promise nothing checked.** `VIDEO_CAP_444` rode
the "Full chroma" setting alone. That was safe while a software HEVC decoder
existed underneath it; M8 removed one (there is no permissively licensed HEVC
CPU decoder, so `software_decodable_codecs()` is H.264|AV1). The host grants
4:4:4 on HEVC ONLY, and answers the resolved chroma in the Welcome before the
client builds a decoder — so on a device with no 4:4:4 decode the toggle did not
cost crispness, it cost the entire codec: the Vulkan rung refuses the shape at
construction, VAAPI refuses it too, there is no CPU rung, and the session
reconnects on H.264. AMD has no HEVC 4:4:4 decode on any silicon, so every Deck
with that switch on lost HEVC. It is per-profile and default-off, which is
exactly why it looked intermittent — a "Work" profile lost HEVC where "Game"
kept it, same box, same host.
Gated on `hevc_444_hardware_decodable`, which asks the driver through the SAME
code the rung uses at construction (`VkH265Decoder::probe_stream_support`), so
the advertisement and the rung that must honour it cannot disagree. Both depths
are required, not either: with HDR on the host may resolve 4:4:4 10-bit, and a
device offering YUV444_8 but not YUV444_10 would land in the same hole.
Answering from the Vulkan rung alone is exact rather than approximate — it is
the only rung in this build that implements 4:4:4 at all (`pf_vaadec::profile_for`
errors on chroma_format_idc 3, pf-dxvadec refuses anything but 4:2:0, the CPU
rung is 8-bit 4:2:0). Deliberately NOT extended to VIDEO_CAP_10BIT/HDR: all
three rungs implement 10-bit 4:2:0, so a Vulkan-only probe there would withdraw
HDR from boxes whose VAAPI/DXVA rung decodes it perfectly — a real regression
against a case never observed.
The bit arithmetic moves into `video::video_caps_for` so the part that was
wrong is testable without a GPU, a host or a Hello; the test is verified
non-vacuous against the planted original defect.
**`--probe-decode` described a different device from the one that streams.** The
RADV video-decode opt-in sat AFTER the --list-adapters/--probe-decode/--list-audio
/--pair early exits, so the triage tool never had it. Measured on a Deck
(canary e22af40f), same binary back to back: bare `--probe-decode` printed
"vulkan video decode: no", "driver decode ops: none (0x0)", "no queue family
advertises VIDEO_DECODE"; with RADV_PERFTEST=video_decode in the environment,
"YES" and "H.264, H.265, AV1, VP9". Any Deck triage that consulted it reached
the opposite of the truth. Hoisted to the top of `run`, ahead of every early
exit — nothing touches Vulkan before it (`main` calls `run` directly).
Gates, in the Linux container: fmt, plain `cargo build` (not only
--all-targets), `clippy --all-targets -D warnings`, and 185 tests.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Field report (2026-08-08, end user on a Steam Deck): "Sometimes I got an error saying that the decoder was not found and then it fell back to h264, but other times it worked."
Two separate defects, one of which explains the report and one of which would have sent the triage the wrong way.
1. The 4:4:4 advertisement was a promise nothing checked
VIDEO_CAP_444rode the "Full chroma" setting alone, with a comment saying the software rung was the floor underneath it. M8 removed that floor — there is no permissively licensed software HEVC decoder, sosoftware_decodable_codecs()isH264 | AV1. The host grants 4:4:4 on HEVC only, and answers the resolved chroma in the Welcome before the client builds a decoder.So on a device with no 4:4:4 decode, the toggle did not cost crispness — it cost the entire codec:
AMD has no HEVC 4:4:4 decode on any silicon (verified two independent ways — see the vendor matrix work), the Deck included. H.264 never shows this symptom because it has a CPU rung underneath it.
Why it looked intermittent:
enable_444is per-profile and defaults off — "a 'Work' profile wants it; 'Game' usually doesn't". Same Deck, same host, same session: the Work profile loses HEVC where Game keeps it. A second source of variance is the host's own 4:4:4 encode probe, which only NVIDIA passes.The fix
Gated on
hevc_444_hardware_decodable, which asks the driver through the same code the rung uses at construction (VkH265Decoder::probe_stream_support) — so the advertisement and the rung that has to honour it cannot disagree. It costs a handful of capability queries, no session, no images, no submits, and&&short-circuits so a box that never enabled Full chroma pays nothing.Both depths are required, not either. With HDR on the host may resolve 4:4:4 10-bit, and a device offering
YUV444_8but notYUV444_10would land in exactly the hole this closes.Answering from the Vulkan rung alone is exact, not approximate — it is the only rung in this build that implements 4:4:4 at all:
pf_vaadec::profile_formaps onlychroma_format_idc == 1and errorsUnsupportedShapeon 3;pf_dxvadec's config refuses "anything but 4:2:0" by construction; the CPU rung is 8-bit 4:2:0. That is also why an Intel box — whose hardware has done HEVC 4:4:4 since Ice Lake — is stillfalsehere: our DXVA/VAAPI rungs do not implement it, so advertising it would be a lie about us, not about the GPU.The user is not left guessing: a
warnnames the setting, the reason, and PyroWave as the 4:4:4 path that works on any GPU.One deliberate non-change:
VIDEO_CAP_10BIT/VIDEO_CAP_HDRThese are advertised unprobed for the same reason 4:4:4 was, and I left them alone on purpose. The asymmetry is real: all three hardware rungs implement 10-bit 4:2:0 (
profile_formaps(H265, 1, 10)and(Av1, 1, 10); pf-dxvadec carries P010), so a Vulkan-only probe there would answerfalseon boxes whose VAAPI/DXVA rung decodes 10-bit perfectly and would silently withdraw HDR from them — a visible regression bought against a case never observed. Gating 10-bit honestly needs a libva/D3D11 probe this path cannot afford, for the same reasonav1_hardware_decodabledoes not consult VAAPI. Measured on a Deck: HEVC Main and Main 10 both offer the full format set, so 10-bit was never this bug.2.
--probe-decodedescribed a different device from the one that streamsThe RADV video-decode opt-in sat after the
--list-adapters/--probe-decode/--list-audio/--pairearly exits, so the triage tool never had it. Measured on a Deck (canarye22af40f), same binary, back to back:--probe-decodevulkan video decode: no·driver decode ops: none (0x0)·no queue family advertises VIDEO_DECODERADV_PERFTEST=video_decode … --probe-decodevulkan video decode: YES·H.264, H.265, AV1, VP9 (0xF)The tool exists to be believed. Any Deck triage that consulted it reached the opposite of the truth — including, briefly, this one. Hoisted to the top of
run, ahead of every early exit; nothing touches Vulkan before it (maincallsrundirectly).Shape of the change
The bit arithmetic moves into
video::video_caps_for— a pure function — so the part that was actually wrong is testable without a GPU, a host or a Hello, in the spirit oflast_rung_verdict. The device question stays with the caller, which owns the expensive probe and logs its own refusal with the user's setting in hand.Verification
Run in the
pf-lxcheck2Linux container (pf-client-coredoes not build on macOS at all):cargo fmt --all -- --check— cleancargo build(plain, not only--all-targets— that hides "dead outside tests") — cleancargo clippy --all-targets -- -D warnings— cleancargo test -p pf-client-core— 185 passed, 0 failedThe new test is verified non-vacuous: planting the original defect (
if want_444→if true) fails it with exactly the intended assertion —a 4:4:4 promise this device cannot keep costs HEVC entirely,left: 4, right: 0.Re-run green after rebasing onto
e22082ac; no overlap with anything that landed meanwhile.What is NOT verified
std::env::set_var→setenv(3)and verified ordering, so it is determined rather than guessed — but the on-glass confirmation is owed. It needs new packages in a dev container, so it was left rather than done half-way.Some(vk)arm needs a GPU and has no test; only theNonearm and the bit arithmetic are covered here.