From bee2ffc28337ad21975e0e5992ef0deae118badf Mon Sep 17 00:00:00 2001 From: Jeremy Yao Date: Sat, 10 Oct 2026 01:46:30 -0400 Subject: [PATCH] Default wgpu to Direct3D 12 on Windows: fixes startup crash on hybrid AMD laptops On Windows the launcher now asks wgpu for DX12 with GL as the fallback instead of wgpu's default list, which starts with Vulkan. WGPU_BACKEND still overrides it; other platforms keep wgpu's defaults. Without this the launcher died on startup with STATUS_ACCESS_VIOLATION on an ASUS G513QY (Ryzen 9 5900HX integrated Radeon + Radeon RX 6800M). The crash is inside AMD's Vulkan driver (amdvlk64.dll): the integrated GPU runs the OEM driver from 2021 while the 6800M runs Adrenalin from 2026, both register a Vulkan ICD, the loader reports the 6800M twice, and wgpu's pick dies right after the surface is configured. AMD's installer never updates the OEM iGPU driver, so this state is common on hybrid laptops. DX12 and GL both work. Also reorders one import in self_update.rs that stable rustfmt flagged, so `cargo xtask ci` passes again. Co-Authored-By: Claude Fable 5.1 --- apps/artcraft-launcher/src/main.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/apps/artcraft-launcher/src/main.rs b/apps/artcraft-launcher/src/main.rs index 8077318..e5de160 100644 --- a/apps/artcraft-launcher/src/main.rs +++ b/apps/artcraft-launcher/src/main.rs @@ -55,7 +55,7 @@ fn main() -> ExitCode { if let Some(icon) = icon { viewport = viewport.with_icon(icon); } - let options = eframe::NativeOptions { viewport, persist_window: true, ..Default::default() }; + let options = eframe::NativeOptions { viewport, persist_window: true, wgpu_options: wgpu_options(), ..Default::default() }; let result = eframe::run_native( "ArtCraft Launcher", options, @@ -74,6 +74,26 @@ fn main() -> ExitCode { } } +/// wgpu's backend list. On Windows that is Direct3D 12 with GL as the fallback, not Vulkan: +/// Vulkan goes through vendor ICDs and third-party overlay layers, and on hybrid AMD laptops whose +/// integrated and discrete GPUs run different driver packages (common on OEM machines, where the +/// Adrenalin installer leaves the integrated GPU on the OEM driver) it crashes inside +/// `amdvlk64.dll` before the first frame. `WGPU_BACKEND` still overrides the default. +#[cfg(windows)] +fn wgpu_options() -> eframe::WgpuConfiguration { + use eframe::wgpu::Backends; + let mut config = eframe::WgpuConfiguration::default(); + if let eframe::egui_wgpu::WgpuSetup::CreateNew(setup) = &mut config.wgpu_setup { + setup.instance_descriptor.backends = Backends::from_env().unwrap_or(Backends::DX12 | Backends::GL); + } + config +} + +#[cfg(not(windows))] +fn wgpu_options() -> eframe::WgpuConfiguration { + eframe::WgpuConfiguration::default() +} + struct DesktopHost { tray: bool, quit: bool,