diff --git a/crates/bootstrap/src/plugins.rs b/crates/bootstrap/src/plugins.rs index 1b74df6..71cf212 100644 --- a/crates/bootstrap/src/plugins.rs +++ b/crates/bootstrap/src/plugins.rs @@ -80,6 +80,16 @@ pub fn add_runtime_plugins_with_role(app: &mut App, role: RuntimeRole) { render_app.edit_schedule(bevy::render::ExtractSchedule, |schedule| { schedule.set_executor(bevy::ecs::schedule::SingleThreadedExecutor::new()); }); + if cfg!(target_os = "macos") && pipelined_rendering() { + // The Metal surface must be created on the main thread; pipelined, only + // extraction runs there. + render_app.add_systems( + bevy::render::ExtractSchedule, + bevy::render::view::create_surfaces + .run_if(bevy::render::view::need_surface_configuration) + .after(bevy::render::camera::extract_cameras), + ); + } } } @@ -128,11 +138,7 @@ const PIPELINED_RENDERING_ENV: &str = "IW4L_PIPELINED_RENDERING"; /// boundary; the bounded render channel permits one outstanding frame. /// Set IW4L_PIPELINED_RENDERING=0 for synchronous presentation. /// -/// Off by default on macOS: AppKit only lets the main thread touch the NSView -/// behind the Metal surface. Bevy hands `create_surfaces` back to the main -/// thread through the multi-threaded executor, which the single-threaded -/// `Render` schedule above bypasses, so the render thread would create it and -/// panic in `raw-window-metal`. +/// Off by default on macOS. fn pipelined_rendering() -> bool { match std::env::var_os(PIPELINED_RENDERING_ENV) { None => !cfg!(target_os = "macos"), diff --git a/docs/BUILD.md b/docs/BUILD.md index 43d543e..c622514 100644 --- a/docs/BUILD.md +++ b/docs/BUILD.md @@ -33,7 +33,7 @@ macOS needs only the Xcode command line tools (`xcode-select --install`) and rustup: winit, wgpu (Metal), CoreAudio and gilrs link system frameworks, and the `x11` / `wayland` features compile to nothing. Menu and `make map mp_boneyard` run on Apple silicon (M2 Max, Metal). Pipelined -rendering is off by default there (`bootstrap/src/plugins.rs` says why). +rendering is off by default there; `IW4L_PIPELINED_RENDERING=1` turns it on. Game data: the Windows depot of a Steam copy, `steamcmd +@sSteamCmdForcePlatformType windows +force_install_dir ~/Games/MW2 +login +app_update 10190 +quit`, then `IW4L_GAMES=~/Games`.