This commit is contained in:
Claude 2026-10-11 11:39:26 +00:00
commit 9ecd3309b2
No known key found for this signature in database
4 changed files with 46 additions and 0 deletions

View File

@ -98,6 +98,8 @@ fn window_wgpu_options() -> eframe::egui_wgpu::WgpuConfiguration {
if let eframe::egui_wgpu::WgpuSetup::CreateNew(n) = &mut c.wgpu_setup {
n.instance_descriptor.backends = lightcraft_engine::gpu::backend::window_backends();
n.instance_descriptor.backend_options = lightcraft_engine::gpu::backend::backend_options();
// no indirect-call validation pipeline: Intel Metal fails to compile it and the window never opens (#250)
n.instance_descriptor.flags = lightcraft_engine::gpu::backend::instance_flags_from_env(n.instance_descriptor.flags);
}
c
}
@ -1086,6 +1088,16 @@ mod tests {
}
}
/// Issue #250: the window's device is created without wgpu's indirect-call validation pipeline,
/// which Intel Macs' Metal compiler fails to build (the device was lost, the window never opened).
#[test]
fn window_has_no_indirect_call_validation_pipeline() {
let eframe::egui_wgpu::WgpuSetup::CreateNew(n) = window_wgpu_options().wgpu_setup else { panic!("expected CreateNew") };
if std::env::var_os("WGPU_VALIDATION_INDIRECT_CALL").is_none() {
assert!(!n.instance_descriptor.flags.contains(eframe::wgpu::InstanceFlags::VALIDATION_INDIRECT_CALL));
}
}
/// Issue #234: Windows opens links with the URL protocol handler (the default browser), not
/// File Explorer, and passes the whole map link, `?`, `&` and `#` included, as one argument.
#[test]

View File

@ -145,6 +145,25 @@ pub fn backend_options() -> wgpu::BackendOptions {
o
}
/// wgpu's instance flags for every instance LightCraft creates, from `flags` (wgpu's defaults with its
/// environment variables applied) without `VALIDATION_INDIRECT_CALL`, unless
/// `WGPU_VALIDATION_INDIRECT_CALL` asks for it (any value but `0`). That validation builds an internal
/// compute pipeline when each device is created; Intel Macs' Metal compiler fails on it ("Compiler
/// encountered an internal error"), the device is lost and the window never opens (#250). It only
/// guards indirect draws and dispatches, which neither LightCraft nor egui issue.
pub fn instance_flags(flags: wgpu::InstanceFlags, env: Option<&str>) -> wgpu::InstanceFlags {
if env.is_some_and(|v| v != "0") {
flags | wgpu::InstanceFlags::VALIDATION_INDIRECT_CALL
} else {
flags - wgpu::InstanceFlags::VALIDATION_INDIRECT_CALL
}
}
/// [`instance_flags`] with `WGPU_VALIDATION_INDIRECT_CALL` read from the environment.
pub fn instance_flags_from_env(flags: wgpu::InstanceFlags) -> wgpu::InstanceFlags {
instance_flags(flags, std::env::var("WGPU_VALIDATION_INDIRECT_CALL").ok().as_deref())
}
/// `LIGHTCRAFT_GPU_BACKEND=off`.
pub(crate) fn env_off() -> bool {
env_choice() == BackendChoice::Off
@ -195,6 +214,17 @@ pub fn read_init_marker(path: &std::path::Path) -> Option<String> {
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
/// #250: the indirect-call validation pipeline is off unless asked for; other flags are kept.
#[test]
fn indirect_call_validation_is_off_unless_asked_for() {
use wgpu::InstanceFlags as F;
let base = F::VALIDATION_INDIRECT_CALL | F::DEBUG;
assert_eq!(instance_flags(base, None), F::DEBUG);
assert_eq!(instance_flags(base, Some("0")), F::DEBUG);
assert_eq!(instance_flags(F::empty(), Some("1")), F::VALIDATION_INDIRECT_CALL);
assert_eq!(instance_flags(F::empty(), None), F::empty());
}
use super::*;
#[test]

View File

@ -284,6 +284,8 @@ impl Gpu {
desc.backends = backends;
// DX12 shaders compile with FXC (issue #471)
desc.backend_options = crate::backend::backend_options();
// no indirect-call validation pipeline: Intel Metal fails to compile it (#250)
desc.flags = crate::backend::instance_flags_from_env(desc.flags);
let instance = wgpu::Instance::new(desc);
let adapter = pollster::block_on(
instance.request_adapter(&wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::HighPerformance, ..Default::default() }),

View File

@ -86,6 +86,8 @@ fn make_device(backends: wgpu::Backends) -> Result<Dev, String> {
desc.backends = backends;
// DX12 shaders compile with FXC (issue #471)
desc.backend_options = crate::backend::backend_options();
// no indirect-call validation pipeline: Intel Metal fails to compile it (#250)
desc.flags = crate::backend::instance_flags_from_env(desc.flags);
let instance = wgpu::Instance::new(desc);
let wanted = std::env::var("LIGHTCRAFT_GPU_ADAPTER").ok().map(|s| s.trim().to_lowercase()).filter(|s| !s.is_empty());
let adapter = match &wanted {