diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 79cf04d12..06dbac44e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,45 +34,15 @@ jobs: - name: Install wasm-bindgen run: cargo +stable install wasm-bindgen-cli --version=$WASM_BINDGEN_VERSION - - name: Build WebGPU examples - run: cargo build --release --target wasm32-unknown-unknown - - - name: Generate JS bindings for WebGPU examples - run: | - for i in target/wasm32-unknown-unknown/release/*.wasm; - do - wasm-bindgen --no-typescript --out-dir target/generated-gpu --web "$i"; - done + - name: Build examples + run: cargo xtask run-wasm --no-serve - name: Deploy WebGPU examples uses: JamesIves/github-pages-deploy-action@v4.4.3 if: github.ref == 'refs/heads/trunk' with: token: ${{ secrets.WEB_DEPLOY }} - folder: target/generated-gpu + folder: target/generated repository-name: gfx-rs/wgpu-rs.github.io branch: master - target-folder: examples-gpu/wasm - - - name: Clean the build - run: cargo clean - - - name: Build WebGL examples - run: cargo build --release --target wasm32-unknown-unknown --features webgl - - - name: Generate JS bindings for WebGL examples - run: | - for i in target/wasm32-unknown-unknown/release/*.wasm; - do - wasm-bindgen --no-typescript --out-dir target/generated-gl --web "$i"; - done - - - name: Deploy WebGL examples - uses: JamesIves/github-pages-deploy-action@v4.4.3 - if: github.ref == 'refs/heads/trunk' - with: - token: ${{ secrets.WEB_DEPLOY }} - folder: target/generated-gl - repository-name: gfx-rs/wgpu-rs.github.io - branch: master - target-folder: examples-gl/wasm + target-folder: examples/ diff --git a/Cargo.lock b/Cargo.lock index a5b50e783..37ec39151 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -937,10 +937,11 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "ddsfile" -version = "0.5.2-unstable" -source = "git+https://github.com/SiegeEngine/ddsfile.git?rev=9b597930edc00502391cbb1a39708dadde0fd0ff#9b597930edc00502391cbb1a39708dadde0fd0ff" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479dfe1e6737aa9e96c6ac7b69689dc4c32da8383f2c12744739d76afa8b66c4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.1", "byteorder", "enum-primitive-derive", "num-traits", @@ -1260,12 +1261,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fdeflate" @@ -1445,17 +1443,6 @@ dependencies = [ "futures-util", ] -[[package]] -name = "futures-intrusive" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" -dependencies = [ - "futures-core", - "lock_api", - "parking_lot", -] - [[package]] name = "futures-io" version = "0.3.29" @@ -1464,9 +1451,9 @@ checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-lite" -version = "1.13.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +checksum = "d3831c2651acb5177cbd83943f3d9c8912c5ad03c76afcc0e9511ba568ec5ebb" dependencies = [ "fastrand", "futures-core", @@ -1474,7 +1461,6 @@ dependencies = [ "memchr", "parking", "pin-project-lite", - "waker-fn", ] [[package]] @@ -3760,12 +3746,6 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" -[[package]] -name = "waker-fn" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" - [[package]] name = "walkdir" version = "2.4.0" @@ -4144,7 +4124,6 @@ dependencies = [ "env_logger", "fern", "flume", - "futures-intrusive", "getrandom", "glam", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index 7646acdd2..ebece615e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,14 +77,12 @@ cfg_aliases = "0.1" cfg-if = "1" codespan-reporting = "0.11" ctor = "0.2" -# https://github.com/SiegeEngine/ddsfile/issues/15 (Updated dependencies) -ddsfile = { version = "0.5.2-unstable", git = "https://github.com/SiegeEngine/ddsfile.git", rev = "9b597930edc00502391cbb1a39708dadde0fd0ff" } +ddsfile = "0.5.2" encase = "0.6" env_logger = "0.10" fern = "0.6" flume = "0.11" -futures-lite = "1" -futures-intrusive = "0.5" +futures-lite = "2" rustc-hash = "1.1.0" getrandom = "0.2" glam = "0.24.2" diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 3250db91c..c0d927f32 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -24,9 +24,7 @@ bytemuck.workspace = true cfg-if.workspace = true ddsfile.workspace = true encase = { workspace = true, features = ["glam"] } -env_logger.workspace = true flume.workspace = true -futures-intrusive.workspace = true getrandom.workspace = true glam.workspace = true log.workspace = true @@ -42,13 +40,15 @@ winit.workspace = true [dev-dependencies] wgpu-test.workspace = true +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +env_logger.workspace = true + [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook.workspace = true console_log.workspace = true fern.workspace = true js-sys.workspace = true wasm-bindgen.workspace = true -wasm-bindgen-test.workspace = true wasm-bindgen-futures.workspace = true hal = { workspace = true, optional = true } # We need these features in the framework examples and tests @@ -63,8 +63,7 @@ web-sys = { workspace = true, features = [ "HtmlImageElement", "WebGl2RenderingContext", "CanvasRenderingContext2d", - - # Needed for example display logic - "HtmlStyleElement", - "HtmlHeadElement", ] } + +[target.'cfg(target_arch = "wasm32")'.dev-dependencies] +wasm-bindgen-test.workspace = true diff --git a/examples/src/framework.rs b/examples/src/framework.rs index f618332c9..107031c4d 100644 --- a/examples/src/framework.rs +++ b/examples/src/framework.rs @@ -98,21 +98,22 @@ impl EventLoopWrapper { pub fn new(title: &str) -> Self { let event_loop = EventLoop::new().unwrap(); let mut builder = winit::window::WindowBuilder::new(); - builder = builder.with_title(title); - let window = Arc::new(builder.build(&event_loop).unwrap()); - #[cfg(target_arch = "wasm32")] { - use winit::platform::web::WindowExtWebSys; - let canvas = window.canvas().expect("Couldn't get canvas"); - canvas.style().set_css_text("height: 100%; width: 100%;"); - // On wasm, append the canvas to the document body - web_sys::window() - .and_then(|win| win.document()) - .and_then(|doc| doc.body()) - .and_then(|body| body.append_child(&canvas).ok()) - .expect("couldn't append canvas to document body"); + use wasm_bindgen::JsCast; + use winit::platform::web::WindowBuilderExtWebSys; + let canvas = web_sys::window() + .unwrap() + .document() + .unwrap() + .get_element_by_id("canvas") + .unwrap() + .dyn_into::() + .unwrap(); + builder = builder.with_canvas(Some(canvas)); } + builder = builder.with_title(title); + let window = Arc::new(builder.build(&event_loop).unwrap()); Self { event_loop, window } } diff --git a/examples/src/hello_triangle/mod.rs b/examples/src/hello_triangle/mod.rs index 0b0350700..e810cc1a1 100644 --- a/examples/src/hello_triangle/mod.rs +++ b/examples/src/hello_triangle/mod.rs @@ -150,7 +150,24 @@ async fn run(event_loop: EventLoop<()>, window: Window) { pub fn main() { let event_loop = EventLoop::new().unwrap(); - let window = winit::window::Window::new(&event_loop).unwrap(); + #[allow(unused_mut)] + let mut builder = winit::window::WindowBuilder::new(); + #[cfg(target_arch = "wasm32")] + { + use wasm_bindgen::JsCast; + use winit::platform::web::WindowBuilderExtWebSys; + let canvas = web_sys::window() + .unwrap() + .document() + .unwrap() + .get_element_by_id("canvas") + .unwrap() + .dyn_into::() + .unwrap(); + builder = builder.with_canvas(Some(canvas)); + } + let window = builder.build(&event_loop).unwrap(); + #[cfg(not(target_arch = "wasm32"))] { env_logger::init(); @@ -160,15 +177,6 @@ pub fn main() { { std::panic::set_hook(Box::new(console_error_panic_hook::hook)); console_log::init().expect("could not initialize logger"); - use winit::platform::web::WindowExtWebSys; - let canvas = window.canvas().expect("Couldn't get canvas"); - canvas.style().set_css_text("height: 100%; width: 100%;"); - // On wasm, append the canvas to the document body - web_sys::window() - .and_then(|win| win.document()) - .and_then(|doc| doc.body()) - .and_then(|body| body.append_child(&canvas).ok()) - .expect("couldn't append canvas to document body"); wasm_bindgen_futures::spawn_local(run(event_loop, window)); } } diff --git a/examples/src/hello_workgroups/mod.rs b/examples/src/hello_workgroups/mod.rs index c19f4437c..933364a6f 100644 --- a/examples/src/hello_workgroups/mod.rs +++ b/examples/src/hello_workgroups/mod.rs @@ -170,10 +170,10 @@ async fn get_data( ); queue.submit(Some(command_encoder.finish())); let buffer_slice = staging_buffer.slice(..); - let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel(); + let (sender, receiver) = flume::bounded(1); buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap()); device.poll(wgpu::Maintain::Wait); - receiver.receive().await.unwrap().unwrap(); + receiver.recv_async().await.unwrap().unwrap(); output.copy_from_slice(bytemuck::cast_slice(&buffer_slice.get_mapped_range()[..])); staging_buffer.unmap(); } diff --git a/examples/src/main.rs b/examples/src/main.rs index ec863827a..948cfd494 100644 --- a/examples/src/main.rs +++ b/examples/src/main.rs @@ -1,33 +1,151 @@ -const EXAMPLES: &[(&str, fn())] = &[ - ("boids", wgpu_examples::boids::main), - ("bunnymark", wgpu_examples::bunnymark::main), - ( - "conservative_raster", - wgpu_examples::conservative_raster::main, - ), - ("cube", wgpu_examples::cube::main), - ("hello", wgpu_examples::hello::main), - ("hello_compute", wgpu_examples::hello_compute::main), - ( - "hello_synchronization", - wgpu_examples::hello_synchronization::main, - ), - ("hello_triangle", wgpu_examples::hello_triangle::main), - ("hello_windows", wgpu_examples::hello_windows::main), - ("hello_workgroups", wgpu_examples::hello_workgroups::main), - ("mipmap", wgpu_examples::mipmap::main), - ("msaa_line", wgpu_examples::msaa_line::main), - ("render_to_texture", wgpu_examples::render_to_texture::main), - ("repeated_compute", wgpu_examples::repeated_compute::main), - ("shadow", wgpu_examples::shadow::main), - ("skybox", wgpu_examples::skybox::main), - ("srgb_blend", wgpu_examples::srgb_blend::main), - ("stencil_triangles", wgpu_examples::stencil_triangles::main), - ("storage_texture", wgpu_examples::storage_texture::main), - ("texture_arrays", wgpu_examples::texture_arrays::main), - ("timestamp_queries", wgpu_examples::timestamp_queries::main), - ("uniform_values", wgpu_examples::uniform_values::main), - ("water", wgpu_examples::water::main), +struct ExampleDesc { + name: &'static str, + function: fn(), + #[allow(dead_code)] // isn't used on native + webgl: bool, + #[allow(dead_code)] // isn't used on native + webgpu: bool, +} + +const EXAMPLES: &[ExampleDesc] = &[ + ExampleDesc { + name: "boids", + function: wgpu_examples::boids::main, + webgl: false, // No compute + webgpu: true, + }, + ExampleDesc { + name: "bunnymark", + function: wgpu_examples::bunnymark::main, + webgl: true, + webgpu: true, + }, + ExampleDesc { + name: "conservative_raster", + function: wgpu_examples::conservative_raster::main, + webgl: false, // No conservative raster + webgpu: false, // No conservative raster + }, + ExampleDesc { + name: "cube", + function: wgpu_examples::cube::main, + webgl: true, + webgpu: true, + }, + ExampleDesc { + name: "hello", + function: wgpu_examples::hello::main, + webgl: false, // No canvas for WebGL + webgpu: true, + }, + ExampleDesc { + name: "hello_compute", + function: wgpu_examples::hello_compute::main, + webgl: false, // No compute + webgpu: true, + }, + ExampleDesc { + name: "hello_synchronization", + function: wgpu_examples::hello_synchronization::main, + webgl: false, // No canvas for WebGL + webgpu: true, + }, + ExampleDesc { + name: "hello_triangle", + function: wgpu_examples::hello_triangle::main, + webgl: true, + webgpu: true, + }, + ExampleDesc { + name: "hello_windows", + function: wgpu_examples::hello_windows::main, + webgl: false, // Native only example + webgpu: false, // Native only example + }, + ExampleDesc { + name: "hello_workgroups", + function: wgpu_examples::hello_workgroups::main, + webgl: false, + webgpu: true, + }, + ExampleDesc { + name: "mipmap", + function: wgpu_examples::mipmap::main, + webgl: true, + webgpu: true, + }, + ExampleDesc { + name: "msaa_line", + function: wgpu_examples::msaa_line::main, + webgl: true, + webgpu: true, + }, + ExampleDesc { + name: "render_to_texture", + function: wgpu_examples::render_to_texture::main, + webgl: false, // No canvas for WebGL + webgpu: true, + }, + ExampleDesc { + name: "repeated_compute", + function: wgpu_examples::repeated_compute::main, + webgl: false, // No compute + webgpu: true, + }, + ExampleDesc { + name: "shadow", + function: wgpu_examples::shadow::main, + webgl: true, + webgpu: true, + }, + ExampleDesc { + name: "skybox", + function: wgpu_examples::skybox::main, + webgl: true, + webgpu: true, + }, + ExampleDesc { + name: "srgb_blend", + function: wgpu_examples::srgb_blend::main, + webgl: true, + webgpu: true, + }, + ExampleDesc { + name: "stencil_triangles", + function: wgpu_examples::stencil_triangles::main, + webgl: true, + webgpu: true, + }, + ExampleDesc { + name: "storage_texture", + function: wgpu_examples::storage_texture::main, + webgl: false, // No storage textures + webgpu: true, + }, + ExampleDesc { + name: "texture_arrays", + function: wgpu_examples::texture_arrays::main, + webgl: false, // No texture arrays + webgpu: false, // No texture arrays + }, + ExampleDesc { + name: "timestamp_queries", + function: wgpu_examples::timestamp_queries::main, + webgl: false, // No canvas for WebGL + webgpu: false, // No timestamp queries + }, + ExampleDesc { + name: "uniform_values", + function: wgpu_examples::uniform_values::main, + webgl: false, // No compute + webgpu: true, + }, + ExampleDesc { + name: "water", + function: wgpu_examples::water::main, + webgl: false, // No RODS + webgpu: true, + }, ]; fn get_example_name() -> Option { @@ -42,71 +160,70 @@ fn get_example_name() -> Option { } } -fn print_unknown_example(result: Option) { - cfg_if::cfg_if! { - if #[cfg(target_arch = "wasm32")] { - use wasm_bindgen::JsCast; - use web_sys::HtmlStyleElement; +#[cfg(target_arch = "wasm32")] +fn print_examples() { + // Get the document, header, and body elements. + let document = web_sys::window().unwrap().document().unwrap(); - // Get the document, header, and body elements. - let document = web_sys::window().unwrap().document().unwrap(); - let head = document.head().unwrap(); - let body = document.body().unwrap(); + for backend in ["webgl2", "webgpu"] { + let ul = document + .get_element_by_id(&format!("{backend}-list")) + .unwrap(); - // Add a basic style sheet to center the text and remove some margin. - let style_sheet: HtmlStyleElement = document.create_element("style").unwrap().dyn_into().unwrap(); - style_sheet.set_inner_text("div { text-align: center; } p { margin: 4px }"); - head.append_child(&style_sheet).unwrap(); - - // A div to provide a container and some padding. - let div = document.create_element("div").unwrap(); - body.append_child(&div).unwrap(); - - let user_message = if let Some(example) = result { - format!("Unknown example: {example}. Please choose an example!") - } else { - String::from("Please choose an example!") - }; - - // A header to display the message to the user. - let header = document.create_element("h1").unwrap(); - header.set_text_content(Some(&user_message)); - div.append_child(&header).unwrap(); - - // Write a link for each example, wrapped in a paragraph. - for (name, _) in EXAMPLES { - let paragraph = document.create_element("p").unwrap(); - let link = document.create_element("a").unwrap(); - link.set_text_content(Some(name)); - link.set_attribute("href", &format!("?example={name}")).unwrap(); - paragraph.append_child(&link).unwrap(); - div.append_child(¶graph).unwrap(); + for example in EXAMPLES { + if backend == "webgl2" && !example.webgl { + continue; } - } else { - if let Some(example) = result { - println!("Unknown example: {}", example); - } else { - println!("Please specify an example as the first argument!"); + if backend == "webgpu" && !example.webgpu { + continue; } - println!("\nAvailable Examples:"); - for (name, _) in EXAMPLES { - println!("\t{name}"); - } + let link = document.create_element("a").unwrap(); + link.set_text_content(Some(example.name)); + link.set_attribute( + "href", + &format!("?backend={backend}&example={}", example.name), + ) + .unwrap(); + link.set_class_name("example-link"); + + let item = document.create_element("div").unwrap(); + item.append_child(&link).unwrap(); + ul.append_child(&item).unwrap(); } } } +#[cfg(target_arch = "wasm32")] +fn print_unknown_example(_result: Option) {} + +#[cfg(not(target_arch = "wasm32"))] +fn print_unknown_example(result: Option) { + if let Some(example) = result { + println!("Unknown example: {}", example); + } else { + println!("Please specify an example as the first argument!"); + } + + println!("\nAvailable Examples:"); + for examples in EXAMPLES { + println!("\t{}", examples.name); + } +} + fn main() { + #[cfg(target_arch = "wasm32")] + print_examples(); + let Some(example) = get_example_name() else { print_unknown_example(None); return; }; - let Some((_, function)) = EXAMPLES.iter().find(|(name, _)| *name == example) else { + let Some(found) = EXAMPLES.iter().find(|e| e.name == example) else { print_unknown_example(Some(example)); return; }; - function(); + (found.function)(); } diff --git a/examples/src/mipmap/mod.rs b/examples/src/mipmap/mod.rs index 68d04d670..c6dc7fa25 100644 --- a/examples/src/mipmap/mod.rs +++ b/examples/src/mipmap/mod.rs @@ -521,7 +521,7 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest #[wgpu_test::gpu_test] static TEST_QUERY: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "mipmap-query", - image_path: "/examples/src/mipmap/screenshot-query.png", + image_path: "/examples/src/mipmap/screenshot_query.png", width: 1024, height: 768, optional_features: QUERY_FEATURES, diff --git a/examples/src/render_to_texture/mod.rs b/examples/src/render_to_texture/mod.rs index 87ab19f6c..820618f6e 100644 --- a/examples/src/render_to_texture/mod.rs +++ b/examples/src/render_to_texture/mod.rs @@ -129,10 +129,10 @@ async fn run(_path: Option) { // Time to get our image. let buffer_slice = output_staging_buffer.slice(..); - let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel(); + let (sender, receiver) = flume::bounded(1); buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap()); device.poll(wgpu::Maintain::Wait); - receiver.receive().await.unwrap().unwrap(); + receiver.recv_async().await.unwrap().unwrap(); log::info!("Output buffer mapped."); { let view = buffer_slice.get_mapped_range(); diff --git a/examples/src/repeated_compute/mod.rs b/examples/src/repeated_compute/mod.rs index 3e22111ad..735ebb958 100644 --- a/examples/src/repeated_compute/mod.rs +++ b/examples/src/repeated_compute/mod.rs @@ -103,7 +103,7 @@ async fn compute(local_buffer: &mut [u32], context: &WgpuContext) { // It may also be worth noting that although on native, the usage of asynchronous // channels is wholely unnecessary, for the sake of portability to WASM (std channels // don't work on WASM,) we'll use async channels that work on both native and WASM. - let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel(); + let (sender, receiver) = flume::bounded(1); buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap()); // In order for the mapping to be completed, one of three things must happen. // One of those can be calling `Device::poll`. This isn't necessary on the web as devices @@ -112,7 +112,7 @@ async fn compute(local_buffer: &mut [u32], context: &WgpuContext) { context.device.poll(wgpu::Maintain::Wait); log::info!("Device polled."); // Now we await the receiving and panic if anything went wrong because we're lazy. - receiver.receive().await.unwrap().unwrap(); + receiver.recv_async().await.unwrap().unwrap(); log::info!("Result received."); // NOW we can call get_mapped_range. { diff --git a/examples/src/skybox/mod.rs b/examples/src/skybox/mod.rs index 3bb969dcf..e3ba07c7d 100644 --- a/examples/src/skybox/mod.rs +++ b/examples/src/skybox/mod.rs @@ -478,7 +478,7 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest #[wgpu_test::gpu_test] static TEST_BCN: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "skybox-bc1", - image_path: "/examples/src/skybox/screenshot-bc1.png", + image_path: "/examples/src/skybox/screenshot_bc1.png", width: 1024, height: 768, optional_features: wgpu::Features::TEXTURE_COMPRESSION_BC, @@ -491,7 +491,7 @@ static TEST_BCN: crate::framework::ExampleTestParams = crate::framework::Example #[wgpu_test::gpu_test] static TEST_ETC2: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "skybox-etc2", - image_path: "/examples/src/skybox/screenshot-etc2.png", + image_path: "/examples/src/skybox/screenshot_etc2.png", width: 1024, height: 768, optional_features: wgpu::Features::TEXTURE_COMPRESSION_ETC2, @@ -504,7 +504,7 @@ static TEST_ETC2: crate::framework::ExampleTestParams = crate::framework::Exampl #[wgpu_test::gpu_test] static TEST_ASTC: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "skybox-astc", - image_path: "/examples/src/skybox/screenshot-astc.png", + image_path: "/examples/src/skybox/screenshot_astc.png", width: 1024, height: 768, optional_features: wgpu::Features::TEXTURE_COMPRESSION_ASTC, diff --git a/examples/src/skybox/screenshot-astc.png b/examples/src/skybox/screenshot-astc.png deleted file mode 100644 index 38515fada..000000000 Binary files a/examples/src/skybox/screenshot-astc.png and /dev/null differ diff --git a/examples/src/skybox/screenshot-bc1.png b/examples/src/skybox/screenshot-bc1.png deleted file mode 100644 index efba0b5c8..000000000 Binary files a/examples/src/skybox/screenshot-bc1.png and /dev/null differ diff --git a/examples/src/skybox/screenshot-etc2.png b/examples/src/skybox/screenshot-etc2.png deleted file mode 100644 index 46ae8d319..000000000 Binary files a/examples/src/skybox/screenshot-etc2.png and /dev/null differ diff --git a/examples/src/skybox/screenshot_astc.png b/examples/src/skybox/screenshot_astc.png new file mode 100644 index 000000000..26e39e3b8 Binary files /dev/null and b/examples/src/skybox/screenshot_astc.png differ diff --git a/examples/src/skybox/screenshot_bc1.png b/examples/src/skybox/screenshot_bc1.png new file mode 100644 index 000000000..e1ca0fd2e Binary files /dev/null and b/examples/src/skybox/screenshot_bc1.png differ diff --git a/examples/src/skybox/screenshot_etc2.png b/examples/src/skybox/screenshot_etc2.png new file mode 100644 index 000000000..4d0374bc3 Binary files /dev/null and b/examples/src/skybox/screenshot_etc2.png differ diff --git a/examples/src/stencil_triangles/mod.rs b/examples/src/stencil_triangles/mod.rs index 6e2ccfa51..bf645d3a3 100644 --- a/examples/src/stencil_triangles/mod.rs +++ b/examples/src/stencil_triangles/mod.rs @@ -170,11 +170,24 @@ impl crate::framework::Example for Example { fn resize( &mut self, - _config: &wgpu::SurfaceConfiguration, - _device: &wgpu::Device, + config: &wgpu::SurfaceConfiguration, + device: &wgpu::Device, _queue: &wgpu::Queue, ) { - // empty + self.stencil_buffer = device.create_texture(&wgpu::TextureDescriptor { + label: Some("Stencil buffer"), + size: wgpu::Extent3d { + width: config.width, + height: config.height, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Stencil8, + view_formats: &[], + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + }); } fn render(&mut self, view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue) { diff --git a/examples/src/storage_texture/mod.rs b/examples/src/storage_texture/mod.rs index bc17b7e55..0fac837e2 100644 --- a/examples/src/storage_texture/mod.rs +++ b/examples/src/storage_texture/mod.rs @@ -141,10 +141,10 @@ async fn run(_path: Option) { queue.submit(Some(command_encoder.finish())); let buffer_slice = output_staging_buffer.slice(..); - let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel(); + let (sender, receiver) = flume::bounded(1); buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap()); device.poll(wgpu::Maintain::Wait); - receiver.receive().await.unwrap().unwrap(); + receiver.recv_async().await.unwrap().unwrap(); log::info!("Output buffer mapped"); { let view = buffer_slice.get_mapped_range(); diff --git a/examples/src/uniform_values/mod.rs b/examples/src/uniform_values/mod.rs index 2d26dc7b3..fdb6a5f85 100644 --- a/examples/src/uniform_values/mod.rs +++ b/examples/src/uniform_values/mod.rs @@ -347,11 +347,27 @@ async fn run(event_loop: EventLoop<()>, window: Arc) { pub fn main() { let event_loop = EventLoop::new().unwrap(); - let window = winit::window::WindowBuilder::new() + #[allow(unused_mut)] + let mut builder = winit::window::WindowBuilder::new() .with_title("Remember: Use U/D to change sample count!") - .with_inner_size(winit::dpi::LogicalSize::new(900, 900)) - .build(&event_loop) - .unwrap(); + .with_inner_size(winit::dpi::LogicalSize::new(900, 900)); + + #[cfg(target_arch = "wasm32")] + { + use wasm_bindgen::JsCast; + use winit::platform::web::WindowBuilderExtWebSys; + let canvas = web_sys::window() + .unwrap() + .document() + .unwrap() + .get_element_by_id("canvas") + .unwrap() + .dyn_into::() + .unwrap(); + builder = builder.with_canvas(Some(canvas)); + } + let window = builder.build(&event_loop).unwrap(); + let window = Arc::new(window); #[cfg(not(target_arch = "wasm32"))] { @@ -362,16 +378,11 @@ pub fn main() { { std::panic::set_hook(Box::new(console_error_panic_hook::hook)); console_log::init().expect("could not initialize logger"); - use winit::platform::web::WindowExtWebSys; - - let canvas = window.canvas().expect("Couldn't get canvas"); - canvas.style().set_css_text("height: 100%; width: 100%;"); let document = web_sys::window() .and_then(|win| win.document()) .expect("Failed to get document."); let body = document.body().unwrap(); - body.append_child(&canvas).unwrap(); let controls_text = document .create_element("p") .expect("Failed to create controls text as element."); diff --git a/examples/static/index.html b/examples/static/index.html new file mode 100644 index 000000000..12a395f21 --- /dev/null +++ b/examples/static/index.html @@ -0,0 +1,122 @@ + + + + + + + + +
+ + +
+ + + + \ No newline at end of file diff --git a/tests/Cargo.toml b/tests/Cargo.toml index f3d8a739b..7c0288388 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -26,7 +26,6 @@ bitflags.workspace = true bytemuck.workspace = true cfg-if.workspace = true ctor.workspace = true -env_logger.workspace = true futures-lite.workspace = true heck.workspace = true libtest-mimic.workspace = true @@ -42,6 +41,7 @@ wgpu.workspace = true wgt = { workspace = true, features = ["replay"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] +env_logger.workspace = true nv-flip.workspace = true parking_lot = { workspace = true, features = ["deadlock_detection"] } diff --git a/tests/src/image.rs b/tests/src/image.rs index 3b075e710..d555332bf 100644 --- a/tests/src/image.rs +++ b/tests/src/image.rs @@ -11,7 +11,7 @@ async fn read_png(path: impl AsRef, width: u32, height: u32) -> Option f, Err(e) => { log::warn!( - "image comparison invalid: file io error when 3comparing {}: {}", + "image comparison invalid: file io error when comparing {}: {}", path.as_ref().display(), e ); diff --git a/xtask/Cargo.lock b/xtask/Cargo.lock index 9ee4a72e9..50b572cd0 100644 --- a/xtask/Cargo.lock +++ b/xtask/Cargo.lock @@ -8,57 +8,6 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" -[[package]] -name = "base64" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -dependencies = [ - "byteorder", - "safemem", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "cargo-run-wasm" -version = "0.3.2" -source = "git+https://github.com/ErichDonGubler/cargo-run-wasm?branch=expose-args#e9b502e50eaccb0f360deb36ccd0f42c6c56f9ba" -dependencies = [ - "devserver_lib", - "pico-args", - "serde_json", - "wasm-bindgen-cli-support", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "devserver_lib" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edf215dbb8cb1409cca7645aaed35f9e39fb0a21855bba1ac48bc0334903bf66" - [[package]] name = "env_logger" version = "0.10.0" @@ -68,61 +17,6 @@ dependencies = [ "log", ] -[[package]] -name = "errno" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "id-arena" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" - -[[package]] -name = "itoa" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" - -[[package]] -name = "leb128" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" - -[[package]] -name = "libc" -version = "0.2.150" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" - -[[package]] -name = "linux-raw-sys" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" - [[package]] name = "log" version = "0.4.20" @@ -135,321 +29,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" -[[package]] -name = "proc-macro2" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustix" -version = "0.38.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" -dependencies = [ - "bitflags 2.4.1", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "ryu" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" - -[[package]] -name = "safemem" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" - -[[package]] -name = "serde" -version = "1.0.190" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.190" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] - -[[package]] -name = "serde_json" -version = "1.0.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall", - "rustix", - "windows-sys", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - -[[package]] -name = "walrus" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb08e48cde54c05f363d984bb54ce374f49e242def9468d2e1b6c2372d291f8" -dependencies = [ - "anyhow", - "id-arena", - "leb128", - "log", - "walrus-macro", - "wasmparser", -] - -[[package]] -name = "walrus-macro" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e5bd22c71e77d60140b0bd5be56155a37e5bd14e24f5f87298040d0cc40d7" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "wasm-bindgen-cli-support" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2252adf46913da7b729caf556b81cedd1335165576e6446d84618e8835d89dd" -dependencies = [ - "anyhow", - "base64", - "log", - "rustc-demangle", - "serde_json", - "tempfile", - "unicode-ident", - "walrus", - "wasm-bindgen-externref-xform", - "wasm-bindgen-multi-value-xform", - "wasm-bindgen-shared", - "wasm-bindgen-threads-xform", - "wasm-bindgen-wasm-conventions", - "wasm-bindgen-wasm-interpreter", -] - -[[package]] -name = "wasm-bindgen-externref-xform" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f3b73cf8fcb86da78c6649c74acef205723f57af99b9f549b2609c83fe7815" -dependencies = [ - "anyhow", - "walrus", -] - -[[package]] -name = "wasm-bindgen-multi-value-xform" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "930dd8e8226379aebb7d512f31b9241a3c59a1801452932e5a15bebfd3b708fb" -dependencies = [ - "anyhow", - "walrus", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" - -[[package]] -name = "wasm-bindgen-threads-xform" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759b1e9784f903a7890bcf147aa7c8c529a6318a2db05f88c054194a3e6c6d57" -dependencies = [ - "anyhow", - "walrus", - "wasm-bindgen-wasm-conventions", -] - -[[package]] -name = "wasm-bindgen-wasm-conventions" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc12bc175c837239520b8aa9dcfb68a025fcf56a718a02551a75a972711c816" -dependencies = [ - "anyhow", - "walrus", -] - -[[package]] -name = "wasm-bindgen-wasm-interpreter" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a5510ab88377b4e3160a7e5d90a876d0a1da2d9b9b67495f437246714c0980f" -dependencies = [ - "anyhow", - "log", - "walrus", - "wasm-bindgen-wasm-conventions", -] - -[[package]] -name = "wasmparser" -version = "0.77.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe3d5405e9ea6c1317a656d6e0820912d8b7b3607823a7596117c8f666daf6f" - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "xshell" version = "0.2.5" @@ -470,7 +49,6 @@ name = "xtask" version = "0.1.0" dependencies = [ "anyhow", - "cargo-run-wasm", "env_logger", "log", "pico-args", diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 0c99c35d9..3bbc64c46 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -4,9 +4,6 @@ version = "0.1.0" edition = "2021" publish = false -[features] -run-wasm = ["cargo-run-wasm"] - [dependencies] # The dependencies in this config have no transitive dependencies. anyhow = "1.0.71" @@ -19,10 +16,4 @@ pico-args = { version = "0.5.0", features = [ ] } xshell = "0.2.3" -# Feature: run-wasm - -# Current contents filed as a PR here: -# -cargo-run-wasm = { version = "0.3.2", git = "https://github.com/ErichDonGubler/cargo-run-wasm", branch = "expose-args", optional = true } - [workspace] diff --git a/xtask/src/cli.rs b/xtask/src/cli.rs index 50a79483c..78547268a 100644 --- a/xtask/src/cli.rs +++ b/xtask/src/cli.rs @@ -8,6 +8,8 @@ Usage: xtask Commands: run-wasm + --release Build in release mode + --no-serve Just build the generated files, don't serve them test --llvm-cov Run tests with LLVM code coverage using the llvm-cov tool @@ -49,33 +51,6 @@ pub enum Subcommand { } impl Subcommand { - /// Returns the name of the subcommand as a string. - /// - /// Opposite of [`Self::parse`]. - pub fn to_str(&self) -> &'static str { - match self { - Self::RunWasm => "run-wasm", - Self::Test => "test", - } - } - - /// Returns true if all required features are enabled for this subcommand. - pub fn required_features_enabled(&self) -> bool { - match self { - Self::RunWasm => cfg!(feature = "run-wasm"), - Self::Test => true, - } - } - - /// Comma separated list of features required by this subcommand. - pub fn features(&self) -> &'static str { - match self { - Self::RunWasm => "run-wasm", - // We will never ask for the features if required_features_enabled always returns true. - Self::Test => unreachable!(), - } - } - fn parse(args: &mut Arguments) -> anyhow::Result { let subcmd = args .subcommand() diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 01b9aa933..1ff0aa8ef 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,10 +1,9 @@ -use std::process::Command; - -use anyhow::Context; use cli::Args; mod cli; +mod run_wasm; mod test; +mod util; fn main() -> anyhow::Result<()> { env_logger::builder() @@ -15,57 +14,13 @@ fn main() -> anyhow::Result<()> { let args = Args::parse(); - if !args.subcommand.required_features_enabled() { - let features = args.subcommand.features(); - log::info!( - "Required features \"{features}\" are not enabled, recursing with features enabled" - ); - - let subcommand_args = args.command_args.finish(); - let iter = subcommand_args - .iter() - .map(|os| os.as_os_str().to_str().unwrap()); - - let status = Command::new("cargo") - .args(["xtask", "--features", features, args.subcommand.to_str()]) - .args(iter) - .status() - .context("Failed to execute recursive cargo xtask")?; - - if status.success() { - return Ok(()); - } else { - return Err(anyhow::anyhow!("subcommand failed")); - } - } - run(args) } #[allow(unused_mut, unreachable_patterns)] fn run(mut args: Args) -> anyhow::Result<()> { match args.subcommand { - #[cfg(feature = "run-wasm")] - cli::Subcommand::RunWasm => { - log::info!("Running wasm example"); - // Use top-level Cargo.toml instead of xtask/Cargo.toml by default - let manifest_path = args - .command_args - .value_from_str("--manifest-path") - .unwrap_or_else(|_| "../Cargo.toml".to_string()); - let mut arg_vec = args.command_args.finish(); - arg_vec.push("--manifest-path".into()); - arg_vec.push(manifest_path.into()); - let args = pico_args::Arguments::from_vec(arg_vec); - - cargo_run_wasm::run_wasm_with_css_and_args( - "body { margin: 0px; }", - cargo_run_wasm::Args::from_args(args) - .map_err(anyhow::Error::msg) - .context("failed to parse arguments for `cargo-run-wasm`")?, - ); - Ok(()) - } + cli::Subcommand::RunWasm => run_wasm::run_wasm(args.command_args), cli::Subcommand::Test => test::run_tests(args.command_args), _ => unreachable!(), } diff --git a/xtask/src/run_wasm.rs b/xtask/src/run_wasm.rs new file mode 100644 index 000000000..bf175dbd5 --- /dev/null +++ b/xtask/src/run_wasm.rs @@ -0,0 +1,97 @@ +use anyhow::Context; + +use pico_args::Arguments; + +use crate::util::check_all_programs; + +pub(crate) fn run_wasm(mut args: Arguments) -> Result<(), anyhow::Error> { + let no_serve = args.contains("--no-serve"); + let release = args.contains("--release"); + + let programs_needed: &[_] = if no_serve { + &["wasm-bindgen"] + } else { + &["wasm-bindgen", "simple-http-server"] + }; + + check_all_programs(programs_needed)?; + + let release_flag: &[_] = if release { &["--release"] } else { &[] }; + let output_dir = if release { "release" } else { "debug" }; + + let shell = xshell::Shell::new().context("Couldn't create xshell shell")?; + shell.change_dir(String::from(env!("CARGO_MANIFEST_DIR")) + "/.."); + + log::info!("building webgpu examples"); + + let cargo_args = args.finish(); + + xshell::cmd!( + shell, + "cargo build --target wasm32-unknown-unknown --bin wgpu-examples {release_flag...}" + ) + .args(&cargo_args) + .quiet() + .run() + .context("Failed to build webgpu examples for wasm")?; + + log::info!("running wasm-bindgen on webgpu examples"); + + xshell::cmd!( + shell, + "wasm-bindgen target/wasm32-unknown-unknown/{output_dir}/wgpu-examples.wasm --target web --no-typescript --out-dir target/generated --out-name webgpu" + ) + .quiet() + .run() + .context("Failed to run wasm-bindgen")?; + + log::info!("building webgl examples"); + + xshell::cmd!( + shell, + "cargo build --target wasm32-unknown-unknown --bin wgpu-examples --features webgl {release_flag...}" + ) + .args(&cargo_args) + .quiet() + .run() + .context("Failed to build webgl examples for wasm")?; + + log::info!("running wasm-bindgen on webgl examples"); + + xshell::cmd!( + shell, + "wasm-bindgen target/wasm32-unknown-unknown/{output_dir}/wgpu-examples.wasm --target web --no-typescript --out-dir target/generated --out-name webgl2" + ) + .quiet() + .run() + .context("Failed to run wasm-bindgen")?; + + let static_files = shell + .read_dir("examples/static") + .context("Failed to enumerate static files")?; + + for file in static_files { + log::info!( + "copying static file \"{}\"", + file.canonicalize().unwrap().display() + ); + + shell + .copy_file(&file, "target/generated") + .with_context(|| format!("Failed to copy static file \"{}\"", file.display()))?; + } + + if !no_serve { + log::info!("serving on port 8000"); + + xshell::cmd!( + shell, + "simple-http-server target/generated -c wasm,html,js -i --coep --coop" + ) + .quiet() + .run() + .context("Failed to simple-http-server")?; + } + + Ok(()) +} diff --git a/xtask/src/util.rs b/xtask/src/util.rs new file mode 100644 index 000000000..3b2456a89 --- /dev/null +++ b/xtask/src/util.rs @@ -0,0 +1,33 @@ +use std::{io, process::Command}; + +pub(crate) fn check_all_programs(programs: &[&str]) -> anyhow::Result<()> { + let mut failed = Vec::new(); + for &program in programs { + let mut cmd = Command::new(program); + cmd.arg("--help"); + let output = cmd.output(); + match output { + Ok(_output) => { + log::info!("Checking for {program} in PATH: ✅"); + } + Err(e) if matches!(e.kind(), io::ErrorKind::NotFound) => { + log::error!("Checking for {program} in PATH: ❌"); + failed.push(program); + } + Err(e) => { + log::error!("Checking for {program} in PATH: ❌"); + panic!("Unknown IO error: {:?}", e); + } + } + } + + if !failed.is_empty() { + log::error!( + "Please install them with: cargo install {}", + failed.join(" ") + ); + anyhow::bail!("Missing programs in PATH"); + } + + Ok(()) +}