perf(latency): T2.5b — NV12 compute CSC on the LINEAR/gamescope zero-copy path
apple / swift (push) Successful in 1m21s
apple / screenshots (push) Successful in 6m23s
ci / web (push) Successful in 54s
arch / build-publish (push) Successful in 10m52s
ci / docs-site (push) Successful in 1m7s
decky / build-publish (push) Successful in 35s
android / android (push) Successful in 13m2s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 16s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 16s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 11s
ci / bench (push) Successful in 6m8s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 7m56s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 9m44s
docker / deploy-docs (push) Successful in 24s
deb / build-publish (push) Successful in 11m52s
ci / rust (push) Successful in 27m4s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 20m26s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 20m20s
apple / swift (push) Successful in 1m21s
apple / screenshots (push) Successful in 6m23s
ci / web (push) Successful in 54s
arch / build-publish (push) Successful in 10m52s
ci / docs-site (push) Successful in 1m7s
decky / build-publish (push) Successful in 35s
android / android (push) Successful in 13m2s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 16s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 16s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 11s
ci / bench (push) Successful in 6m8s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 7m56s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 9m44s
docker / deploy-docs (push) Successful in 24s
deb / build-publish (push) Successful in 11m52s
ci / rust (push) Successful in 27m4s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 20m26s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 20m20s
design/latency-reduction-2026-07.md T2.5's Linux half: the LINEAR dmabuf path (gamescope's only offer) fed NVENC RGB, paying its internal RGB->YUV CSC on the SM the game is saturating — the exact contention §5.A removed everywhere else. The Vulkan bridge now carries a buffer-to-buffer RGB->NV12 compute shader (rgb2nv12_buf.comp, BT.709 limited, coefficient-identical to pf-encode's rgb2yuv.comp; whole-word writes so no 8-bit-storage feature is needed): import dmabuf -> dispatch CSC into the exportable buffer -> CUDA de-strides both planes into a pooled two-plane NV12 buffer. PUNKTFUNK_NV12 (default-on) now covers LINEAR; a CSC failure latches RGB for the stream (mid-frame fallback, no dropped frame); 4:4:4 LINEAR sessions stay RGB (never silently subsample). New ImportKind::LinearNv12 rides the existing worker IPC (appended last per the wire-tag rule); cursor stays downstream (blend_nv12). Validated: .21 clippy -D warnings (pf-zerocopy/pf-capture/host+nvenc) + 17 zero-copy tests. Owed: on-glass gamescope session (visual + dmon sm% check). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -748,6 +748,9 @@ mod pipewire {
|
||||
/// (`ImportKind::Tiled444`) and feed NVENC native full-chroma YUV — takes precedence over
|
||||
/// `nv12` (a 4:4:4 session must never subsample).
|
||||
yuv444: bool,
|
||||
/// The LINEAR (gamescope) NV12 compute CSC failed once — RGB for the rest of the stream
|
||||
/// (T2.5b's per-stream fallback latch; cleared by the next stream's fresh `Ud`).
|
||||
linear_nv12_failed: bool,
|
||||
/// Rate-limit counter for the latest-frame-only diagnostic log (see `.process`).
|
||||
dbg_log_n: u64,
|
||||
/// Cursor-as-metadata state, composited into the CPU de-pad path (see `consume_frame`).
|
||||
@@ -1352,15 +1355,17 @@ mod pipewire {
|
||||
// sample LINEAR).
|
||||
let modifier = (ud.modifier != 0).then_some(ud.modifier);
|
||||
if let Some(fourcc) = pf_frame::drm_fourcc(fmt) {
|
||||
// GPU converts only on the tiled EGL/GL path (`modifier.is_some()`): a 4:4:4
|
||||
// session gets the planar-YUV444 convert (full chroma, takes precedence over
|
||||
// NV12 — 4:4:4 must never subsample), otherwise `PUNKTFUNK_NV12` gets NV12 —
|
||||
// both feed NVENC native YUV so it skips its internal RGB→YUV CSC. The
|
||||
// LINEAR/Vulkan (gamescope) path stays RGB — its converts aren't wired here;
|
||||
// a 4:4:4 session on LINEAR frames falls to the encoder's clear-error path
|
||||
// (`want_444` with an RGB CUDA payload) rather than silently subsampling.
|
||||
// GPU converts: a 4:4:4 session gets the planar-YUV444 convert on the tiled
|
||||
// EGL/GL path (full chroma, takes precedence over NV12 — 4:4:4 must never
|
||||
// subsample), otherwise `PUNKTFUNK_NV12` gets NV12 — tiled via the EGL/GL
|
||||
// blit, LINEAR/gamescope via the Vulkan bridge's compute CSC (latency plan
|
||||
// T2.5b) — so NVENC encodes native YUV and skips its internal RGB→YUV CSC on
|
||||
// the contended SM. A 4:4:4 session on LINEAR frames has no convert and
|
||||
// stays RGB, falling to the encoder's clear-error path (`want_444` with an
|
||||
// RGB CUDA payload) rather than silently subsampling. A LINEAR NV12 convert
|
||||
// failure latches RGB for the stream (mid-frame fallback, no drop).
|
||||
let yuv444 = ud.yuv444 && modifier.is_some();
|
||||
let nv12 = ud.nv12 && !yuv444 && modifier.is_some();
|
||||
let mut nv12 = ud.nv12 && !ud.yuv444;
|
||||
let imported = if let Some(m) = modifier {
|
||||
if yuv444 {
|
||||
importer.import_yuv444(&plane, w as u32, h as u32, fourcc, Some(m))
|
||||
@@ -1369,7 +1374,20 @@ mod pipewire {
|
||||
} else {
|
||||
importer.import(&plane, w as u32, h as u32, fourcc, Some(m))
|
||||
}
|
||||
} else if nv12 && !ud.linear_nv12_failed {
|
||||
match importer.import_linear_nv12(&plane, w as u32, h as u32) {
|
||||
Ok(buf) => Ok(buf),
|
||||
Err(e) => {
|
||||
ud.linear_nv12_failed = true;
|
||||
nv12 = false;
|
||||
tracing::warn!(error = %format!("{e:#}"),
|
||||
"LINEAR NV12 compute CSC failed — RGB for the rest of this \
|
||||
stream (NVENC does the CSC internally)");
|
||||
importer.import_linear(&plane, w as u32, h as u32)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nv12 = false;
|
||||
importer.import_linear(&plane, w as u32, h as u32)
|
||||
};
|
||||
match imported {
|
||||
@@ -1742,6 +1760,7 @@ mod pipewire {
|
||||
vaapi_passthrough,
|
||||
nv12: pf_zerocopy::nv12_enabled(),
|
||||
yuv444: want_444,
|
||||
linear_nv12_failed: false,
|
||||
dbg_log_n: 0,
|
||||
cursor: CursorState::default(),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user