fix(client): Linux auto decoder prefers Vulkan Video on ALL AMD, not just VanGogh
android / android (push) Has been cancelled
arch / build-publish (push) Has been cancelled
ci / web (push) Has been cancelled
ci / docs-site (push) Has been cancelled
ci / bench (push) Has been cancelled
ci / rust (push) Has been cancelled
decky / build-publish (push) Successful in 21s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 13s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 15s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 15s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 10s
apple / swift (push) Has been cancelled
apple / screenshots (push) Has been cancelled
deb / build-publish (push) Has been cancelled
docker / deploy-docs (push) Has been cancelled
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Has been cancelled
flatpak / build-publish (push) Has been cancelled
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Has been cancelled
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Has been cancelled
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Has been cancelled
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Has been cancelled
windows / build (aarch64-pc-windows-msvc) (push) Has been cancelled
windows / build (x86_64-pc-windows-msvc) (push) Has been cancelled

VAAPI-first on desktop RADV (46b7ffc0) was a regression: Vulkan Video decode
outperforms VAAPI on AMD (on-glass verdict). Vulkan-first is safe there since
the same commit's failure-streak demotion lands on VAAPI, not software — a
broken Mesa Vulkan path still ends up on the working driver.

Auto's order is now: Vulkan first on NVIDIA (no usable VAAPI) + all AMD
(perf; VanGogh additionally chroma-fringes over VAAPI); VAAPI first stays on
Intel/unknown (ANV's Vulkan Video is the least-proven Mesa path). Policy test
updated; 26 pf-client-core tests + clippy green on Linux.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 23:51:54 +02:00
parent 9d67dc18aa
commit 0bca67f73e
+19 -16
View File
@@ -1091,21 +1091,23 @@ pub struct VulkanDecodeDevice {
} }
impl VulkanDecodeDevice { impl VulkanDecodeDevice {
/// Should `auto` try Vulkan Video BEFORE VAAPI on this device? Only where that's the /// Should `auto` try Vulkan Video BEFORE VAAPI on this device?
/// established right answer:
/// * **NVIDIA** — Vulkan is its only hardware path (no usable VAAPI; the /// * **NVIDIA** — Vulkan is its only hardware path (no usable VAAPI; the
/// nvidia-vaapi-driver is broken for this, Moonlight blacklists it). /// nvidia-vaapi-driver is broken for this, Moonlight blacklists it).
/// * **VanGogh (Steam Deck)** — VAAPI's separate-plane dmabuf import shows chroma /// * **AMD (RADV, VanGogh included)** — Vulkan decode outperforms VAAPI on RADV
/// fringing there; the session binary opts RADV into `video_decode` precisely to /// (on-glass verdict), and on VanGogh VAAPI's separate-plane dmabuf import
/// get the Vulkan path. /// additionally shows chroma fringing; the session binary opts RADV into
/// `video_decode` precisely to get the Vulkan path. Vulkan-first is safe here
/// because a mid-session Vulkan failure streak demotes to VAAPI (not software),
/// so a broken Mesa Vulkan path still lands on the working driver.
/// ///
/// Every other Mesa device (desktop RADV, ANV) keeps the battle-tested zero-copy /// Intel (ANV) and unknown vendors keep the battle-tested zero-copy VAAPI first —
/// VAAPI first: Mesa now exposes decode queues by default, and FFmpeg-Vulkan-on-Mesa /// ANV's Vulkan Video is the least-proven Mesa path and VAAPI is what every other
/// regressing (judder, error-streaks that used to demote to software) is a real, /// Linux client uses there.
/// user-reported failure — while VAAPI is the path every other Linux client uses.
pub fn prefer_vulkan_over_vaapi(&self) -> bool { pub fn prefer_vulkan_over_vaapi(&self) -> bool {
const VENDOR_NVIDIA: u32 = 0x10DE; const VENDOR_NVIDIA: u32 = 0x10DE;
self.vendor_id == VENDOR_NVIDIA || self.device_name.to_ascii_uppercase().contains("VANGOGH") const VENDOR_AMD: u32 = 0x1002;
self.vendor_id == VENDOR_NVIDIA || self.vendor_id == VENDOR_AMD
} }
} }
@@ -1603,19 +1605,20 @@ mod tests {
} }
} }
/// Auto's Linux hardware order: Vulkan-first ONLY on NVIDIA (no usable VAAPI) and the /// Auto's Linux hardware order: Vulkan-first on NVIDIA (no usable VAAPI) and ALL AMD
/// Deck's VanGogh (VAAPI chroma-fringes); desktop RADV/ANV keep VAAPI first — the /// (Vulkan decode outperforms VAAPI on RADV — on-glass verdict; VanGogh additionally
/// user-reported judder/software regression came from FFmpeg-Vulkan-on-Mesa winning auto. /// chroma-fringes over VAAPI); Intel/unknown keep VAAPI first (ANV's Vulkan Video is
/// the least-proven Mesa path). A Vulkan failure streak still demotes to VAAPI, so
/// Vulkan-first can never strand a box on software decode.
#[test] #[test]
fn vulkan_over_vaapi_only_on_nvidia_and_vangogh() { fn vulkan_over_vaapi_on_nvidia_and_amd() {
assert!(decode_device(0x10DE, "NVIDIA GeForce RTX 5070 Ti").prefer_vulkan_over_vaapi()); assert!(decode_device(0x10DE, "NVIDIA GeForce RTX 5070 Ti").prefer_vulkan_over_vaapi());
assert!(decode_device(0x1002, "AMD RADV VANGOGH").prefer_vulkan_over_vaapi()); assert!(decode_device(0x1002, "AMD RADV VANGOGH").prefer_vulkan_over_vaapi());
assert!( assert!(
decode_device(0x1002, "AMD Custom GPU 0405 (RADV VANGOGH)").prefer_vulkan_over_vaapi() decode_device(0x1002, "AMD Custom GPU 0405 (RADV VANGOGH)").prefer_vulkan_over_vaapi()
); );
assert!( assert!(
!decode_device(0x1002, "AMD Radeon RX 7800 XT (RADV NAVI32)") decode_device(0x1002, "AMD Radeon RX 7800 XT (RADV NAVI32)").prefer_vulkan_over_vaapi()
.prefer_vulkan_over_vaapi()
); );
assert!( assert!(
!decode_device(0x8086, "Intel(R) Arc(tm) A770 Graphics (DG2)") !decode_device(0x8086, "Intel(R) Arc(tm) A770 Graphics (DG2)")