mirror of
https://github.com/storytold/craft-launcher.git
synced 2026-11-02 18:07:04 +00:00
macOS: skip wgpu's indirect-call validation on Intel Macs (#569)
wgpu 30 turns on InstanceFlags::VALIDATION_INDIRECT_CALL by default and compiles its indirect-validation compute shaders in request_device. On Intel Iris and Iris Pro Macs, Metal's compiler fails on them with an internal error, the device is lost and the launcher exits at startup. wgpu_options() on macOS now removes the flag when the build is x86_64, then applies with_env() so WGPU_VALIDATION_INDIRECT_CALL=1 turns it back on. The launcher issues no indirect draws or dispatches. Apple silicon, Windows and Linux keep wgpu's default. This follows PhotoCraft's fix in storytold/photocraft#3171 (apps/photocraft/src/gpu_startup.rs). Fixes #344
This commit is contained in:
@@ -276,9 +276,29 @@ fn wgpu_options() -> eframe::WgpuConfiguration {
|
||||
config
|
||||
}
|
||||
|
||||
/// Returns wgpu's defaults, except that Intel Macs skip the indirect-call validation shaders
|
||||
/// ([`skips_indirect_validation`]).
|
||||
#[cfg(target_os = "macos")]
|
||||
fn wgpu_options() -> eframe::WgpuConfiguration {
|
||||
eframe::WgpuConfiguration::default()
|
||||
use eframe::wgpu::InstanceFlags;
|
||||
let mut config = eframe::WgpuConfiguration::default();
|
||||
if let eframe::egui_wgpu::WgpuSetup::CreateNew(setup) = &mut config.wgpu_setup
|
||||
&& skips_indirect_validation(std::env::consts::OS, cfg!(target_arch = "x86_64"))
|
||||
{
|
||||
setup.instance_descriptor.flags = setup.instance_descriptor.flags.difference(InstanceFlags::VALIDATION_INDIRECT_CALL).with_env();
|
||||
}
|
||||
config
|
||||
}
|
||||
|
||||
/// wgpu compiles its indirect-call validation shaders inside `request_device`. On old Intel Macs
|
||||
/// on Big Sur and Monterey (Iris and Iris Pro among them), Metal's compiler fails on them with an
|
||||
/// internal error, the device is lost and the launcher exits at startup (#344). Intel Macs skip
|
||||
/// them, and other platforms keep wgpu's default. The launcher issues no indirect draws or
|
||||
/// dispatches. `WGPU_VALIDATION_INDIRECT_CALL=1` still turns them back on. PhotoCraft does the same
|
||||
/// (storytold/photocraft#3171).
|
||||
#[cfg(any(target_os = "macos", test))]
|
||||
fn skips_indirect_validation(os: &str, intel: bool) -> bool {
|
||||
os == "macos" && intel
|
||||
}
|
||||
|
||||
/// Wakes whatever is running the launcher: the window while there is one, the tray loop otherwise.
|
||||
@@ -1044,6 +1064,38 @@ mod tests {
|
||||
assert!(!shell.launcher.closed_to_tray);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn intel_macs_skip_the_indirect_validation_shaders() {
|
||||
// Metal's compiler fails on them on Intel Iris Macs, losing the device (#344).
|
||||
assert!(skips_indirect_validation("macos", true));
|
||||
// Apple silicon, Windows, Linux and the BSDs keep wgpu's validation.
|
||||
for (os, intel) in [("macos", false), ("windows", true), ("windows", false), ("linux", true), ("linux", false), ("freebsd", true)] {
|
||||
assert!(!skips_indirect_validation(os, intel), "{os} intel={intel}");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[test]
|
||||
fn intel_macs_create_the_device_without_indirect_validation() {
|
||||
use eframe::egui_wgpu::WgpuSetup;
|
||||
use eframe::wgpu::InstanceFlags;
|
||||
fn flags(config: eframe::WgpuConfiguration) -> InstanceFlags {
|
||||
match config.wgpu_setup {
|
||||
WgpuSetup::CreateNew(setup) => setup.instance_descriptor.flags,
|
||||
WgpuSetup::Existing(_) => panic!("the launcher creates its own wgpu instance"),
|
||||
}
|
||||
}
|
||||
let launcher = flags(wgpu_options());
|
||||
if !cfg!(target_arch = "x86_64") {
|
||||
// Apple silicon keeps wgpu's flags.
|
||||
assert_eq!(launcher, flags(eframe::WgpuConfiguration::default()));
|
||||
} else {
|
||||
// The flag is off unless `WGPU_VALIDATION_INDIRECT_CALL` turns it back on.
|
||||
let asked = std::env::var_os("WGPU_VALIDATION_INDIRECT_CALL").is_some_and(|v| v != "0");
|
||||
assert_eq!(launcher.contains(InstanceFlags::VALIDATION_INDIRECT_CALL), asked, "{launcher:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dx12_shaders_compile_with_fxc_unless_asked() {
|
||||
use eframe::egui_wgpu::WgpuSetup;
|
||||
|
||||
Reference in New Issue
Block a user