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 <noreply@anthropic.com>
This commit is contained in:
Jeremy Yao 2026-10-10 01:46:30 -04:00 committed by Brandon Thomas
parent e91d26d99f
commit bee2ffc283
1 changed files with 21 additions and 1 deletions

View File

@ -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,