refactor(host/W6.2): extract the video encode backends into the pf-encode crate
encode.rs + encode/* (NVENC, VAAPI, native AMF, AMF/QSV ffmpeg, direct-SDK NVENC/CUDA, raw Vulkan-Video, PyroWave, openh264) move into crates/pf-encode behind one Encoder trait + open_video selector (plan §W6). The crate speaks the shared frame vocabulary (pf-frame: CapturedFrame/PixelFormat + the DXGI identity D3d11Frame/make_device) and pf-zerocopy (CUDA context/buffers), and NEVER pf-capture — the capture→encode edge is one-way (ZeroCopyPolicy, prior commit). Dep moves: the heavy encoder deps (ffmpeg-next, the NVENC SDK, openh264, pyrowave-sys) move from the host to pf-encode; the host's nvenc/amf-qsv/vulkan-encode/pyrowave features now FORWARD to pf-encode/*. The host keeps a mod-encode shim (pub use pf_encode) so every crate::encode::* path (negotiator + GameStream/native/mgmt planes) is unchanged. resolve_render_adapter_luid moves from the host's windows/win_adapter.rs into pf-gpu (both pf-encode and pf-capture need it as a peer of GPU selection); its 5 call sites (encode amf/nvenc, capture idd_push/synthetic_nv12, vdisplay manager) rewire to pf_gpu::resolve_render_adapter_luid and win_adapter.rs is deleted. pf-frame's make_device gains a # Safety section (public-unsafe-fn lint, latent since the pf-frame carve — a full-workspace -D warnings clippy catches it). Verified: Linux clippy -D warnings (pf-encode + host nvenc,vulkan-encode,pyrowave --all-targets) + 13/13 pf-encode + 299/299 host tests; Windows clippy -D warnings (pf-encode nvenc,amf-qsv --all-targets + host nvenc,amf-qsv --all-targets) Finished exit 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -914,3 +914,39 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pick the render GPU LUID the Windows pipeline is created on: the IDD-push capturer's
|
||||
/// shared-texture ring, the IddCx `SET_RENDER_ADAPTER` pin, and (via the captured frame's device)
|
||||
/// NVENC/AMF/QSV all follow this one decision — see [`selected_gpu`] for the precedence (operator
|
||||
/// preference > `PUNKTFUNK_RENDER_ADAPTER` substring > max `DedicatedVideoMemory`). A configured
|
||||
/// preference that doesn't match a present GPU falls back to auto selection (with a warning) rather
|
||||
/// than returning `None`, so a stale preference never stops the host from streaming.
|
||||
///
|
||||
/// Lives here (not in a host module) so BOTH the capture and encode subsystem crates depend on it
|
||||
/// as a peer of GPU selection instead of the orchestrator — the plan's `windows/adapter.rs`, folded
|
||||
/// into `pf-gpu` (plan §W6). It was historically the SudoVDA backend's, then the host's
|
||||
/// `win_adapter.rs`; the LUID-shaped view of [`selected_gpu`] plus the per-decision logging.
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn resolve_render_adapter_luid() -> Option<windows::Win32::Foundation::LUID> {
|
||||
match selected_gpu() {
|
||||
Some(sel) => {
|
||||
tracing::info!(
|
||||
adapter = sel.info.name,
|
||||
vram_mb = sel.info.vram_bytes / (1024 * 1024),
|
||||
source = sel.source.tag(),
|
||||
"render adapter selected"
|
||||
);
|
||||
if sel.source == PickSource::PreferenceMissing {
|
||||
tracing::warn!(
|
||||
"the preferred GPU is not present — auto-selected the adapter above \
|
||||
(fix or clear the preference in the web console)"
|
||||
);
|
||||
}
|
||||
Some(sel.info.luid())
|
||||
}
|
||||
None => {
|
||||
tracing::warn!("no suitable render adapter found for SET_RENDER_ADAPTER");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user