diff --git a/README.md b/README.md index 39eb0325..606b3e31 100644 --- a/README.md +++ b/README.md @@ -327,8 +327,8 @@ Nothing below the front ends depends on a UI toolkit or OS API. `cargo xtask ci` Installers and executables are code-signed. -**If the app doesn't open on Windows:** the desktop app initializes only DirectX 12 by default. -Letting wgpu also create an OpenGL instance can crash some graphics drivers (AMD's +**If the app doesn't open on Windows:** the desktop app initializes only Vulkan and DirectX 12 by +default, not OpenGL. Letting wgpu also create an OpenGL instance can crash some graphics drivers (AMD's `atio6axx.dll`) before the window appears, so the app would flash in Task Manager and quit. `WGPU_BACKEND` overrides the default for troubleshooting (for example `dx12` or `vulkan`). In PowerShell, from the folder containing the executable: diff --git a/apps/filmcraft/src/graphics.rs b/apps/filmcraft/src/graphics.rs index ccd0c459..b2be99cb 100644 --- a/apps/filmcraft/src/graphics.rs +++ b/apps/filmcraft/src/graphics.rs @@ -2,16 +2,18 @@ use eframe::{NativeOptions, egui_wgpu::WgpuSetup, wgpu::Backends}; -/// Restrict the wgpu instance to DirectX 12 unless `backend_override` (normally -/// `Backends::from_env()`, i.e. `WGPU_BACKEND`) names other backends. +/// Restrict the wgpu instance to the primary backends (Vulkan, DirectX 12, Metal), i.e. leave +/// OpenGL out, unless `backend_override` (normally `Backends::from_env()`, i.e. `WGPU_BACKEND`) +/// names other backends. pub fn configure(options: &mut NativeOptions, backend_override: Option) { if let WgpuSetup::CreateNew(create) = &mut options.wgpu_options.wgpu_setup { // eframe's default includes GL. Creating that backend can crash inside AMD's // atio6axx.dll before adapter selection or any Rust error handling runs, so the // window never appears. Choosing an adapter afterwards is too late: only leaving GL - // out of the instance avoids it. This matches the verified WGPU_BACKEND=dx12 - // workaround without mutating process environment variables. - create.instance_descriptor.backends = backend_override.unwrap_or(Backends::DX12); + // out of the instance avoids it. Keep Vulkan and DX12 both: forcing DX12 alone sends + // shaders through FXC (which rejects fx.wgsl, silently falling back to the CPU) and + // leaves machines without DX12 with no backend at all. + create.instance_descriptor.backends = backend_override.unwrap_or(Backends::PRIMARY); } } @@ -29,13 +31,16 @@ mod tests { } #[test] - fn windows_default_initializes_only_dx12() { + fn windows_default_leaves_out_gl() { // eframe's own default (PRIMARY | GL) would initialize OpenGL as well. let WgpuSetup::CreateNew(eframe_default) = NativeOptions::default().wgpu_options.wgpu_setup else { panic!("default native options must create a wgpu instance"); }; assert!(eframe_default.instance_descriptor.backends.contains(Backends::GL)); - assert_eq!(configured_backends(None), Backends::DX12); + let configured = configured_backends(None); + assert_eq!(configured, Backends::PRIMARY); + assert!(!configured.contains(Backends::GL)); + assert!(configured.contains(Backends::DX12) && configured.contains(Backends::VULKAN)); } #[test]