bevy/tools/build-wasm-example/src/main.rs

107 lines
3.1 KiB
Rust
Raw Normal View History

//! Tool used to build Bevy examples for wasm.
use std::{fs::File, io::Write};
Webgpu support (#8336) # Objective - Support WebGPU - alternative to #5027 that doesn't need any async / await - fixes #8315 - Surprise fix #7318 ## Solution ### For async renderer initialisation - Update the plugin lifecycle: - app builds the plugin - calls `plugin.build` - registers the plugin - app starts the event loop - event loop waits for `ready` of all registered plugins in the same order - returns `true` by default - then call all `finish` then all `cleanup` in the same order as registered - then execute the schedule In the case of the renderer, to avoid anything async: - building the renderer plugin creates a detached task that will send back the initialised renderer through a mutex in a resource - `ready` will wait for the renderer to be present in the resource - `finish` will take that renderer and place it in the expected resources by other plugins - other plugins (that expect the renderer to be available) `finish` are called and they are able to set up their pipelines - `cleanup` is called, only custom one is still for pipeline rendering ### For WebGPU support - update the `build-wasm-example` script to support passing `--api webgpu` that will build the example with WebGPU support - feature for webgl2 was always enabled when building for wasm. it's now in the default feature list and enabled on all platforms, so check for this feature must also check that the target_arch is `wasm32` --- ## Migration Guide - `Plugin::setup` has been renamed `Plugin::cleanup` - `Plugin::finish` has been added, and plugins adding pipelines should do it in this function instead of `Plugin::build` ```rust // Before impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>() .init_resource::<OtherRenderResource>(); } } // After impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<OtherRenderResource>(); } fn finish(&self, app: &mut App) { let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>(); } } ```
2023-05-04 22:07:57 +00:00
use clap::{Parser, ValueEnum};
use xshell::{cmd, Shell};
Webgpu support (#8336) # Objective - Support WebGPU - alternative to #5027 that doesn't need any async / await - fixes #8315 - Surprise fix #7318 ## Solution ### For async renderer initialisation - Update the plugin lifecycle: - app builds the plugin - calls `plugin.build` - registers the plugin - app starts the event loop - event loop waits for `ready` of all registered plugins in the same order - returns `true` by default - then call all `finish` then all `cleanup` in the same order as registered - then execute the schedule In the case of the renderer, to avoid anything async: - building the renderer plugin creates a detached task that will send back the initialised renderer through a mutex in a resource - `ready` will wait for the renderer to be present in the resource - `finish` will take that renderer and place it in the expected resources by other plugins - other plugins (that expect the renderer to be available) `finish` are called and they are able to set up their pipelines - `cleanup` is called, only custom one is still for pipeline rendering ### For WebGPU support - update the `build-wasm-example` script to support passing `--api webgpu` that will build the example with WebGPU support - feature for webgl2 was always enabled when building for wasm. it's now in the default feature list and enabled on all platforms, so check for this feature must also check that the target_arch is `wasm32` --- ## Migration Guide - `Plugin::setup` has been renamed `Plugin::cleanup` - `Plugin::finish` has been added, and plugins adding pipelines should do it in this function instead of `Plugin::build` ```rust // Before impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>() .init_resource::<OtherRenderResource>(); } } // After impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<OtherRenderResource>(); } fn finish(&self, app: &mut App) { let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>(); } } ```
2023-05-04 22:07:57 +00:00
#[derive(Debug, Copy, Clone, ValueEnum)]
enum WebApi {
Webgpu support (#8336) # Objective - Support WebGPU - alternative to #5027 that doesn't need any async / await - fixes #8315 - Surprise fix #7318 ## Solution ### For async renderer initialisation - Update the plugin lifecycle: - app builds the plugin - calls `plugin.build` - registers the plugin - app starts the event loop - event loop waits for `ready` of all registered plugins in the same order - returns `true` by default - then call all `finish` then all `cleanup` in the same order as registered - then execute the schedule In the case of the renderer, to avoid anything async: - building the renderer plugin creates a detached task that will send back the initialised renderer through a mutex in a resource - `ready` will wait for the renderer to be present in the resource - `finish` will take that renderer and place it in the expected resources by other plugins - other plugins (that expect the renderer to be available) `finish` are called and they are able to set up their pipelines - `cleanup` is called, only custom one is still for pipeline rendering ### For WebGPU support - update the `build-wasm-example` script to support passing `--api webgpu` that will build the example with WebGPU support - feature for webgl2 was always enabled when building for wasm. it's now in the default feature list and enabled on all platforms, so check for this feature must also check that the target_arch is `wasm32` --- ## Migration Guide - `Plugin::setup` has been renamed `Plugin::cleanup` - `Plugin::finish` has been added, and plugins adding pipelines should do it in this function instead of `Plugin::build` ```rust // Before impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>() .init_resource::<OtherRenderResource>(); } } // After impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<OtherRenderResource>(); } fn finish(&self, app: &mut App) { let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>(); } } ```
2023-05-04 22:07:57 +00:00
Webgl2,
Webgpu,
}
#[derive(Parser, Debug)]
struct Args {
/// Examples to build
examples: Vec<String>,
#[arg(short, long)]
/// Run tests
test: bool,
#[arg(short, long)]
/// Run on the given browsers. By default, chromium, firefox, webkit
browsers: Vec<String>,
#[arg(short, long)]
/// Stop after this number of frames
frames: Option<usize>,
Webgpu support (#8336) # Objective - Support WebGPU - alternative to #5027 that doesn't need any async / await - fixes #8315 - Surprise fix #7318 ## Solution ### For async renderer initialisation - Update the plugin lifecycle: - app builds the plugin - calls `plugin.build` - registers the plugin - app starts the event loop - event loop waits for `ready` of all registered plugins in the same order - returns `true` by default - then call all `finish` then all `cleanup` in the same order as registered - then execute the schedule In the case of the renderer, to avoid anything async: - building the renderer plugin creates a detached task that will send back the initialised renderer through a mutex in a resource - `ready` will wait for the renderer to be present in the resource - `finish` will take that renderer and place it in the expected resources by other plugins - other plugins (that expect the renderer to be available) `finish` are called and they are able to set up their pipelines - `cleanup` is called, only custom one is still for pipeline rendering ### For WebGPU support - update the `build-wasm-example` script to support passing `--api webgpu` that will build the example with WebGPU support - feature for webgl2 was always enabled when building for wasm. it's now in the default feature list and enabled on all platforms, so check for this feature must also check that the target_arch is `wasm32` --- ## Migration Guide - `Plugin::setup` has been renamed `Plugin::cleanup` - `Plugin::finish` has been added, and plugins adding pipelines should do it in this function instead of `Plugin::build` ```rust // Before impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>() .init_resource::<OtherRenderResource>(); } } // After impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<OtherRenderResource>(); } fn finish(&self, app: &mut App) { let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>(); } } ```
2023-05-04 22:07:57 +00:00
#[arg(value_enum, short, long, default_value_t = WebApi::Webgl2)]
Webgpu support (#8336) # Objective - Support WebGPU - alternative to #5027 that doesn't need any async / await - fixes #8315 - Surprise fix #7318 ## Solution ### For async renderer initialisation - Update the plugin lifecycle: - app builds the plugin - calls `plugin.build` - registers the plugin - app starts the event loop - event loop waits for `ready` of all registered plugins in the same order - returns `true` by default - then call all `finish` then all `cleanup` in the same order as registered - then execute the schedule In the case of the renderer, to avoid anything async: - building the renderer plugin creates a detached task that will send back the initialised renderer through a mutex in a resource - `ready` will wait for the renderer to be present in the resource - `finish` will take that renderer and place it in the expected resources by other plugins - other plugins (that expect the renderer to be available) `finish` are called and they are able to set up their pipelines - `cleanup` is called, only custom one is still for pipeline rendering ### For WebGPU support - update the `build-wasm-example` script to support passing `--api webgpu` that will build the example with WebGPU support - feature for webgl2 was always enabled when building for wasm. it's now in the default feature list and enabled on all platforms, so check for this feature must also check that the target_arch is `wasm32` --- ## Migration Guide - `Plugin::setup` has been renamed `Plugin::cleanup` - `Plugin::finish` has been added, and plugins adding pipelines should do it in this function instead of `Plugin::build` ```rust // Before impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>() .init_resource::<OtherRenderResource>(); } } // After impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<OtherRenderResource>(); } fn finish(&self, app: &mut App) { let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>(); } } ```
2023-05-04 22:07:57 +00:00
/// Browser API to use for rendering
api: WebApi,
#[arg(short, long)]
/// Optimize the wasm file for size with wasm-opt
optimize_size: bool,
#[arg(long)]
/// Additional features to enable
features: Vec<String>,
}
fn main() {
let cli = Args::parse();
assert!(!cli.examples.is_empty(), "must have at least one example");
Update to wgpu 0.19 and raw-window-handle 0.6 (#11280) # Objective Keep core dependencies up to date. ## Solution Update the dependencies. wgpu 0.19 only supports raw-window-handle (rwh) 0.6, so bumping that was included in this. The rwh 0.6 version bump is just the simplest way of doing it. There might be a way we can take advantage of wgpu's new safe surface creation api, but I'm not familiar enough with bevy's window management to untangle it and my attempt ended up being a mess of lifetimes and rustc complaining about missing trait impls (that were implemented). Thanks to @MiniaczQ for the (much simpler) rwh 0.6 version bump code. Unblocks https://github.com/bevyengine/bevy/pull/9172 and https://github.com/bevyengine/bevy/pull/10812 ~~This might be blocked on cpal and oboe updating their ndk versions to 0.8, as they both currently target ndk 0.7 which uses rwh 0.5.2~~ Tested on android, and everything seems to work correctly (audio properly stops when minimized, and plays when re-focusing the app). --- ## Changelog - `wgpu` has been updated to 0.19! The long awaited arcanization has been merged (for more info, see https://gfx-rs.github.io/2023/11/24/arcanization.html), and Vulkan should now be working again on Intel GPUs. - Targeting WebGPU now requires that you add the new `webgpu` feature (setting the `RUSTFLAGS` environment variable to `--cfg=web_sys_unstable_apis` is still required). This feature currently overrides the `webgl2` feature if you have both enabled (the `webgl2` feature is enabled by default), so it is not recommended to add it as a default feature to libraries without putting it behind a flag that allows library users to opt out of it! In the future we plan on supporting wasm binaries that can target both webgl2 and webgpu now that wgpu added support for doing so (see https://github.com/bevyengine/bevy/issues/11505). - `raw-window-handle` has been updated to version 0.6. ## Migration Guide - `bevy_render::instance_index::get_instance_index()` has been removed as the webgl2 workaround is no longer required as it was fixed upstream in wgpu. The `BASE_INSTANCE_WORKAROUND` shaderdef has also been removed. - WebGPU now requires the new `webgpu` feature to be enabled. The `webgpu` feature currently overrides the `webgl2` feature so you no longer need to disable all default features and re-add them all when targeting `webgpu`, but binaries built with both the `webgpu` and `webgl2` features will only target the webgpu backend, and will only work on browsers that support WebGPU. - Places where you conditionally compiled things for webgl2 need to be updated because of this change, eg: - `#[cfg(any(not(feature = "webgl"), not(target_arch = "wasm32")))]` becomes `#[cfg(any(not(feature = "webgl") ,not(target_arch = "wasm32"), feature = "webgpu"))]` - `#[cfg(all(feature = "webgl", target_arch = "wasm32"))]` becomes `#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]` - `if cfg!(all(feature = "webgl", target_arch = "wasm32"))` becomes `if cfg!(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))` - `create_texture_with_data` now also takes a `TextureDataOrder`. You can probably just set this to `TextureDataOrder::default()` - `TextureFormat`'s `block_size` has been renamed to `block_copy_size` - See the `wgpu` changelog for anything I might've missed: https://github.com/gfx-rs/wgpu/blob/trunk/CHANGELOG.md --------- Co-authored-by: François <mockersf@gmail.com>
2024-01-26 18:14:21 +00:00
let default_features = true;
let mut features: Vec<&str> = cli.features.iter().map(String::as_str).collect();
if let Some(frames) = cli.frames {
let mut file = File::create("ci_testing_config.ron").unwrap();
file.write_fmt(format_args!("(events: [({frames}, AppExit)])"))
.unwrap();
Webgpu support (#8336) # Objective - Support WebGPU - alternative to #5027 that doesn't need any async / await - fixes #8315 - Surprise fix #7318 ## Solution ### For async renderer initialisation - Update the plugin lifecycle: - app builds the plugin - calls `plugin.build` - registers the plugin - app starts the event loop - event loop waits for `ready` of all registered plugins in the same order - returns `true` by default - then call all `finish` then all `cleanup` in the same order as registered - then execute the schedule In the case of the renderer, to avoid anything async: - building the renderer plugin creates a detached task that will send back the initialised renderer through a mutex in a resource - `ready` will wait for the renderer to be present in the resource - `finish` will take that renderer and place it in the expected resources by other plugins - other plugins (that expect the renderer to be available) `finish` are called and they are able to set up their pipelines - `cleanup` is called, only custom one is still for pipeline rendering ### For WebGPU support - update the `build-wasm-example` script to support passing `--api webgpu` that will build the example with WebGPU support - feature for webgl2 was always enabled when building for wasm. it's now in the default feature list and enabled on all platforms, so check for this feature must also check that the target_arch is `wasm32` --- ## Migration Guide - `Plugin::setup` has been renamed `Plugin::cleanup` - `Plugin::finish` has been added, and plugins adding pipelines should do it in this function instead of `Plugin::build` ```rust // Before impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>() .init_resource::<OtherRenderResource>(); } } // After impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<OtherRenderResource>(); } fn finish(&self, app: &mut App) { let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>(); } } ```
2023-05-04 22:07:57 +00:00
features.push("bevy_ci_testing");
}
match cli.api {
WebApi::Webgl2 => (),
WebApi::Webgpu => {
Update to wgpu 0.19 and raw-window-handle 0.6 (#11280) # Objective Keep core dependencies up to date. ## Solution Update the dependencies. wgpu 0.19 only supports raw-window-handle (rwh) 0.6, so bumping that was included in this. The rwh 0.6 version bump is just the simplest way of doing it. There might be a way we can take advantage of wgpu's new safe surface creation api, but I'm not familiar enough with bevy's window management to untangle it and my attempt ended up being a mess of lifetimes and rustc complaining about missing trait impls (that were implemented). Thanks to @MiniaczQ for the (much simpler) rwh 0.6 version bump code. Unblocks https://github.com/bevyengine/bevy/pull/9172 and https://github.com/bevyengine/bevy/pull/10812 ~~This might be blocked on cpal and oboe updating their ndk versions to 0.8, as they both currently target ndk 0.7 which uses rwh 0.5.2~~ Tested on android, and everything seems to work correctly (audio properly stops when minimized, and plays when re-focusing the app). --- ## Changelog - `wgpu` has been updated to 0.19! The long awaited arcanization has been merged (for more info, see https://gfx-rs.github.io/2023/11/24/arcanization.html), and Vulkan should now be working again on Intel GPUs. - Targeting WebGPU now requires that you add the new `webgpu` feature (setting the `RUSTFLAGS` environment variable to `--cfg=web_sys_unstable_apis` is still required). This feature currently overrides the `webgl2` feature if you have both enabled (the `webgl2` feature is enabled by default), so it is not recommended to add it as a default feature to libraries without putting it behind a flag that allows library users to opt out of it! In the future we plan on supporting wasm binaries that can target both webgl2 and webgpu now that wgpu added support for doing so (see https://github.com/bevyengine/bevy/issues/11505). - `raw-window-handle` has been updated to version 0.6. ## Migration Guide - `bevy_render::instance_index::get_instance_index()` has been removed as the webgl2 workaround is no longer required as it was fixed upstream in wgpu. The `BASE_INSTANCE_WORKAROUND` shaderdef has also been removed. - WebGPU now requires the new `webgpu` feature to be enabled. The `webgpu` feature currently overrides the `webgl2` feature so you no longer need to disable all default features and re-add them all when targeting `webgpu`, but binaries built with both the `webgpu` and `webgl2` features will only target the webgpu backend, and will only work on browsers that support WebGPU. - Places where you conditionally compiled things for webgl2 need to be updated because of this change, eg: - `#[cfg(any(not(feature = "webgl"), not(target_arch = "wasm32")))]` becomes `#[cfg(any(not(feature = "webgl") ,not(target_arch = "wasm32"), feature = "webgpu"))]` - `#[cfg(all(feature = "webgl", target_arch = "wasm32"))]` becomes `#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]` - `if cfg!(all(feature = "webgl", target_arch = "wasm32"))` becomes `if cfg!(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))` - `create_texture_with_data` now also takes a `TextureDataOrder`. You can probably just set this to `TextureDataOrder::default()` - `TextureFormat`'s `block_size` has been renamed to `block_copy_size` - See the `wgpu` changelog for anything I might've missed: https://github.com/gfx-rs/wgpu/blob/trunk/CHANGELOG.md --------- Co-authored-by: François <mockersf@gmail.com>
2024-01-26 18:14:21 +00:00
features.push("webgpu");
Webgpu support (#8336) # Objective - Support WebGPU - alternative to #5027 that doesn't need any async / await - fixes #8315 - Surprise fix #7318 ## Solution ### For async renderer initialisation - Update the plugin lifecycle: - app builds the plugin - calls `plugin.build` - registers the plugin - app starts the event loop - event loop waits for `ready` of all registered plugins in the same order - returns `true` by default - then call all `finish` then all `cleanup` in the same order as registered - then execute the schedule In the case of the renderer, to avoid anything async: - building the renderer plugin creates a detached task that will send back the initialised renderer through a mutex in a resource - `ready` will wait for the renderer to be present in the resource - `finish` will take that renderer and place it in the expected resources by other plugins - other plugins (that expect the renderer to be available) `finish` are called and they are able to set up their pipelines - `cleanup` is called, only custom one is still for pipeline rendering ### For WebGPU support - update the `build-wasm-example` script to support passing `--api webgpu` that will build the example with WebGPU support - feature for webgl2 was always enabled when building for wasm. it's now in the default feature list and enabled on all platforms, so check for this feature must also check that the target_arch is `wasm32` --- ## Migration Guide - `Plugin::setup` has been renamed `Plugin::cleanup` - `Plugin::finish` has been added, and plugins adding pipelines should do it in this function instead of `Plugin::build` ```rust // Before impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>() .init_resource::<OtherRenderResource>(); } } // After impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<OtherRenderResource>(); } fn finish(&self, app: &mut App) { let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>(); } } ```
2023-05-04 22:07:57 +00:00
}
}
for example in cli.examples {
let sh = Shell::new().unwrap();
Webgpu support (#8336) # Objective - Support WebGPU - alternative to #5027 that doesn't need any async / await - fixes #8315 - Surprise fix #7318 ## Solution ### For async renderer initialisation - Update the plugin lifecycle: - app builds the plugin - calls `plugin.build` - registers the plugin - app starts the event loop - event loop waits for `ready` of all registered plugins in the same order - returns `true` by default - then call all `finish` then all `cleanup` in the same order as registered - then execute the schedule In the case of the renderer, to avoid anything async: - building the renderer plugin creates a detached task that will send back the initialised renderer through a mutex in a resource - `ready` will wait for the renderer to be present in the resource - `finish` will take that renderer and place it in the expected resources by other plugins - other plugins (that expect the renderer to be available) `finish` are called and they are able to set up their pipelines - `cleanup` is called, only custom one is still for pipeline rendering ### For WebGPU support - update the `build-wasm-example` script to support passing `--api webgpu` that will build the example with WebGPU support - feature for webgl2 was always enabled when building for wasm. it's now in the default feature list and enabled on all platforms, so check for this feature must also check that the target_arch is `wasm32` --- ## Migration Guide - `Plugin::setup` has been renamed `Plugin::cleanup` - `Plugin::finish` has been added, and plugins adding pipelines should do it in this function instead of `Plugin::build` ```rust // Before impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>() .init_resource::<OtherRenderResource>(); } } // After impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<OtherRenderResource>(); } fn finish(&self, app: &mut App) { let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>(); } } ```
2023-05-04 22:07:57 +00:00
let features_string = features.join(",");
let mut parameters = vec![];
if !default_features {
parameters.push("--no-default-features");
}
if !features.is_empty() {
parameters.push("--features");
parameters.push(&features_string);
}
let cmd = cmd!(
sh,
"cargo build {parameters...} --profile release --target wasm32-unknown-unknown --example {example}"
Webgpu support (#8336) # Objective - Support WebGPU - alternative to #5027 that doesn't need any async / await - fixes #8315 - Surprise fix #7318 ## Solution ### For async renderer initialisation - Update the plugin lifecycle: - app builds the plugin - calls `plugin.build` - registers the plugin - app starts the event loop - event loop waits for `ready` of all registered plugins in the same order - returns `true` by default - then call all `finish` then all `cleanup` in the same order as registered - then execute the schedule In the case of the renderer, to avoid anything async: - building the renderer plugin creates a detached task that will send back the initialised renderer through a mutex in a resource - `ready` will wait for the renderer to be present in the resource - `finish` will take that renderer and place it in the expected resources by other plugins - other plugins (that expect the renderer to be available) `finish` are called and they are able to set up their pipelines - `cleanup` is called, only custom one is still for pipeline rendering ### For WebGPU support - update the `build-wasm-example` script to support passing `--api webgpu` that will build the example with WebGPU support - feature for webgl2 was always enabled when building for wasm. it's now in the default feature list and enabled on all platforms, so check for this feature must also check that the target_arch is `wasm32` --- ## Migration Guide - `Plugin::setup` has been renamed `Plugin::cleanup` - `Plugin::finish` has been added, and plugins adding pipelines should do it in this function instead of `Plugin::build` ```rust // Before impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>() .init_resource::<OtherRenderResource>(); } } // After impl Plugin for MyPlugin { fn build(&self, app: &mut App) { app.insert_resource::<MyResource> .add_systems(Update, my_system); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<OtherRenderResource>(); } fn finish(&self, app: &mut App) { let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; render_app .init_resource::<RenderResourceNeedingDevice>(); } } ```
2023-05-04 22:07:57 +00:00
);
cmd.run().expect("Error building example");
cmd!(
sh,
"wasm-bindgen --out-dir examples/wasm/target --out-name wasm_example --target web target/wasm32-unknown-unknown/release/examples/{example}.wasm"
)
.run()
.expect("Error creating wasm binding");
if cli.optimize_size {
cmd!(sh, "wasm-opt -Oz --output examples/wasm/target/wasm_example_bg.wasm.optimized examples/wasm/target/wasm_example_bg.wasm")
.run().expect("Failed to optimize for size. Do you have wasm-opt correctly set up?");
}
if cli.test {
let _dir = sh.push_dir(".github/start-wasm-example");
let mut browsers = cli.browsers.clone();
if !browsers.is_empty() {
browsers.insert(0, "--project".to_string());
}
cmd!(sh, "npx playwright test --headed {browsers...}")
.env("SCREENSHOT_PREFIX", format!("screenshot-{example}"))
.run()
.expect("Error running playwright test");
}
}
}