diff --git a/apps/craft-anything/src/main.rs b/apps/craft-anything/src/main.rs index 07f06e68..4282d4ea 100644 --- a/apps/craft-anything/src/main.rs +++ b/apps/craft-anything/src/main.rs @@ -48,6 +48,10 @@ fn main() -> eframe::Result { let mut options = eframe::NativeOptions { viewport, ..Default::default() }; #[cfg(windows)] if let eframe::egui_wgpu::WgpuSetup::CreateNew(setup) = &mut options.wgpu_options.wgpu_setup { + // Starting GL loads the system's OpenGL driver before any adapter is picked, and some + // Intel drivers crash in it (ig9icd64.dll, #196), so the window never opens. DX12 (with + // WARP) and Vulkan always cover Windows; `WGPU_BACKEND=gl` still asks for GL. + setup.instance_descriptor.backends = windows_backends(eframe::wgpu::Backends::from_env()); setup.native_adapter_selector = Some(Arc::new(pick_adapter)); } let run = eframe::run_native( @@ -102,6 +106,13 @@ fn pick_adapter(adapters: &[eframe::wgpu::Adapter], surface: Option<&eframe::wgp } } +/// Windows: the graphics backends to start. `WGPU_BACKEND` decides when set; otherwise every +/// primary backend and not GL (#196). +#[cfg(windows)] +fn windows_backends(from_env: Option) -> eframe::wgpu::Backends { + from_env.unwrap_or(eframe::wgpu::Backends::PRIMARY) +} + /// Lower is better: GL last, then the fastest kind of device first (wgpu's own high-performance /// preference). #[cfg(windows)] @@ -131,6 +142,15 @@ mod tests { assert_eq!(best(&[(B::Dx12, T::IntegratedGpu), (B::Vulkan, T::DiscreteGpu), (B::Dx12, T::Cpu)]), Some(1), "fastest GPU first"); assert_eq!(best(&[(B::Gl, T::Other)]), Some(0), "GL when it's all there is"); } + + /// #196: an Intel OpenGL driver crashed the app as wgpu started GL, before any window. + #[test] + fn gl_is_only_started_when_asked_for() { + use eframe::wgpu::Backends; + let started = windows_backends(None); + assert!(!started.contains(Backends::GL) && started.contains(Backends::DX12) && started.contains(Backends::VULKAN)); + assert_eq!(windows_backends(Some(Backends::GL)), Backends::GL, "WGPU_BACKEND=gl still works"); + } } /// Kept small: started afresh once it passes this size. diff --git a/docs/pitfalls.md b/docs/pitfalls.md index 0c59e076..25ec7f85 100644 --- a/docs/pitfalls.md +++ b/docs/pitfalls.md @@ -141,6 +141,11 @@ real Deep-mode run (the CLI never shows it: it already has a console). Every chi the windowed app gets `CREATE_NO_WINDOW`; check the desktop app, not only the CLI, after adding a program. +**A graphics backend that crashed before it was chosen.** We ranked GL last when picking an +adapter, but eframe starts every backend first, and starting GL loaded an old Intel OpenGL driver +that crashed the app before any window or error box (#196). Ranking can't protect you from a +backend that's started at all: start only the backends the app may use. + **A Mac app that couldn't find Claude Code, and offered a GitHub key instead.** An app opened from the Dock gets the system's short `PATH`, not the shell's, so `claude` in `~/.local/bin` wasn't found; "Built by" then fell back to "Claude Code on github.com-work", an `~/.ssh/config` alias