feat(mgmt/web): surface the host.env encoder pin so a conflicting GPU choice isn't invisible
listGpus gains encoder_pin (PUNKTFUNK_ENCODER when it actually pins something — unset/auto stay null), and the console's GPU card shows it: a muted note when the pin is compatible, an amber warning naming the pinned vendor and the next session's GPU when it contradicts the selection (the host overrides such a pin at session open — without this field the selection just looked broken). Docs updated to say the adapter wins. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -66,6 +66,11 @@ pub(crate) struct GpuState {
|
||||
/// `PUNKTFUNK_RENDER_ADAPTER` (the host.env pin), when set — it applies while `mode` is
|
||||
/// `auto`; a manual preference overrides it.
|
||||
env_override: Option<String>,
|
||||
/// `PUNKTFUNK_ENCODER` (the host.env encoder pin), when set to something other than `auto`
|
||||
/// (e.g. `qsv`, `nvenc`, `amf`, `software`). A pin whose vendor contradicts the selected
|
||||
/// GPU is overridden at session open — the adapter wins — so the console can warn that the
|
||||
/// pin is stale rather than letting the selection look broken.
|
||||
encoder_pin: Option<String>,
|
||||
/// The GPU the next session will use.
|
||||
selected: Option<ApiSelectedGpu>,
|
||||
/// The GPU live sessions use right now (absent while nothing is streaming).
|
||||
@@ -143,11 +148,36 @@ pub(crate) fn gpu_state() -> GpuState {
|
||||
.render_adapter
|
||||
.clone()
|
||||
.filter(|s| !s.is_empty()),
|
||||
encoder_pin: encoder_pin_of(&pf_host_config::config().encoder_pref),
|
||||
selected,
|
||||
active,
|
||||
}
|
||||
}
|
||||
|
||||
/// The `PUNKTFUNK_ENCODER` value worth surfacing to the console: `None` for unset/empty and for
|
||||
/// an explicit `auto` (both mean "derive from the selected adapter" — nothing is pinned).
|
||||
fn encoder_pin_of(pref: &str) -> Option<String> {
|
||||
match pref {
|
||||
"" | "auto" => None,
|
||||
pin => Some(pin.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// Only a real pin surfaces to the console — the `auto` spellings pin nothing, and showing
|
||||
/// them would put a permanent scary note under every default install's GPU card.
|
||||
#[test]
|
||||
fn encoder_pin_surfaces_only_real_pins() {
|
||||
assert_eq!(encoder_pin_of(""), None);
|
||||
assert_eq!(encoder_pin_of("auto"), None);
|
||||
assert_eq!(encoder_pin_of("qsv"), Some("qsv".into()));
|
||||
assert_eq!(encoder_pin_of("software"), Some("software".into()));
|
||||
}
|
||||
}
|
||||
|
||||
/// GPU inventory and selection
|
||||
///
|
||||
/// Lists the host's hardware GPUs, the persisted auto/manual preference, the GPU the next session
|
||||
|
||||
@@ -1234,6 +1234,13 @@ async fn gpu_endpoints_list_and_validate() {
|
||||
assert_eq!(s, StatusCode::OK);
|
||||
assert!(b["gpus"].is_array());
|
||||
assert!(b["mode"].is_string());
|
||||
// The host.env encoder pin is part of the schema (null when nothing is pinned) — the
|
||||
// console warns off it when a pin contradicts the selected GPU (the pin is overridden at
|
||||
// session open, and without this field the selection would just look broken).
|
||||
assert!(
|
||||
b.as_object().unwrap().contains_key("encoder_pin"),
|
||||
"listGpus must carry encoder_pin"
|
||||
);
|
||||
|
||||
// Unknown mode → 400.
|
||||
let (s, _) = send(
|
||||
|
||||
Reference in New Issue
Block a user