mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-24 10:09:01 -06:00
Merge PR #1644: fix(gpu): no popup when renderer falls back from DX12 at pro
This commit is contained in:
@@ -93,7 +93,6 @@ pub fn choose(files: &Files) -> Chosen {
|
||||
let compiled = wgpu::Instance::enabled_backend_features();
|
||||
let os = std::env::consts::OS;
|
||||
let order = backend::window_renderer_order(forced, remembered, failed, os, compiled, true);
|
||||
let mut notice = failed.map(|f| format!("The window could not start with its {} renderer last time.", f.name()));
|
||||
let mut problems = Vec::new();
|
||||
let chosen = if cfg!(windows) {
|
||||
pick_probed(&order, &mut problems)
|
||||
@@ -104,18 +103,7 @@ pub fn choose(files: &Files) -> Chosen {
|
||||
Some((WindowRenderer::Wgpu(backend::window_backends()), None))
|
||||
};
|
||||
let (which, existing) = chosen.unwrap_or((WindowRenderer::Glow, None));
|
||||
if !problems.is_empty() {
|
||||
notice = Some(format!("{} {}", notice.unwrap_or_default(), problems.join(" ")).trim().to_string());
|
||||
}
|
||||
let notice = notice.map(|n| {
|
||||
format!(
|
||||
"{n} {app} now draws its window with {}. To choose another, start {app} with {var}=dx12, vulkan, gl or glow \
|
||||
(see docs/gpu-pipeline.md → Troubleshooting).",
|
||||
which.name(),
|
||||
app = "LightCraft",
|
||||
var = "LIGHTCRAFT_GPU_BACKEND",
|
||||
)
|
||||
});
|
||||
let notice = user_notice(failed, forced, &problems, which);
|
||||
log::info!("window: renderer {} (order {:?})", which.name(), order.iter().map(|r| r.name()).collect::<Vec<_>>());
|
||||
let mut wgpu_options = base_options();
|
||||
let renderer = match (which, existing) {
|
||||
@@ -134,6 +122,25 @@ pub fn choose(files: &Files) -> Chosen {
|
||||
Chosen { renderer, wgpu_options, which, notice }
|
||||
}
|
||||
|
||||
/// What to tell the user about the window's renderer. A renderer that failed its probe is skipped
|
||||
/// silently (it is logged, and the one that worked is remembered): the app works, so a pop-up with
|
||||
/// wgpu's error only alarms (#1624). Shown: the last start died, or the forced renderer failed.
|
||||
fn user_notice(failed: Option<WindowRenderer>, forced: Option<WindowRenderer>, problems: &[String], which: WindowRenderer) -> Option<String> {
|
||||
let mut notice = failed.map(|f| format!("The window could not start with its {} renderer last time.", f.name()));
|
||||
if forced.is_some() && !problems.is_empty() {
|
||||
notice = Some(format!("{} {}", notice.unwrap_or_default(), problems.join(" ")).trim().to_string());
|
||||
}
|
||||
notice.map(|n| {
|
||||
format!(
|
||||
"{n} {app} now draws its window with {}. To choose another, start {app} with {var}=dx12, vulkan, gl or glow \
|
||||
(see docs/gpu-pipeline.md → Troubleshooting).",
|
||||
which.name(),
|
||||
app = "LightCraft",
|
||||
var = "LIGHTCRAFT_GPU_BACKEND",
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// eframe's defaults with the app's backends and DX12 shader compiler (issues #136, #471).
|
||||
pub fn base_options() -> WgpuConfiguration {
|
||||
let mut c = WgpuConfiguration::default();
|
||||
@@ -269,6 +276,20 @@ mod tests {
|
||||
let _ = std::fs::remove_dir_all(&d);
|
||||
}
|
||||
|
||||
/// #1624: a renderer skipped by the probe (DX12 → Vulkan) is no pop-up; a died start or a
|
||||
/// failed forced renderer still is.
|
||||
#[test]
|
||||
fn probe_fallback_is_silent() {
|
||||
let (dx, vk) = (WindowRenderer::Wgpu(Backends::DX12), WindowRenderer::Wgpu(Backends::VULKAN));
|
||||
let problems = vec!["The dx12 renderer failed (Validation Error).".to_string()];
|
||||
assert_eq!(user_notice(None, None, &problems, vk), None);
|
||||
assert_eq!(user_notice(None, None, &[], vk), None);
|
||||
let forced = user_notice(None, Some(dx), &problems, vk).unwrap();
|
||||
assert!(forced.starts_with("The dx12 renderer failed") && forced.contains("now draws its window with vulkan"), "{forced}");
|
||||
let died = user_notice(Some(dx), None, &problems, vk).unwrap();
|
||||
assert!(died.contains("last time") && !died.contains("Validation Error"), "{died}");
|
||||
}
|
||||
|
||||
/// The crash report: a pipeline that fails validation must come back as an error, never as
|
||||
/// wgpu's default panic. Needs an adapter; skipped where there is none (CI without a GPU).
|
||||
#[test]
|
||||
|
||||
@@ -105,7 +105,8 @@ or worked around with `LIGHTCRAFT_GPU_BACKEND`.
|
||||
**The window's renderer and its fallback (Windows).** Before the window opens, each renderer is probed in
|
||||
order: DX12, Vulkan, GL, then eframe's OpenGL renderer (glow). A probe creates a device and builds egui's
|
||||
pipeline inside wgpu error scopes, so a driver that cannot compile egui's shaders ("The parameter is
|
||||
incorrect. (0x80070057)" in `egui_pipeline`) is logged and skipped instead of killing the app. The renderer
|
||||
incorrect. (0x80070057)" in `egui_pipeline`) is logged and skipped instead of killing the app; no pop-up
|
||||
unless that renderer was forced (#1624). The renderer
|
||||
that worked is remembered in the settings folder (`window-renderer`); a start that dies before the window is up
|
||||
leaves `window-init.marker`, and the next start (relaunched automatically, at most 4 times) tries that
|
||||
renderer last. `LIGHTCRAFT_GPU_BACKEND=dx12 | vulkan | gl | glow` (or `WGPU_BACKEND`) forces one; DX12 stays
|
||||
|
||||
Reference in New Issue
Block a user