84a3b95f17
Goal 2 ("drop every trace of SudoVDA") is done. The SudoVDA driver is no longer
shipped (only pf-vdisplay; the old vdisplay-driver tree was deleted in a2bd0cd),
and F1 (d638a93/e60cda3) already moved the display-utility helpers out of the
backend into neutral modules (win_adapter/win_display), breaking the reach-in.
So the backend is now cleanly removable:
- Deleted crates/punktfunk-host/src/vdisplay/windows/sudovda.rs (350 lines: the
SudoVdaDisplay VirtualDisplay impl + its VdisplayDriver/probe).
- vdisplay::open()/probe() are now unconditional pf-vdisplay; deleted the
windows_use_pf_vdisplay() backend selector. open() now ensure!s
pf_vdisplay::is_available() with a clear "driver not installed" error instead
of the old silent SudoVDA fallback (no fallback driver exists anymore).
- Scrubbed the dangling references to the deleted symbols (manager/sendinput/dxgi
comments, the config + host.env PUNKTFUNK_VDISPLAY docs); the var stays as an
informational forward-seam. Updated the F1 module docs (Goal 2 now done).
All changes are #[cfg(windows)] except the config doc; Linux clippy
-p punktfunk-host -D warnings clean; zero `sudovda::`/`SudoVdaDisplay` code refs
remain (comments only). Windows build is CI-gated.
Scorecard Goal 2 -> DONE; recorded the E1 "do NOT do it" stability decision in
windows-host-rewrite.md §4 (the process-global driver design is sound given
ProcessSharingDisabled; a device-owned variant adds a use-after-free window for
no gain).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
67 lines
2.9 KiB
Rust
67 lines
2.9 KiB
Rust
//! Backend-neutral DXGI adapter selection.
|
|
//!
|
|
//! The discrete render-GPU LUID picker used to live in the SudoVDA backend (`vdisplay::sudovda`) — a
|
|
//! historical accident, since it is display-utility, not SudoVDA-specific. It lives here so the capturers
|
|
//! (IDD-push) and the pf-vdisplay backend depend on it as a *peer* instead of reaching into the SudoVDA
|
|
//! module — breaking that circular reach-in, which let the SudoVDA backend be dropped without losing this
|
|
//! helper (audit §9 / Goal 2 — done). This is the plan's `windows/adapter.rs`.
|
|
|
|
use windows::Win32::Foundation::LUID;
|
|
|
|
/// Pick the discrete render GPU LUID: the adapter with the most `DedicatedVideoMemory`, skipping
|
|
/// WARP / Basic-Render and the SudoVDA software adapter (≈0 VRAM). `PUNKTFUNK_RENDER_ADAPTER=<substring>`
|
|
/// forces a match by Description (Apollo's `adapter_name`). Used by the IDD direct-push capturer (to
|
|
/// create its shared textures on the same discrete GPU it pins, where NVENC runs) and SET_RENDER_ADAPTER.
|
|
///
|
|
/// # Safety
|
|
/// Creates + enumerates a DXGI factory; the COM calls run in the caller's apartment (the existing callers
|
|
/// already satisfy this).
|
|
pub(crate) unsafe fn resolve_render_adapter_luid() -> Option<LUID> {
|
|
use windows::Win32::Graphics::Dxgi::{CreateDXGIFactory1, IDXGIFactory1};
|
|
let want = crate::config::config()
|
|
.render_adapter
|
|
.clone()
|
|
.filter(|s| !s.is_empty());
|
|
let factory: IDXGIFactory1 = CreateDXGIFactory1().ok()?;
|
|
let mut best: Option<(LUID, u64, String)> = None;
|
|
let mut i = 0u32;
|
|
while let Ok(a) = factory.EnumAdapters1(i) {
|
|
i += 1;
|
|
let Ok(d) = a.GetDesc1() else { continue };
|
|
let name = String::from_utf16_lossy(&d.Description);
|
|
let name = name.trim_end_matches('\u{0}').to_string();
|
|
let lname = name.to_ascii_lowercase();
|
|
if lname.contains("basic render") || lname.contains("warp") {
|
|
continue; // never pin to the software rasterizer
|
|
}
|
|
if let Some(w) = &want {
|
|
if lname.contains(&w.to_ascii_lowercase()) {
|
|
tracing::info!(
|
|
adapter = name,
|
|
"render adapter chosen by PUNKTFUNK_RENDER_ADAPTER"
|
|
);
|
|
return Some(d.AdapterLuid);
|
|
}
|
|
continue;
|
|
}
|
|
let vram = d.DedicatedVideoMemory as u64; // SudoVDA software adapter ≈ 0 → loses to the dGPU
|
|
if best.as_ref().is_none_or(|(_, v, _)| vram > *v) {
|
|
best = Some((d.AdapterLuid, vram, name));
|
|
}
|
|
}
|
|
match best {
|
|
Some((luid, vram, name)) => {
|
|
tracing::info!(
|
|
adapter = name,
|
|
vram_mb = vram / (1024 * 1024),
|
|
"render adapter chosen (max VRAM)"
|
|
);
|
|
Some(luid)
|
|
}
|
|
None => {
|
|
tracing::warn!("no suitable render adapter found for SET_RENDER_ADAPTER");
|
|
None
|
|
}
|
|
}
|
|
}
|