Merge pull request #699 from didpublishing/fix/596-gpu-information
#596: GPU Information names the adapter, or why the GPU compositor is off
This commit is contained in:
commit
162a2e2e01
|
|
@ -190,6 +190,25 @@ pub fn cpu_cores() -> usize {
|
|||
std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1)
|
||||
}
|
||||
|
||||
/// The graphics lines of Settings ▸ GPU Information and Help ▸ System Report: whether the GPU
|
||||
/// compositor runs (and on which adapter), else why compositing is on the CPU, and the adapter
|
||||
/// the window itself got. Without this a card the compositor couldn't use looked undetected (#596).
|
||||
pub fn gpu_summary(s: &crate::Session) -> String {
|
||||
let mut text = match s.accel.as_ref().map(|a| a.name()) {
|
||||
Some(name) => format!("Compositing: GPU, {name}.\n"),
|
||||
None => {
|
||||
let threads = std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1);
|
||||
let why = s.accel_note.as_deref().unwrap_or("no reason was recorded");
|
||||
format!("Compositing: CPU, {threads} threads (pure Rust, rayon).\nGPU compositing is off: {why}\n")
|
||||
}
|
||||
};
|
||||
match &s.window_adapter {
|
||||
Some(adapter) => text.push_str(&format!("Window graphics: {adapter}\n")),
|
||||
None => text.push_str("Window graphics: not known yet (the window has not drawn its first frame).\n"),
|
||||
}
|
||||
text
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -650,3 +650,44 @@ fn render_backend_says_why_it_renders_on_the_cpu() {
|
|||
assert_eq!(why(&mut s), json!("headless: renders on the CPU unless started with --gpu"));
|
||||
assert_eq!(s.execute("render.backend", json!({"backend": "cpu"})).unwrap()["why"], json!("the project's renderer is Mercury Software Only"));
|
||||
}
|
||||
|
||||
/// Settings ▸ GPU Information names what the GPU compositor runs on, or why it is off, and the
|
||||
/// adapter the window got, so a card the compositor couldn't use doesn't look undetected (#596).
|
||||
#[test]
|
||||
fn gpu_summary_names_the_adapter_or_says_why_there_is_none() {
|
||||
use crate::sysinfo::gpu_summary;
|
||||
use effectcraft_render::{Accelerator, FxStep, Renderer};
|
||||
|
||||
struct Named;
|
||||
impl Accelerator for Named {
|
||||
fn name(&self) -> String {
|
||||
"NVIDIA GeForce RTX 4070 (Vulkan)".into()
|
||||
}
|
||||
fn comp_frame(&self, _: &Renderer, _: crate::project::ItemId, _: effectcraft_time::Tick) -> Option<effectcraft_raster::Image> {
|
||||
None
|
||||
}
|
||||
fn supports_effect(&self, _: &str) -> bool {
|
||||
false
|
||||
}
|
||||
fn effects(&self, _: &[FxStep], _: &effectcraft_effects::Buf, _: Option<f32>) -> Option<effectcraft_effects::Buf> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let mut s = Session::default();
|
||||
let off = gpu_summary(&s);
|
||||
assert!(off.contains("Compositing: CPU"), "{off}");
|
||||
assert!(off.contains("GPU compositing is off: no reason was recorded"), "{off}");
|
||||
assert!(off.contains("Window graphics: not known yet"), "{off}");
|
||||
|
||||
s.accel_note = Some("GPU compositor unavailable: no compute shaders".into());
|
||||
s.window_adapter = Some("NVIDIA GeForce RTX 4070 (Dx12, DiscreteGpu)".into());
|
||||
let declined = gpu_summary(&s);
|
||||
assert!(declined.contains("GPU compositing is off: GPU compositor unavailable: no compute shaders"), "{declined}");
|
||||
assert!(declined.contains("Window graphics: NVIDIA GeForce RTX 4070 (Dx12, DiscreteGpu)"), "the card the window got is listed: {declined}");
|
||||
|
||||
s.accel = Some(std::sync::Arc::new(Named));
|
||||
let on = gpu_summary(&s);
|
||||
assert!(on.starts_with("Compositing: GPU, NVIDIA GeForce RTX 4070 (Vulkan)."), "{on}");
|
||||
assert!(!on.contains("compositing is off"), "{on}");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -775,12 +775,12 @@ pub fn frontend(app: &mut EffectcraftApp, ctx: &egui::Context, id: &str, p: Valu
|
|||
Value::Null
|
||||
}
|
||||
"app.gpuInfo" => {
|
||||
let threads = std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1);
|
||||
crate::panels::dialogs::info(
|
||||
app,
|
||||
"GPU Information",
|
||||
&format!(
|
||||
"Compositing: CPU, {threads} threads (pure Rust, rayon).\nDisplay: egui on wgpu.\nLayer cache: {} MB • Preview cache: {} MB.",
|
||||
"{}Layer cache: {} MB • Preview cache: {} MB.",
|
||||
effectcraft_engine::sysinfo::gpu_summary(&app.session),
|
||||
app.session.layer_cache.budget() >> 20,
|
||||
app.frames.budget() >> 20
|
||||
),
|
||||
|
|
|
|||
|
|
@ -111,3 +111,22 @@ fn gpu_information_ok_returns_to_settings_and_cancel_restores_preferences() {
|
|||
fn gpu_information_escape_returns_to_settings_and_ok_saves_preferences() {
|
||||
check_info_transaction(true);
|
||||
}
|
||||
|
||||
/// GPU Information names the adapter the window got and says why the compositor is off, so a
|
||||
/// card that the compositor could not use does not look undetected (#596).
|
||||
#[test]
|
||||
fn gpu_information_names_the_adapter_and_why_the_gpu_is_off() {
|
||||
let session = Session {
|
||||
accel_note: Some("GPU compositor unavailable: no compute shaders".into()),
|
||||
window_adapter: Some("NVIDIA GeForce RTX 4070 (Dx12, DiscreteGpu)".into()),
|
||||
..Default::default()
|
||||
};
|
||||
let mut h = Harness::builder().with_size(vec2(1600.0, 1000.0)).build_eframe(|_| EffectcraftApp::new(session));
|
||||
h.run_steps(4);
|
||||
let ctx = h.ctx.clone();
|
||||
menus::invoke(h.state_mut(), &ctx, "app.gpuInfo", json!({})).unwrap();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().dialog, Some(Dialog::Info));
|
||||
assert!(h.query_by_label_contains("Window graphics: NVIDIA GeForce RTX 4070").is_some(), "the window's adapter is shown");
|
||||
assert!(h.query_by_label_contains("GPU compositing is off: GPU compositor unavailable").is_some(), "the reason is shown");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue