From 41f7736959e10d7e5968d2202598c687499b27b5 Mon Sep 17 00:00:00 2001 From: fabian-co Date: Mon, 12 Oct 2026 17:45:45 -0500 Subject: [PATCH] macOS: open the window on Intel Metal by skipping indirect-call validation wgpu validates indirect draw and dispatch arguments with a compute shader it compiles when the device is created. Metal on an Intel Iris Pro (MacBookPro11,3, macOS 12.7.6) fails to compile it ("Compiler encountered an internal error" in MTLCompilerService), the device is lost, and the window never opens. EffectCraft draws and dispatches nothing indirectly, so leave the check out of the instance flags. WGPU_VALIDATION_INDIRECT_CALL=1 turns it back on. VectorCraft does the same (storytold/vectorcraft#651). Co-Authored-By: Claude Opus 5.5 --- apps/effectcraft/src/main.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/apps/effectcraft/src/main.rs b/apps/effectcraft/src/main.rs index 83015f1a..3135fc35 100644 --- a/apps/effectcraft/src/main.rs +++ b/apps/effectcraft/src/main.rs @@ -308,6 +308,11 @@ fn wgpu_options(backends: Option) -> eframe::WgpuConfigu if let Some(b) = backends { setup.instance_descriptor.backends = b; } + // Nothing draws or dispatches indirectly, so wgpu's check of indirect arguments only costs + // a compute shader when the device is created, one that Metal can't compile on an Intel + // Iris Pro: the device is lost and the window never opens. + // `WGPU_VALIDATION_INDIRECT_CALL=1` turns the check back on. + setup.instance_descriptor.flags = setup.instance_descriptor.flags.difference(eframe::wgpu::InstanceFlags::VALIDATION_INDIRECT_CALL).with_env(); setup.device_descriptor = std::sync::Arc::new(|adapter| eframe::wgpu::DeviceDescriptor { label: Some("EffectCraft device"), required_limits: device_limits(adapter.limits()), @@ -442,6 +447,18 @@ mod tests { } /// The window's device never asks for more than the adapter offers (#198). + #[test] + fn the_window_instance_skips_indirect_call_validation() { + if std::env::var_os("WGPU_VALIDATION_INDIRECT_CALL").is_some() { + return; + } + let eframe::egui_wgpu::WgpuSetup::CreateNew(setup) = super::wgpu_options(None).wgpu_setup else { + panic!("the default setup creates its own instance"); + }; + // Intel Metal can't compile the validation's compute shader, and the device is lost. + assert!(!setup.instance_descriptor.flags.contains(eframe::wgpu::InstanceFlags::VALIDATION_INDIRECT_CALL)); + } + #[test] fn device_limits_fit_the_adapter() { use eframe::wgpu::Limits;