feat(presenter): VAAPI dmabuf → Vulkan zero-copy import + CSC pass (phase 2)

The decoder's NV12 dmabuf imports per-plane (R8 + GR88, explicit DRM
format modifier, dedicated dup'd-fd import, FOREIGN→graphics acquire)
and a fullscreen-triangle render pass converts it into the presenter's
video image with the CICP-driven coefficients ported from video_gl.rs
(same tests, plus a rows-vs-matrix agreement check). SPIR-V is committed
(shaders/build.sh regenerates) so builds and CI need no toolchain. The
import extension set is probed at device creation; unsupported boxes and
3-failure streaks demote the decoder to software via the existing
force_software contract. The session binary now honors the Settings
decoder preference instead of forcing software.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 18:12:16 +02:00
parent 89d45f2a55
commit a02d0a2e9f
12 changed files with 1091 additions and 56 deletions
+5 -3
View File
@@ -23,6 +23,8 @@ In-stream keys match the desktop client: click captures input (Ctrl+Alt+Shift+Q
releases), Ctrl+Alt+Shift+D disconnects, F11 toggles fullscreen; the controller escape
chord (L1+R1+Start+Select, hold to disconnect) works the same.
Current phase (1): software decode presented via a transfer-only blit — request path
`--connect` only. The VAAPI dmabuf → Vulkan zero-copy import, HDR/P010, and the Skia
console UI (`--browse`) are later phases of the plan.
Decode follows the Settings preference: VAAPI frames import zero-copy into Vulkan
(per-plane dmabuf + the stream's CICP-driven CSC shader); boxes whose driver can't
import (NVIDIA proprietary by design) fall back to software decode automatically —
`PUNKTFUNK_DECODER=software|vaapi` overrides for bisects. HDR/P010 and the Skia console
UI (`--browse`) are later phases of the plan.
+3 -3
View File
@@ -180,10 +180,10 @@ mod session_main {
audio_channels: settings.audio_channels,
preferred_codec: settings.preferred_codec(),
mic_enabled: settings.mic_enabled,
// Phase 1 presents the software path only (the Vulkan dmabuf import is
// Phase 2) — request it outright instead of demoting after one frame.
// The Settings preference (auto → VAAPI where it exists; the presenter
// demotes to software on boxes whose Vulkan can't import the dmabufs).
// PUNKTFUNK_DECODER still overrides inside the decoder for bisects.
decoder: "software".into(),
decoder: settings.decoder.clone(),
launch,
pin: Some(pin),
identity,