mirror of
https://github.com/storytold/wordcraft.git
synced 2026-10-19 02:10:15 -05:00
wgpu compiles its indirect-call validation compute shaders inside request_device. On Intel HD Graphics 5000 (Big Sur) Metal's Intel compiler aborts on them, the device is lost and eframe exits before the window opens. WordCraft issues no indirect draws or dispatches, so x86_64 macOS builds leave VALIDATION_INDIRECT_CALL out of the instance flags (WGPU_VALIDATION_INDIRECT_CALL=1 still re-enables it). Same fix as storytold/PhotoCraft#3171. Fixes storytold/WordCraft#2652 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
2 files changed
+56
-4
No files matched your search
@@ -1,12 +1,34 @@
|
||||
//! Windows graphics instance configuration (backends and the DirectX 12 shader compiler), applied
|
||||
//! before wgpu can initialize any driver.
|
||||
//! Graphics instance configuration applied before wgpu can initialize any driver: Windows
|
||||
//! backends and the DirectX 12 shader compiler, and the Intel Mac indirect-validation skip.
|
||||
// On macOS only the indirect-validation items are used outside tests.
|
||||
#![cfg_attr(target_os = "macos", allow(dead_code))]
|
||||
|
||||
use eframe::{
|
||||
NativeOptions,
|
||||
egui_wgpu::WgpuSetup,
|
||||
wgpu::{Backends, DeviceType, Dx12Compiler},
|
||||
wgpu::{Backends, DeviceType, Dx12Compiler, InstanceFlags},
|
||||
};
|
||||
|
||||
/// wgpu compiles its indirect-call validation compute shaders inside `request_device`. On old
|
||||
/// Intel Macs (HD Graphics 5000 on Big Sur, #2652) Metal's Intel
|
||||
/// compiler aborts on them, the device is lost and eframe exits before the window opens. WordCraft
|
||||
/// issues no indirect draws or dispatches, so Intel Macs skip them; every other GPU keeps wgpu's
|
||||
/// default. Same fix as PhotoCraft's storytold/PhotoCraft#3171.
|
||||
pub fn skips_indirect_validation(macos: bool, intel: bool) -> bool {
|
||||
macos && intel
|
||||
}
|
||||
|
||||
/// Leaves wgpu's indirect-call validation out of the instance eframe creates when `skip`.
|
||||
/// `WGPU_VALIDATION_INDIRECT_CALL=1` still turns it back on.
|
||||
pub fn configure_indirect_validation(options: &mut NativeOptions, skip: bool) {
|
||||
if !skip {
|
||||
return;
|
||||
}
|
||||
if let WgpuSetup::CreateNew(create) = &mut options.wgpu_options.wgpu_setup {
|
||||
create.instance_descriptor.flags = create.instance_descriptor.flags.difference(InstanceFlags::VALIDATION_INDIRECT_CALL).with_env();
|
||||
}
|
||||
}
|
||||
|
||||
/// What the start-up probe learned about one DirectX 12 adapter.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Dx12Adapter {
|
||||
@@ -153,6 +175,33 @@ fn probe_dx12(options: &NativeOptions) -> Vec<Dx12Adapter> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn intel_macs_skip_the_indirect_validation_shaders() {
|
||||
// #2652: Metal's Intel compiler aborted on them, losing the device before the window opened.
|
||||
assert!(skips_indirect_validation(true, true));
|
||||
// Apple silicon, Windows and Linux keep wgpu's validation.
|
||||
for (macos, intel) in [(true, false), (false, true), (false, false)] {
|
||||
assert!(!skips_indirect_validation(macos, intel), "macos={macos} intel={intel}");
|
||||
}
|
||||
let mut options = NativeOptions::default();
|
||||
let WgpuSetup::CreateNew(before) = &options.wgpu_options.wgpu_setup else {
|
||||
panic!("default native options must create a wgpu instance");
|
||||
};
|
||||
let before = before.instance_descriptor.flags;
|
||||
configure_indirect_validation(&mut options, false);
|
||||
let WgpuSetup::CreateNew(create) = &options.wgpu_options.wgpu_setup else {
|
||||
panic!("default native options must create a wgpu instance");
|
||||
};
|
||||
assert_eq!(create.instance_descriptor.flags, before, "flags untouched when not skipping");
|
||||
if std::env::var_os("WGPU_VALIDATION_INDIRECT_CALL").is_none() {
|
||||
configure_indirect_validation(&mut options, true);
|
||||
let WgpuSetup::CreateNew(create) = &options.wgpu_options.wgpu_setup else {
|
||||
panic!("default native options must create a wgpu instance");
|
||||
};
|
||||
assert!(!create.instance_descriptor.flags.contains(InstanceFlags::VALIDATION_INDIRECT_CALL));
|
||||
}
|
||||
}
|
||||
|
||||
fn configured_backends(backends: Backends) -> Backends {
|
||||
let mut options = NativeOptions::default();
|
||||
configure_backends(&mut options, backends);
|
||||
|
||||
@@ -16,7 +16,7 @@ mod clipboard;
|
||||
mod control_server;
|
||||
mod default_apps;
|
||||
mod file_dialogs;
|
||||
#[cfg(any(target_os = "windows", test))]
|
||||
#[cfg(any(target_os = "windows", target_os = "macos", test))]
|
||||
mod graphics;
|
||||
mod logging;
|
||||
mod print;
|
||||
@@ -389,6 +389,9 @@ fn main() -> eframe::Result {
|
||||
// FXC, which needs no DLL of ours (#603; see graphics.rs).
|
||||
#[cfg(target_os = "windows")]
|
||||
graphics::configure(&mut options, eframe::wgpu::Backends::from_env());
|
||||
// Intel Macs: Metal's compiler aborts on wgpu's indirect-validation shaders (#2652).
|
||||
#[cfg(target_os = "macos")]
|
||||
graphics::configure_indirect_validation(&mut options, graphics::skips_indirect_validation(true, cfg!(target_arch = "x86_64")));
|
||||
load_user_fonts();
|
||||
let restored = saved_window();
|
||||
if let Some(window) = restored {
|
||||
|
||||
Reference in new issue
Block a user