feat(linux/vulkan-encode): default-on native NV12 capture + RGB true-extent
ci / web (push) Successful in 48s
ci / docs-site (push) Successful in 1m5s
apple / swift (push) Successful in 1m20s
decky / build-publish (push) Successful in 21s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 25s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 42s
ci / bench (push) Successful in 5m59s
apple / screenshots (push) Successful in 6m17s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 6m29s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 5m12s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m16s
deb / build-publish (push) Successful in 12m58s
deb / build-publish-host (push) Successful in 13m40s
windows-host / package (push) Successful in 10m46s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 6m52s
android / android (push) Successful in 16m18s
arch / build-publish (push) Successful in 16m20s
docker / deploy-docs (push) Successful in 30s
ci / rust (push) Successful in 19m25s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 14m19s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 15m19s
ci / web (push) Successful in 48s
ci / docs-site (push) Successful in 1m5s
apple / swift (push) Successful in 1m20s
decky / build-publish (push) Successful in 21s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 25s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 42s
ci / bench (push) Successful in 5m59s
apple / screenshots (push) Successful in 6m17s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 6m29s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 5m12s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m16s
deb / build-publish (push) Successful in 12m58s
deb / build-publish-host (push) Successful in 13m40s
windows-host / package (push) Successful in 10m46s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 6m52s
android / android (push) Successful in 16m18s
arch / build-publish (push) Successful in 16m20s
docker / deploy-docs (push) Successful in 30s
ci / rust (push) Successful in 19m25s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 14m19s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 15m19s
Flip both zero-copy levers from opt-in to default: - The capture negotiation now PREFERS gamescope's producer-side NV12 pod by default (PUNKTFUNK_PIPEWIRE_NV12=0 restores the packed-RGB negotiation). Codec-aware gating rides a new OutputFormat::nv12_native -> ZeroCopyPolicy::native_nv12_session edge resolved by the host facade from the session plan (pf_encode::linux_native_nv12_ok): only H265/AV1 sessions whose backend can open the raw Vulkan Video encoder ever see the NV12 pod -- an H264/Moonlight session (libav VAAPI, which would misread the two-plane buffer) keeps today's BGRx negotiation, as do the GameStream-resolve and portal-mirror paths, PyroWave, and NVENC prefs. - RGB-direct's unaligned modes default to the true-extent direct import (PUNKTFUNK_VULKAN_RGB_TRUE_EXTENT=0 restores the padded-copy staging). Guarded-tested on Van Gogh with the kernel journal watched: clean, and at 5.38 ms p50 the fastest 1080p encode path measured on that hardware. The EFC only exists on Mesa >= 26, where the codedExtent-driven session_init padding is guaranteed (verified back to Mesa 24.2). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,7 +26,10 @@ pub use pf_capture::{dxgi, synthetic_nv12};
|
||||
/// capture→encode cycle). Resolved here (the host facade) and threaded in, so the edge stays one-way
|
||||
/// (plan §2.4 / §W6).
|
||||
#[cfg(target_os = "linux")]
|
||||
fn zero_copy_policy(pyrowave_session: bool) -> pf_capture::ZeroCopyPolicy {
|
||||
fn zero_copy_policy(
|
||||
pyrowave_session: bool,
|
||||
native_nv12_session: bool,
|
||||
) -> pf_capture::ZeroCopyPolicy {
|
||||
let backend_is_vaapi = crate::encode::linux_zero_copy_is_vaapi();
|
||||
// The raw-dmabuf passthrough serves a PyroWave session on ANY vendor (the wavelet encoder's
|
||||
// own Vulkan device imports the dmabuf) — per-session from the negotiated codec, plus the
|
||||
@@ -56,6 +59,7 @@ fn zero_copy_policy(pyrowave_session: bool) -> pf_capture::ZeroCopyPolicy {
|
||||
backend_is_gpu: crate::encode::resolved_backend_is_gpu(),
|
||||
pyrowave_session,
|
||||
pyrowave_modifiers,
|
||||
native_nv12_session,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +74,9 @@ pub fn open_portal_monitor(want_hdr: bool) -> Result<Box<dyn Capturer>> {
|
||||
let anchored = crate::inject::default_backend() == crate::inject::Backend::Libei;
|
||||
// Monitor mirrors never carry the native PyroWave plane (GameStream protocol) — per-session
|
||||
// passthrough is virtual-output-only; the global encoder-pref lever still applies inside.
|
||||
pf_capture::open_portal_monitor(anchored, want_hdr, zero_copy_policy(false))
|
||||
// Native NV12 stays off too: the mirror path doesn't resolve the codec here, and the desktop
|
||||
// compositors it mirrors (GNOME/KWin) don't produce NV12 anyway.
|
||||
pf_capture::open_portal_monitor(anchored, want_hdr, zero_copy_policy(false, false))
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
@@ -101,7 +107,7 @@ pub fn capture_virtual_output(
|
||||
vout.keepalive,
|
||||
want.gpu,
|
||||
want.chroma_444,
|
||||
zero_copy_policy(want.pyrowave),
|
||||
zero_copy_policy(want.pyrowave, want.nv12_native),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -179,6 +179,13 @@ impl SessionPlan {
|
||||
// Vulkan device; on Linux the capture facade flips the zero-copy policy to the
|
||||
// raw-dmabuf passthrough (see above).
|
||||
pyrowave: self.codec == crate::encode::Codec::PyroWave,
|
||||
// Producer-native NV12 (gamescope) is consumable only by the Linux Vulkan Video
|
||||
// backend — resolved HERE from the plan's codec so the capturer never reaches back
|
||||
// into encode (the same one-way edge as `gpu` above).
|
||||
#[cfg(target_os = "linux")]
|
||||
nv12_native: crate::encode::linux_native_nv12_ok(self.codec),
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
nv12_native: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user