fix(pyrowave): per-session raw-dmabuf zero-copy capture on the Linux NVIDIA host
ci / web (push) Successful in 52s
apple / swift (push) Successful in 1m13s
ci / docs-site (push) Successful in 1m11s
ci / bench (push) Successful in 5m35s
apple / screenshots (push) Successful in 6m28s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 12s
decky / build-publish (push) Successful in 29s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 11s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 10s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 9s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 10s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 12s
android / android (push) Successful in 13m34s
deb / build-publish (push) Successful in 9m10s
deb / build-publish-host (push) Successful in 9m26s
arch / build-publish (push) Successful in 17m58s
windows-host / package (push) Successful in 16m40s
ci / rust (push) Successful in 29m45s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 20m12s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 20m8s
docker / deploy-docs (push) Successful in 28s
ci / web (push) Successful in 52s
apple / swift (push) Successful in 1m13s
ci / docs-site (push) Successful in 1m11s
ci / bench (push) Successful in 5m35s
apple / screenshots (push) Successful in 6m28s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 12s
decky / build-publish (push) Successful in 29s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 11s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 10s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 9s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 10s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 12s
android / android (push) Successful in 13m34s
deb / build-publish (push) Successful in 9m10s
deb / build-publish-host (push) Successful in 9m26s
arch / build-publish (push) Successful in 17m58s
windows-host / package (push) Successful in 16m40s
ci / rust (push) Successful in 29m45s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 20m12s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 20m8s
docker / deploy-docs (push) Successful in 28s
A PyroWave session on an NVIDIA-auto host was forced onto CPU-RGB capture
(session_plan flipped gpu=false): Mutter blits tiled->LINEAR, we mmap +
de-pad ~30 MB, the encoder re-uploads it - three full-frame CPU touches
per frame at 5120x1440 while an HEVC session on the same box rides the
tiled EGL/CUDA zero-copy. The dmabuf passthrough + Vulkan tiled import
were already validated (8dc5d672) but only reachable via the global
PUNKTFUNK_ENCODER=pyrowave lab policy.
ZeroCopyPolicy gains pyrowave_session (from OutputFormat.pyrowave, i.e.
the negotiated codec): the capturer skips the NVENC-only EGL->CUDA
importer, takes the raw-dmabuf passthrough, and advertises the wavelet
encoder's Vulkan-importable modifiers so Mutter+NVIDIA negotiates tiled
zero-copy. The forced-CPU flip in session_plan is gone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,24 +26,35 @@ 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() -> pf_capture::ZeroCopyPolicy {
|
||||
fn zero_copy_policy(pyrowave_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
|
||||
// global `PUNKTFUNK_ENCODER=pyrowave` lab lever (which also flips `backend_is_vaapi`).
|
||||
#[cfg(feature = "pyrowave")]
|
||||
let pyrowave_modifiers =
|
||||
if backend_is_vaapi && pf_host_config::config().encoder_pref.as_str() == "pyrowave" {
|
||||
// BGRx is the capture path's canonical packed-RGB format (the modifier advertisement keys
|
||||
// on it). `drm_fourcc(Bgrx)` is always `Some`.
|
||||
pf_frame::drm_fourcc(PixelFormat::Bgrx)
|
||||
.map(crate::encode::pyrowave_capture_modifiers)
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
let pyrowave_session =
|
||||
pyrowave_session || pf_host_config::config().encoder_pref.as_str() == "pyrowave";
|
||||
#[cfg(not(feature = "pyrowave"))]
|
||||
let pyrowave_session = {
|
||||
let _ = pyrowave_session;
|
||||
false
|
||||
};
|
||||
#[cfg(feature = "pyrowave")]
|
||||
let pyrowave_modifiers = if pyrowave_session {
|
||||
// BGRx is the capture path's canonical packed-RGB format (the modifier advertisement keys
|
||||
// on it). `drm_fourcc(Bgrx)` is always `Some`.
|
||||
pf_frame::drm_fourcc(PixelFormat::Bgrx)
|
||||
.map(crate::encode::pyrowave_capture_modifiers)
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
#[cfg(not(feature = "pyrowave"))]
|
||||
let pyrowave_modifiers = Vec::new();
|
||||
pf_capture::ZeroCopyPolicy {
|
||||
backend_is_vaapi,
|
||||
backend_is_gpu: crate::encode::resolved_backend_is_gpu(),
|
||||
pyrowave_session,
|
||||
pyrowave_modifiers,
|
||||
}
|
||||
}
|
||||
@@ -57,7 +68,9 @@ pub fn open_portal_monitor(want_hdr: bool) -> Result<Box<dyn Capturer>> {
|
||||
// session so it inherits that grant headlessly; wlroots/Sway has no RemoteDesktop portal,
|
||||
// so use a plain ScreenCast session there.
|
||||
let anchored = crate::inject::default_backend() == crate::inject::Backend::Libei;
|
||||
pf_capture::open_portal_monitor(anchored, want_hdr, zero_copy_policy())
|
||||
// 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))
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
@@ -88,7 +101,7 @@ pub fn capture_virtual_output(
|
||||
vout.keepalive,
|
||||
want.gpu,
|
||||
want.chroma_444,
|
||||
zero_copy_policy(),
|
||||
zero_copy_policy(want.pyrowave),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user