From 8b08c41f71c9d3836d6dcb76f87b39324d20f0eb Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Sat, 26 Nov 2022 17:31:16 +0100 Subject: [PATCH 01/33] First wasm test experiment --- Cargo.lock | 25 +++++ Cargo.toml | 1 + wgpu/Cargo.toml | 3 +- wgpu/tests/root.rs | 1 + wgpu/tests/shader.wgsl | 11 +++ wgpu/tests/wasm.rs | 208 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 wgpu/tests/shader.wgsl create mode 100644 wgpu/tests/wasm.rs diff --git a/Cargo.lock b/Cargo.lock index 0b0361fe8f..0310850c30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2627,6 +2627,30 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +[[package]] +name = "wasm-bindgen-test" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d2fff962180c3fadf677438054b1db62bee4aa32af26a45388af07d1287e1d" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4683da3dfc016f704c9f82cf401520c4f1cb3ee440f7f52b3d6ac29506a49ca7" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "wasm-bindgen-threads-xform" version = "0.2.83" @@ -2804,6 +2828,7 @@ dependencies = [ "static_assertions", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-bindgen-test", "web-sys", "wgpu-core", "wgpu-hal", diff --git a/Cargo.toml b/Cargo.toml index 50fd3c2d51..f458731671 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,6 +112,7 @@ console_log = "0.2" js-sys = "0.3.60" wasm-bindgen = "0.2.83" wasm-bindgen-futures = "0.4.33" +wasm-bindgen-test = "0.3" # dev-dependency web-sys = "0.3.60" # deno dependencies diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 36272c0fda..b79d10a93f 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -126,7 +126,8 @@ obj.workspace = true pollster.workspace = true png.workspace = true nanorand = { workspace = true, features = ["wyrand"] } -winit.workspace = true # for "halmark" example # for "halmark" example +wasm-bindgen-test.workspace = true +winit.workspace = true # for "halmark" example [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] async-executor.workspace = true diff --git a/wgpu/tests/root.rs b/wgpu/tests/root.rs index 3772e8d0f9..8d5678b3f7 100644 --- a/wgpu/tests/root.rs +++ b/wgpu/tests/root.rs @@ -16,5 +16,6 @@ mod shader; mod shader_primitive_index; mod texture_bounds; mod vertex_indices; +mod wasm; mod write_texture; mod zero_init_texture_after_discard; diff --git a/wgpu/tests/shader.wgsl b/wgpu/tests/shader.wgsl new file mode 100644 index 0000000000..f84ccfe94d --- /dev/null +++ b/wgpu/tests/shader.wgsl @@ -0,0 +1,11 @@ +@vertex +fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4 { + let x = f32(i32(in_vertex_index) - 1); + let y = f32(i32(in_vertex_index & 1u) * 2 - 1); + return vec4(x, y, 0.0, 1.0); +} + +@fragment +fn fs_main() -> @location(0) vec4 { + return vec4(1.0, 0.0, 0.0, 1.0); +} diff --git a/wgpu/tests/wasm.rs b/wgpu/tests/wasm.rs new file mode 100644 index 0000000000..22db96605b --- /dev/null +++ b/wgpu/tests/wasm.rs @@ -0,0 +1,208 @@ +use std::borrow::Cow; + +use wasm_bindgen_test::*; +use winit::{ + event::Event, + event_loop::{ControlFlow, EventLoop}, + platform::web::{EventLoopExtWebSys, WindowExtWebSys}, + window::Window, +}; + +use wasm_bindgen::JsCast; +use web_sys::HtmlCanvasElement; +use wgpu::{Adapter, Device, Instance, Queue, Surface}; + +wasm_bindgen_test_configure!(run_in_browser); + +#[wasm_bindgen_test] +async fn test_triangle_rendering() { + let (window, event_loop, surface, adapter, device, queue): ( + Window, + EventLoop<()>, + Surface, + Adapter, + Device, + Queue, + ) = init().await; + let size = window.inner_size(); + + // Load the shaders from disk + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), + }); + + let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: None, + bind_group_layouts: &[], + push_constant_ranges: &[], + }); + + let swapchain_format = surface.get_supported_formats(&adapter)[0]; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: None, + layout: Some(&pipeline_layout), + vertex: wgpu::VertexState { + module: &shader, + entry_point: "vs_main", + buffers: &[], + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "fs_main", + targets: &[Some(swapchain_format.into())], + }), + primitive: wgpu::PrimitiveState::default(), + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + multiview: None, + }); + + let config = wgpu::SurfaceConfiguration { + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + format: swapchain_format, + width: size.width, + height: size.height, + present_mode: wgpu::PresentMode::Fifo, + alpha_mode: surface.get_supported_alpha_modes(&adapter)[0], + }; + + surface.configure(&device, &config); + + event_loop.spawn(move |event, _, control_flow| { + *control_flow = ControlFlow::Wait; + match event { + Event::RedrawRequested(_) => { + let frame = surface + .get_current_texture() + .expect("Failed to acquire next swap chain texture"); + let view = frame + .texture + .create_view(&wgpu::TextureViewDescriptor::default()); + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), + store: true, + }, + })], + depth_stencil_attachment: None, + }); + rpass.set_pipeline(&render_pipeline); + rpass.draw(0..3, 0..1); + } + + queue.submit(Some(encoder.finish())); + + frame.present(); + + // fetch triangle pixel + let result = read_pixel( + window.canvas(), + (size.width as f32 * 0.5) as i32, + (size.height as f32 * 0.5) as i32, + ); + let red = [255, 0, 0, 255_u8]; + assert_eq!(result, red); + + // fetch background pixel + let result = read_pixel( + window.canvas(), + (size.width as f32 * 0.1) as i32, + (size.height as f32 * 0.9) as i32, + ); + let green = [0, 255, 0, 255_u8]; + assert_eq!(result, green); + + *control_flow = ControlFlow::Exit; + } + _ => (), + } + }); +} + +fn read_pixel(canvas: HtmlCanvasElement, x: i32, y: i32) -> [u8; 4] { + let mut result = [0_u8; 4]; + let context = canvas + .get_context("webgl2") + .unwrap() + .unwrap() + .dyn_into::() + .unwrap(); + context + .read_pixels_with_u8_array_and_dst_offset( + x, + y, + 1, + 1, + web_sys::WebGl2RenderingContext::RGBA, + web_sys::WebGl2RenderingContext::UNSIGNED_BYTE, + &mut result, + 0, + ) + .unwrap(); + result +} + +#[cfg(target_arch = "wasm32")] +async fn init() -> ( + Window, + EventLoop<()>, + Surface, + Adapter, + Device, + Queue, +) { + let event_loop = EventLoop::new(); + let window = winit::window::Window::new(&event_loop).unwrap(); + + std::panic::set_hook(Box::new(console_error_panic_hook::hook)); + console_log::init().expect("could not initialize logger"); + // 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(&web_sys::Element::from(window.canvas())) + .ok() + }) + .expect("couldn't append canvas to document body"); + + let instance = wgpu::Instance::new(wgpu::Backends::GL); + let surface = unsafe { instance.create_surface(&window) }; + let adapter = instance + .request_adapter(&wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::default(), + force_fallback_adapter: false, + // Request an adapter which can render to our surface + compatible_surface: Some(&surface), + }) + .await + .expect("Failed to find an appropriate adapter"); + + // Create the logical device and command queue + let (device, queue) = adapter + .request_device( + &wgpu::DeviceDescriptor { + label: None, + features: wgpu::Features::empty(), + // Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain. + limits: wgpu::Limits::downlevel_webgl2_defaults() + .using_resolution(adapter.limits()), + }, + None, + ) + .await + .expect("Failed to create device"); + + ( + window, event_loop, surface, adapter, device, queue, + ) +} From 9dc1cf6678774c10418a2d2750a6ef24f2c7768c Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Sat, 26 Nov 2022 21:36:10 +0100 Subject: [PATCH 02/33] Extract render_triangle fn --- wgpu/tests/wasm.rs | 61 ++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/wgpu/tests/wasm.rs b/wgpu/tests/wasm.rs index 22db96605b..a43cffc5e6 100644 --- a/wgpu/tests/wasm.rs +++ b/wgpu/tests/wasm.rs @@ -16,6 +16,34 @@ wasm_bindgen_test_configure!(run_in_browser); #[wasm_bindgen_test] async fn test_triangle_rendering() { + render_triangle(|window| { + let size = window.inner_size(); + + // fetch triangle pixel + let result = read_pixel( + window.canvas(), + (size.width as f32 * 0.5) as i32, + (size.height as f32 * 0.5) as i32, + ); + let red = [255, 0, 0, 255_u8]; + assert_eq!(result, red); + + // fetch background pixel + let result = read_pixel( + window.canvas(), + (size.width as f32 * 0.1) as i32, + (size.height as f32 * 0.9) as i32, + ); + let green = [0, 255, 0, 255_u8]; + assert_eq!(result, green); + }) + .await; +} + +async fn render_triangle(assert_rendering_result: F) +where + F: Fn(&Window) + 'static, +{ let (window, event_loop, surface, adapter, device, queue): ( Window, EventLoop<()>, @@ -24,6 +52,7 @@ async fn test_triangle_rendering() { Device, Queue, ) = init().await; + let size = window.inner_size(); // Load the shaders from disk @@ -100,26 +129,9 @@ async fn test_triangle_rendering() { } queue.submit(Some(encoder.finish())); - frame.present(); - // fetch triangle pixel - let result = read_pixel( - window.canvas(), - (size.width as f32 * 0.5) as i32, - (size.height as f32 * 0.5) as i32, - ); - let red = [255, 0, 0, 255_u8]; - assert_eq!(result, red); - - // fetch background pixel - let result = read_pixel( - window.canvas(), - (size.width as f32 * 0.1) as i32, - (size.height as f32 * 0.9) as i32, - ); - let green = [0, 255, 0, 255_u8]; - assert_eq!(result, green); + assert_rendering_result(&window); *control_flow = ControlFlow::Exit; } @@ -136,12 +148,9 @@ fn read_pixel(canvas: HtmlCanvasElement, x: i32, y: i32) -> [u8; 4] { .unwrap() .dyn_into::() .unwrap(); - context - .read_pixels_with_u8_array_and_dst_offset( - x, - y, - 1, - 1, + + context.read_pixels_with_u8_array_and_dst_offset( + x, y, 1, 1, web_sys::WebGl2RenderingContext::RGBA, web_sys::WebGl2RenderingContext::UNSIGNED_BYTE, &mut result, @@ -202,7 +211,5 @@ async fn init() -> ( .await .expect("Failed to create device"); - ( - window, event_loop, surface, adapter, device, queue, - ) + (window, event_loop, surface, adapter, device, queue) } From 444c45721d0f0af2de88f9887e9c564da7c9a766 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Sat, 26 Nov 2022 21:40:43 +0100 Subject: [PATCH 03/33] Add wasm-pack test to GH ci.yml --- .github/workflows/ci.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec707a12a6..4ffd202020 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -161,6 +161,28 @@ jobs: # build docs cargo doc --target ${{ matrix.target }} -p wgpu -p wgpu-core -p wgpu-info -p player --all-features --no-deps + wasm-test: + name: Test Wasm + runs-on: ubuntu-latest + steps: + - name: checkout repo + uses: actions/checkout@v3 + + - name: install rust stable + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + override: true + + - name: install wasm-pack + uses: jetli/wasm-pack-action@v0.4.0 + + - name: execute tests + run: | + cd wgpu + wasm-pack test --headless --chrome --features webgl + gpu-test: strategy: fail-fast: false From 86b4382b6b49c0143adebc713603476a2ced4eb9 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Sat, 26 Nov 2022 21:57:25 +0100 Subject: [PATCH 04/33] Fix broken (non-wasm) test --- wgpu/tests/wasm.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wgpu/tests/wasm.rs b/wgpu/tests/wasm.rs index a43cffc5e6..eb8e57e8bb 100644 --- a/wgpu/tests/wasm.rs +++ b/wgpu/tests/wasm.rs @@ -1,3 +1,5 @@ +#![cfg(target_arch = "wasm32")] + use std::borrow::Cow; use wasm_bindgen_test::*; @@ -10,7 +12,7 @@ use winit::{ use wasm_bindgen::JsCast; use web_sys::HtmlCanvasElement; -use wgpu::{Adapter, Device, Instance, Queue, Surface}; +use wgpu::{Adapter, Device, Queue, Surface}; wasm_bindgen_test_configure!(run_in_browser); @@ -160,7 +162,6 @@ fn read_pixel(canvas: HtmlCanvasElement, x: i32, y: i32) -> [u8; 4] { result } -#[cfg(target_arch = "wasm32")] async fn init() -> ( Window, EventLoop<()>, From 26304b10a3e3d20acaf1a188969b3008a8ee0efa Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Sat, 26 Nov 2022 22:19:56 +0100 Subject: [PATCH 05/33] Fix fmt --- wgpu/tests/wasm.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/wgpu/tests/wasm.rs b/wgpu/tests/wasm.rs index eb8e57e8bb..0425c3b307 100644 --- a/wgpu/tests/wasm.rs +++ b/wgpu/tests/wasm.rs @@ -151,8 +151,12 @@ fn read_pixel(canvas: HtmlCanvasElement, x: i32, y: i32) -> [u8; 4] { .dyn_into::() .unwrap(); - context.read_pixels_with_u8_array_and_dst_offset( - x, y, 1, 1, + context + .read_pixels_with_u8_array_and_dst_offset( + x, + y, + 1, + 1, web_sys::WebGl2RenderingContext::RGBA, web_sys::WebGl2RenderingContext::UNSIGNED_BYTE, &mut result, @@ -162,14 +166,7 @@ fn read_pixel(canvas: HtmlCanvasElement, x: i32, y: i32) -> [u8; 4] { result } -async fn init() -> ( - Window, - EventLoop<()>, - Surface, - Adapter, - Device, - Queue, -) { +async fn init() -> (Window, EventLoop<()>, Surface, Adapter, Device, Queue) { let event_loop = EventLoop::new(); let window = winit::window::Window::new(&event_loop).unwrap(); From 051e59d55fe00b8d86bd694f8c5fd2fac37d4214 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Sat, 26 Nov 2022 22:17:41 +0100 Subject: [PATCH 06/33] Install wasm-pack from fork with fix from open PR --- .github/workflows/ci.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4ffd202020..acc780beb0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -174,9 +174,14 @@ jobs: toolchain: stable profile: minimal override: true - +# doesn't work for this project because of https://github.com/rustwasm/wasm-pack/issues/1180 +# - name: install wasm-pack +# uses: jetli/wasm-pack-action@v0.4.0 +# +# install from fork until this is merged: https://github.com/rustwasm/wasm-pack/pull/1185 - name: install wasm-pack - uses: jetli/wasm-pack-action@v0.4.0 + run: | + cargo install --git https://github.com/haraldreingruber/wasm-pack wasm-pack - name: execute tests run: | From 242a1a77a238de54be0aaed23dccc8efc34d6270 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Sat, 26 Nov 2022 22:38:01 +0100 Subject: [PATCH 07/33] Fix clippy --- wgpu/Cargo.toml | 5 ++-- wgpu/tests/wasm.rs | 65 ++++++++++++++++++++++------------------------ 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index b79d10a93f..11755a27b4 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -284,12 +284,13 @@ parking_lot.workspace = true [target.'cfg(target_arch = "wasm32")'.dev-dependencies] console_error_panic_hook.workspace = true console_log.workspace = true -# We need these features in the framework examples +# We need these features in the framework examples and tests web-sys = { workspace = true, features = [ "Location", "Blob", "RequestInit", "RequestMode", "Request", - "Response" + "Response", + "WebGl2RenderingContext" ] } diff --git a/wgpu/tests/wasm.rs b/wgpu/tests/wasm.rs index 0425c3b307..ef83b0a488 100644 --- a/wgpu/tests/wasm.rs +++ b/wgpu/tests/wasm.rs @@ -103,41 +103,38 @@ where event_loop.spawn(move |event, _, control_flow| { *control_flow = ControlFlow::Wait; - match event { - Event::RedrawRequested(_) => { - let frame = surface - .get_current_texture() - .expect("Failed to acquire next swap chain texture"); - let view = frame - .texture - .create_view(&wgpu::TextureViewDescriptor::default()); - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - { - let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, - color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view: &view, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), - store: true, - }, - })], - depth_stencil_attachment: None, - }); - rpass.set_pipeline(&render_pipeline); - rpass.draw(0..3, 0..1); - } - - queue.submit(Some(encoder.finish())); - frame.present(); - - assert_rendering_result(&window); - - *control_flow = ControlFlow::Exit; + if let Event::RedrawRequested(_) = event { + let frame = surface + .get_current_texture() + .expect("Failed to acquire next swap chain texture"); + let view = frame + .texture + .create_view(&wgpu::TextureViewDescriptor::default()); + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), + store: true, + }, + })], + depth_stencil_attachment: None, + }); + rpass.set_pipeline(&render_pipeline); + rpass.draw(0..3, 0..1); } - _ => (), + + queue.submit(Some(encoder.finish())); + frame.present(); + + assert_rendering_result(&window); + + *control_flow = ControlFlow::Exit; } }); } From 4fdb8a01aa15fa3e68ac73fb90e5ff8bede47d4d Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Sun, 27 Nov 2022 22:53:18 +0100 Subject: [PATCH 08/33] Remove dependency comment --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f458731671..664a096069 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,7 @@ console_log = "0.2" js-sys = "0.3.60" wasm-bindgen = "0.2.83" wasm-bindgen-futures = "0.4.33" -wasm-bindgen-test = "0.3" # dev-dependency +wasm-bindgen-test = "0.3" web-sys = "0.3.60" # deno dependencies From f0aa87b0dd185159003920f5175c8e74f756e3bf Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Thu, 1 Dec 2022 21:31:35 +0100 Subject: [PATCH 09/33] Adapting existing tests to be run with wasm in browser --- wgpu/tests/buffer_usages.rs | 4 + wgpu/tests/clear_texture.rs | 5 + wgpu/tests/common/mod.rs | 91 +++++++- wgpu/tests/device.rs | 5 + wgpu/tests/encoder.rs | 4 + wgpu/tests/poll.rs | 8 + wgpu/tests/queue_transfer.rs | 4 + wgpu/tests/resource_descriptor_accessor.rs | 4 + wgpu/tests/resource_error.rs | 5 + wgpu/tests/root.rs | 1 - wgpu/tests/shader.wgsl | 11 - wgpu/tests/wasm.rs | 210 ------------------ wgpu/tests/write_texture.rs | 4 + wgpu/tests/zero_init_texture_after_discard.rs | 7 + 14 files changed, 132 insertions(+), 231 deletions(-) delete mode 100644 wgpu/tests/shader.wgsl delete mode 100644 wgpu/tests/wasm.rs diff --git a/wgpu/tests/buffer_usages.rs b/wgpu/tests/buffer_usages.rs index db734c108b..dcd18fddb4 100644 --- a/wgpu/tests/buffer_usages.rs +++ b/wgpu/tests/buffer_usages.rs @@ -1,11 +1,15 @@ //! Tests for buffer usages validation. use crate::common::{fail_if, initialize_test, TestParameters}; +use wasm_bindgen_test::*; use wgt::BufferAddress; +wasm_bindgen_test_configure!(run_in_browser); + const BUFFER_SIZE: BufferAddress = 1234; #[test] +#[wasm_bindgen_test] fn buffer_usage() { fn try_create(enable_mappable_primary_buffers: bool, usages: &[(bool, &[wgpu::BufferUsages])]) { let mut parameters = TestParameters::default(); diff --git a/wgpu/tests/clear_texture.rs b/wgpu/tests/clear_texture.rs index abe86cac43..9a12786bc7 100644 --- a/wgpu/tests/clear_texture.rs +++ b/wgpu/tests/clear_texture.rs @@ -1,6 +1,9 @@ use crate::common::{initialize_test, TestParameters, TestingContext}; +use wasm_bindgen_test::*; use wgpu::util::align_to; +wasm_bindgen_test_configure!(run_in_browser); + static TEXTURE_FORMATS_UNCOMPRESSED: &[wgpu::TextureFormat] = &[ wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Snorm, @@ -304,6 +307,7 @@ fn clear_texture_tests( } #[test] +#[wasm_bindgen_test] fn clear_texture_2d_uncompressed() { initialize_test( TestParameters::default().features(wgpu::Features::CLEAR_TEXTURE), @@ -315,6 +319,7 @@ fn clear_texture_2d_uncompressed() { } #[test] +#[wasm_bindgen_test] fn clear_texture_d32_s8() { initialize_test( TestParameters::default() diff --git a/wgpu/tests/common/mod.rs b/wgpu/tests/common/mod.rs index dedf80f5a3..7f9e3fd204 100644 --- a/wgpu/tests/common/mod.rs +++ b/wgpu/tests/common/mod.rs @@ -5,10 +5,17 @@ use std::panic::{catch_unwind, AssertUnwindSafe}; use wgt::{Backends, DeviceDescriptor, DownlevelCapabilities, Features, Limits}; -use wgpu::{util, Adapter, Device, DownlevelFlags, Instance, Queue}; +use wgpu::{Adapter, Device, DownlevelFlags, Instance, Queue}; + +#[cfg(all(target_arch = "wasm32", feature = "webgl"))] +use wasm_bindgen::JsCast; +#[cfg(all(target_arch = "wasm32", feature = "webgl"))] +use web_sys::HtmlCanvasElement; pub mod image; +const CANVAS_ID: &str = "test-canvas"; + async fn initialize_device( adapter: &Adapter, features: Features, @@ -170,14 +177,7 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te // We don't actually care if it fails let _ = env_logger::try_init(); - let backend_bits = util::backend_bits_from_env().unwrap_or_else(Backends::all); - let instance = Instance::new(backend_bits); - let adapter = pollster::block_on(util::initialize_adapter_from_env_or_default( - &instance, - backend_bits, - None, - )) - .expect("could not find suitable adapter on the system"); + let adapter = initialize_adapter(); let adapter_info = adapter.get_info(); let adapter_lowercase_name = adapter_info.name.to_lowercase(); @@ -187,11 +187,18 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te let missing_features = parameters.required_features - adapter_features; if !missing_features.is_empty() { + #[cfg(all(target_arch = "wasm32", feature = "webgl"))] + delete_html_canvas(); + + // TODO: we probably should use log crate here for logging also to wasm console println!("TEST SKIPPED: MISSING FEATURES {:?}", missing_features); return; } if !parameters.required_limits.check_limits(&adapter_limits) { + #[cfg(all(target_arch = "wasm32", feature = "webgl"))] + delete_html_canvas(); + println!("TEST SKIPPED: LIMIT TOO LOW"); return; } @@ -199,6 +206,9 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te let missing_downlevel_flags = parameters.required_downlevel_properties.flags - adapter_downlevel_capabilities.flags; if !missing_downlevel_flags.is_empty() { + #[cfg(all(target_arch = "wasm32", feature = "webgl"))] + delete_html_canvas(); + println!( "TEST SKIPPED: MISSING DOWNLEVEL FLAGS {:?}", missing_downlevel_flags @@ -209,6 +219,9 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te if adapter_downlevel_capabilities.shader_model < parameters.required_downlevel_properties.shader_model { + #[cfg(all(target_arch = "wasm32", feature = "webgl"))] + delete_html_canvas(); + println!( "TEST SKIPPED: LOW SHADER MODEL {:?}", adapter_downlevel_capabilities.shader_model @@ -273,6 +286,9 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te }); if let Some((reason, true)) = expected_failure_reason { + #[cfg(all(target_arch = "wasm32", feature = "webgl"))] + delete_html_canvas(); + println!("EXPECTED TEST FAILURE SKIPPED: {:?}", reason); return; } @@ -314,6 +330,63 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te } } +#[cfg(not(all(target_arch = "wasm32", feature = "webgl")))] +fn initialize_adapter() -> Adapter { + let backend_bits = wgpu::util::backend_bits_from_env().unwrap_or_else(Backends::all); + let instance = Instance::new(backend_bits); + + pollster::block_on(wgpu::util::initialize_adapter_from_env_or_default( + &instance, + backend_bits, + None, + )) + .expect("could not find suitable adapter on the system") +} + +#[cfg(all(target_arch = "wasm32", feature = "webgl"))] +fn initialize_adapter() -> Adapter { + // On wasm, append a canvas to the document body for initializing the adapter + delete_html_canvas(); // if there is a previous one + let canvas = create_html_canvas(); + + let instance = Instance::new(Backends::GL); + let surface = instance.create_surface_from_canvas(&canvas); + + pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::default(), + force_fallback_adapter: false, + // Request an adapter which can render to our surface + compatible_surface: Some(&surface), + })) + .expect("could not find suitable adapter on the system") +} + +#[cfg(all(target_arch = "wasm32", feature = "webgl"))] +fn create_html_canvas() -> HtmlCanvasElement { + return web_sys::window() + .and_then(|win| win.document()) + .and_then(|doc| { + let body = doc.body().unwrap(); + let canvas = doc.create_element("Canvas").unwrap(); + canvas.set_id(CANVAS_ID); + body.append_child(&canvas).unwrap(); + canvas.dyn_into::().ok() + }) + .expect("couldn't append canvas to document body"); +} + +#[cfg(all(target_arch = "wasm32", feature = "webgl"))] +fn delete_html_canvas() { + web_sys::window() + .and_then(|win| win.document()) + .and_then(|document| { + if let Some(element) = document.get_element_by_id(CANVAS_ID) { + element.remove(); + } + Some(()) + }); +} + // Run some code in an error scope and assert that validation fails. pub fn fail(device: &wgpu::Device, callback: impl FnOnce() -> T) -> T { device.push_error_scope(wgpu::ErrorFilter::Validation); diff --git a/wgpu/tests/device.rs b/wgpu/tests/device.rs index 2763a6a21a..8672716d46 100644 --- a/wgpu/tests/device.rs +++ b/wgpu/tests/device.rs @@ -1,6 +1,11 @@ +use wasm_bindgen_test::*; + use crate::common::{initialize_test, TestParameters}; +wasm_bindgen_test_configure!(run_in_browser); + #[test] +#[wasm_bindgen_test] fn device_initialization() { initialize_test(TestParameters::default(), |_ctx| { // intentionally empty diff --git a/wgpu/tests/encoder.rs b/wgpu/tests/encoder.rs index f722f8e34b..c27db70349 100644 --- a/wgpu/tests/encoder.rs +++ b/wgpu/tests/encoder.rs @@ -1,6 +1,10 @@ use crate::common::{initialize_test, TestParameters}; +use wasm_bindgen_test::*; + +wasm_bindgen_test_configure!(run_in_browser); #[test] +#[wasm_bindgen_test] fn drop_encoder() { initialize_test(TestParameters::default(), |ctx| { let encoder = ctx diff --git a/wgpu/tests/poll.rs b/wgpu/tests/poll.rs index 6113436d0b..8aaa708d1b 100644 --- a/wgpu/tests/poll.rs +++ b/wgpu/tests/poll.rs @@ -7,6 +7,9 @@ use wgpu::{ }; use crate::common::{initialize_test, TestParameters, TestingContext}; +use wasm_bindgen_test::*; + +wasm_bindgen_test_configure!(run_in_browser); fn generate_dummy_work(ctx: &TestingContext) -> CommandBuffer { let buffer = ctx.device.create_buffer(&BufferDescriptor { @@ -53,6 +56,7 @@ fn generate_dummy_work(ctx: &TestingContext) -> CommandBuffer { } #[test] +#[wasm_bindgen_test] fn wait() { initialize_test(TestParameters::default().skip(), |ctx| { let cmd_buf = generate_dummy_work(&ctx); @@ -63,6 +67,7 @@ fn wait() { } #[test] +#[wasm_bindgen_test] fn double_wait() { initialize_test(TestParameters::default().skip(), |ctx| { let cmd_buf = generate_dummy_work(&ctx); @@ -74,6 +79,7 @@ fn double_wait() { } #[test] +#[wasm_bindgen_test] fn wait_on_submission() { initialize_test(TestParameters::default().skip(), |ctx| { let cmd_buf = generate_dummy_work(&ctx); @@ -84,6 +90,7 @@ fn wait_on_submission() { } #[test] +#[wasm_bindgen_test] fn double_wait_on_submission() { initialize_test(TestParameters::default().skip(), |ctx| { let cmd_buf = generate_dummy_work(&ctx); @@ -95,6 +102,7 @@ fn double_wait_on_submission() { } #[test] +#[wasm_bindgen_test] fn wait_out_of_order() { initialize_test(TestParameters::default().skip(), |ctx| { let cmd_buf1 = generate_dummy_work(&ctx); diff --git a/wgpu/tests/queue_transfer.rs b/wgpu/tests/queue_transfer.rs index 7724c291cd..4b3c0f111a 100644 --- a/wgpu/tests/queue_transfer.rs +++ b/wgpu/tests/queue_transfer.rs @@ -3,8 +3,12 @@ use std::num::NonZeroU32; use crate::common::{fail, initialize_test, TestParameters}; +use wasm_bindgen_test::*; + +wasm_bindgen_test_configure!(run_in_browser); #[test] +#[wasm_bindgen_test] fn queue_write_texture_overflow() { initialize_test(TestParameters::default(), |ctx| { let texture = ctx.device.create_texture(&wgpu::TextureDescriptor { diff --git a/wgpu/tests/resource_descriptor_accessor.rs b/wgpu/tests/resource_descriptor_accessor.rs index f43a996a40..051a46706c 100644 --- a/wgpu/tests/resource_descriptor_accessor.rs +++ b/wgpu/tests/resource_descriptor_accessor.rs @@ -1,7 +1,11 @@ use crate::common::{initialize_test, TestParameters}; +use wasm_bindgen_test::*; + +wasm_bindgen_test_configure!(run_in_browser); /// Buffer's size and usage can be read back. #[test] +#[wasm_bindgen_test] fn buffer_size_and_usage() { initialize_test(TestParameters::default(), |ctx| { let buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { diff --git a/wgpu/tests/resource_error.rs b/wgpu/tests/resource_error.rs index 81d50e5800..0631998273 100644 --- a/wgpu/tests/resource_error.rs +++ b/wgpu/tests/resource_error.rs @@ -1,6 +1,10 @@ use crate::common::{fail, initialize_test, valid, TestParameters}; +use wasm_bindgen_test::*; + +wasm_bindgen_test_configure!(run_in_browser); #[test] +#[wasm_bindgen_test] fn bad_buffer() { // Create a buffer with bad parameters and call a few methods. // Validation should fail but there should be not panic. @@ -24,6 +28,7 @@ fn bad_buffer() { } #[test] +#[wasm_bindgen_test] fn bad_texture() { // Create a texture with bad parameters and call a few methods. // Validation should fail but there should be not panic. diff --git a/wgpu/tests/root.rs b/wgpu/tests/root.rs index 8d5678b3f7..3772e8d0f9 100644 --- a/wgpu/tests/root.rs +++ b/wgpu/tests/root.rs @@ -16,6 +16,5 @@ mod shader; mod shader_primitive_index; mod texture_bounds; mod vertex_indices; -mod wasm; mod write_texture; mod zero_init_texture_after_discard; diff --git a/wgpu/tests/shader.wgsl b/wgpu/tests/shader.wgsl deleted file mode 100644 index f84ccfe94d..0000000000 --- a/wgpu/tests/shader.wgsl +++ /dev/null @@ -1,11 +0,0 @@ -@vertex -fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4 { - let x = f32(i32(in_vertex_index) - 1); - let y = f32(i32(in_vertex_index & 1u) * 2 - 1); - return vec4(x, y, 0.0, 1.0); -} - -@fragment -fn fs_main() -> @location(0) vec4 { - return vec4(1.0, 0.0, 0.0, 1.0); -} diff --git a/wgpu/tests/wasm.rs b/wgpu/tests/wasm.rs deleted file mode 100644 index ef83b0a488..0000000000 --- a/wgpu/tests/wasm.rs +++ /dev/null @@ -1,210 +0,0 @@ -#![cfg(target_arch = "wasm32")] - -use std::borrow::Cow; - -use wasm_bindgen_test::*; -use winit::{ - event::Event, - event_loop::{ControlFlow, EventLoop}, - platform::web::{EventLoopExtWebSys, WindowExtWebSys}, - window::Window, -}; - -use wasm_bindgen::JsCast; -use web_sys::HtmlCanvasElement; -use wgpu::{Adapter, Device, Queue, Surface}; - -wasm_bindgen_test_configure!(run_in_browser); - -#[wasm_bindgen_test] -async fn test_triangle_rendering() { - render_triangle(|window| { - let size = window.inner_size(); - - // fetch triangle pixel - let result = read_pixel( - window.canvas(), - (size.width as f32 * 0.5) as i32, - (size.height as f32 * 0.5) as i32, - ); - let red = [255, 0, 0, 255_u8]; - assert_eq!(result, red); - - // fetch background pixel - let result = read_pixel( - window.canvas(), - (size.width as f32 * 0.1) as i32, - (size.height as f32 * 0.9) as i32, - ); - let green = [0, 255, 0, 255_u8]; - assert_eq!(result, green); - }) - .await; -} - -async fn render_triangle(assert_rendering_result: F) -where - F: Fn(&Window) + 'static, -{ - let (window, event_loop, surface, adapter, device, queue): ( - Window, - EventLoop<()>, - Surface, - Adapter, - Device, - Queue, - ) = init().await; - - let size = window.inner_size(); - - // Load the shaders from disk - let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { - label: None, - source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), - }); - - let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - label: None, - bind_group_layouts: &[], - push_constant_ranges: &[], - }); - - let swapchain_format = surface.get_supported_formats(&adapter)[0]; - - let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: None, - layout: Some(&pipeline_layout), - vertex: wgpu::VertexState { - module: &shader, - entry_point: "vs_main", - buffers: &[], - }, - fragment: Some(wgpu::FragmentState { - module: &shader, - entry_point: "fs_main", - targets: &[Some(swapchain_format.into())], - }), - primitive: wgpu::PrimitiveState::default(), - depth_stencil: None, - multisample: wgpu::MultisampleState::default(), - multiview: None, - }); - - let config = wgpu::SurfaceConfiguration { - usage: wgpu::TextureUsages::RENDER_ATTACHMENT, - format: swapchain_format, - width: size.width, - height: size.height, - present_mode: wgpu::PresentMode::Fifo, - alpha_mode: surface.get_supported_alpha_modes(&adapter)[0], - }; - - surface.configure(&device, &config); - - event_loop.spawn(move |event, _, control_flow| { - *control_flow = ControlFlow::Wait; - if let Event::RedrawRequested(_) = event { - let frame = surface - .get_current_texture() - .expect("Failed to acquire next swap chain texture"); - let view = frame - .texture - .create_view(&wgpu::TextureViewDescriptor::default()); - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - { - let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, - color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view: &view, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), - store: true, - }, - })], - depth_stencil_attachment: None, - }); - rpass.set_pipeline(&render_pipeline); - rpass.draw(0..3, 0..1); - } - - queue.submit(Some(encoder.finish())); - frame.present(); - - assert_rendering_result(&window); - - *control_flow = ControlFlow::Exit; - } - }); -} - -fn read_pixel(canvas: HtmlCanvasElement, x: i32, y: i32) -> [u8; 4] { - let mut result = [0_u8; 4]; - let context = canvas - .get_context("webgl2") - .unwrap() - .unwrap() - .dyn_into::() - .unwrap(); - - context - .read_pixels_with_u8_array_and_dst_offset( - x, - y, - 1, - 1, - web_sys::WebGl2RenderingContext::RGBA, - web_sys::WebGl2RenderingContext::UNSIGNED_BYTE, - &mut result, - 0, - ) - .unwrap(); - result -} - -async fn init() -> (Window, EventLoop<()>, Surface, Adapter, Device, Queue) { - let event_loop = EventLoop::new(); - let window = winit::window::Window::new(&event_loop).unwrap(); - - std::panic::set_hook(Box::new(console_error_panic_hook::hook)); - console_log::init().expect("could not initialize logger"); - // 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(&web_sys::Element::from(window.canvas())) - .ok() - }) - .expect("couldn't append canvas to document body"); - - let instance = wgpu::Instance::new(wgpu::Backends::GL); - let surface = unsafe { instance.create_surface(&window) }; - let adapter = instance - .request_adapter(&wgpu::RequestAdapterOptions { - power_preference: wgpu::PowerPreference::default(), - force_fallback_adapter: false, - // Request an adapter which can render to our surface - compatible_surface: Some(&surface), - }) - .await - .expect("Failed to find an appropriate adapter"); - - // Create the logical device and command queue - let (device, queue) = adapter - .request_device( - &wgpu::DeviceDescriptor { - label: None, - features: wgpu::Features::empty(), - // Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain. - limits: wgpu::Limits::downlevel_webgl2_defaults() - .using_resolution(adapter.limits()), - }, - None, - ) - .await - .expect("Failed to create device"); - - (window, event_loop, surface, adapter, device, queue) -} diff --git a/wgpu/tests/write_texture.rs b/wgpu/tests/write_texture.rs index 742e97d818..b13d94960d 100644 --- a/wgpu/tests/write_texture.rs +++ b/wgpu/tests/write_texture.rs @@ -3,8 +3,12 @@ use crate::common::{initialize_test, TestParameters}; use std::num::NonZeroU32; +use wasm_bindgen_test::*; + +wasm_bindgen_test_configure!(run_in_browser); #[test] +#[wasm_bindgen_test] fn write_texture_subset() { let size = 256; let parameters = TestParameters::default().backend_failure(wgpu::Backends::DX12); diff --git a/wgpu/tests/zero_init_texture_after_discard.rs b/wgpu/tests/zero_init_texture_after_discard.rs index 6043d0388f..05a52b9f9a 100644 --- a/wgpu/tests/zero_init_texture_after_discard.rs +++ b/wgpu/tests/zero_init_texture_after_discard.rs @@ -1,9 +1,13 @@ use std::num::NonZeroU32; use crate::common::{initialize_test, TestParameters}; +use wasm_bindgen_test::*; + +wasm_bindgen_test_configure!(run_in_browser); // Checks if discarding a color target resets its init state, causing a zero read of this texture when copied in after submit of the encoder. #[test] +#[wasm_bindgen_test] fn discarding_color_target_resets_texture_init_state_check_visible_on_copy_after_submit() { initialize_test(TestParameters::default(), |ctx| { let (texture, readback_buffer) = @@ -39,6 +43,7 @@ fn discarding_color_target_resets_texture_init_state_check_visible_on_copy_after // Checks if discarding a color target resets its init state, causing a zero read of this texture when copied in the same encoder to a buffer. #[test] +#[wasm_bindgen_test] fn discarding_color_target_resets_texture_init_state_check_visible_on_copy_in_same_encoder() { initialize_test(TestParameters::default(), |ctx| { let (texture, readback_buffer) = @@ -67,6 +72,7 @@ fn discarding_color_target_resets_texture_init_state_check_visible_on_copy_in_sa } #[test] +#[wasm_bindgen_test] #[allow(clippy::single_element_loop)] fn discarding_depth_target_resets_texture_init_state_check_visible_on_copy_in_same_encoder() { initialize_test( @@ -109,6 +115,7 @@ fn discarding_depth_target_resets_texture_init_state_check_visible_on_copy_in_sa } #[test] +#[wasm_bindgen_test] fn discarding_either_depth_or_stencil_aspect() { initialize_test(TestParameters::default(), |ctx| { let (texture, _) = create_white_texture_and_readback_buffer( From 8a3f00fae570311583b6910226d0e36de64e9871 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Thu, 1 Dec 2022 22:14:38 +0100 Subject: [PATCH 10/33] Also run wasm tests for firefox --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index acc780beb0..5d26c6d008 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -183,7 +183,12 @@ jobs: run: | cargo install --git https://github.com/haraldreingruber/wasm-pack wasm-pack - - name: execute tests + - name: execute tests (Firefox) + run: | + cd wgpu + wasm-pack test --headless --firefox --features webgl + + - name: execute tests (Chrome) run: | cd wgpu wasm-pack test --headless --chrome --features webgl From fd91517afe65576cfafb75e739271a84af429309 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Thu, 1 Dec 2022 22:14:48 +0100 Subject: [PATCH 11/33] Fix clippy warnings --- wgpu/tests/common/mod.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/wgpu/tests/common/mod.rs b/wgpu/tests/common/mod.rs index 7f9e3fd204..10c49643ab 100644 --- a/wgpu/tests/common/mod.rs +++ b/wgpu/tests/common/mod.rs @@ -363,7 +363,7 @@ fn initialize_adapter() -> Adapter { #[cfg(all(target_arch = "wasm32", feature = "webgl"))] fn create_html_canvas() -> HtmlCanvasElement { - return web_sys::window() + web_sys::window() .and_then(|win| win.document()) .and_then(|doc| { let body = doc.body().unwrap(); @@ -372,19 +372,16 @@ fn create_html_canvas() -> HtmlCanvasElement { body.append_child(&canvas).unwrap(); canvas.dyn_into::().ok() }) - .expect("couldn't append canvas to document body"); + .expect("couldn't append canvas to document body") } #[cfg(all(target_arch = "wasm32", feature = "webgl"))] fn delete_html_canvas() { - web_sys::window() - .and_then(|win| win.document()) - .and_then(|document| { - if let Some(element) = document.get_element_by_id(CANVAS_ID) { - element.remove(); - } - Some(()) - }); + if let Some(document) = web_sys::window().and_then(|win| win.document()) { + if let Some(element) = document.get_element_by_id(CANVAS_ID) { + element.remove(); + } + }; } // Run some code in an error scope and assert that validation fails. From 7eee9104b29d95c792eda452e1972d481bdb1f9c Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Thu, 1 Dec 2022 22:26:54 +0100 Subject: [PATCH 12/33] Revert "Also run wasm tests for firefox" This reverts commit 8a3f00fae570311583b6910226d0e36de64e9871. --- .github/workflows/ci.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d26c6d008..acc780beb0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -183,12 +183,7 @@ jobs: run: | cargo install --git https://github.com/haraldreingruber/wasm-pack wasm-pack - - name: execute tests (Firefox) - run: | - cd wgpu - wasm-pack test --headless --firefox --features webgl - - - name: execute tests (Chrome) + - name: execute tests run: | cd wgpu wasm-pack test --headless --chrome --features webgl From 6616195dbb0e6eaf1f5618ef6f3c4e515824e315 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Fri, 2 Dec 2022 21:11:07 +0100 Subject: [PATCH 13/33] Only configure wasm-bindgen-test once --- wgpu/tests/buffer_usages.rs | 2 -- wgpu/tests/clear_texture.rs | 2 -- wgpu/tests/device.rs | 2 -- wgpu/tests/encoder.rs | 2 -- wgpu/tests/poll.rs | 2 -- wgpu/tests/queue_transfer.rs | 2 -- wgpu/tests/resource_descriptor_accessor.rs | 2 -- wgpu/tests/resource_error.rs | 2 -- wgpu/tests/root.rs | 4 ++++ wgpu/tests/write_texture.rs | 2 -- wgpu/tests/zero_init_texture_after_discard.rs | 2 -- 11 files changed, 4 insertions(+), 20 deletions(-) diff --git a/wgpu/tests/buffer_usages.rs b/wgpu/tests/buffer_usages.rs index dcd18fddb4..7eb3f0e832 100644 --- a/wgpu/tests/buffer_usages.rs +++ b/wgpu/tests/buffer_usages.rs @@ -4,8 +4,6 @@ use crate::common::{fail_if, initialize_test, TestParameters}; use wasm_bindgen_test::*; use wgt::BufferAddress; -wasm_bindgen_test_configure!(run_in_browser); - const BUFFER_SIZE: BufferAddress = 1234; #[test] diff --git a/wgpu/tests/clear_texture.rs b/wgpu/tests/clear_texture.rs index 9a12786bc7..c714a318a2 100644 --- a/wgpu/tests/clear_texture.rs +++ b/wgpu/tests/clear_texture.rs @@ -2,8 +2,6 @@ use crate::common::{initialize_test, TestParameters, TestingContext}; use wasm_bindgen_test::*; use wgpu::util::align_to; -wasm_bindgen_test_configure!(run_in_browser); - static TEXTURE_FORMATS_UNCOMPRESSED: &[wgpu::TextureFormat] = &[ wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Snorm, diff --git a/wgpu/tests/device.rs b/wgpu/tests/device.rs index 8672716d46..69da6b9f3e 100644 --- a/wgpu/tests/device.rs +++ b/wgpu/tests/device.rs @@ -2,8 +2,6 @@ use wasm_bindgen_test::*; use crate::common::{initialize_test, TestParameters}; -wasm_bindgen_test_configure!(run_in_browser); - #[test] #[wasm_bindgen_test] fn device_initialization() { diff --git a/wgpu/tests/encoder.rs b/wgpu/tests/encoder.rs index c27db70349..119f2cad8d 100644 --- a/wgpu/tests/encoder.rs +++ b/wgpu/tests/encoder.rs @@ -1,8 +1,6 @@ use crate::common::{initialize_test, TestParameters}; use wasm_bindgen_test::*; -wasm_bindgen_test_configure!(run_in_browser); - #[test] #[wasm_bindgen_test] fn drop_encoder() { diff --git a/wgpu/tests/poll.rs b/wgpu/tests/poll.rs index 8aaa708d1b..77cac2a35f 100644 --- a/wgpu/tests/poll.rs +++ b/wgpu/tests/poll.rs @@ -9,8 +9,6 @@ use wgpu::{ use crate::common::{initialize_test, TestParameters, TestingContext}; use wasm_bindgen_test::*; -wasm_bindgen_test_configure!(run_in_browser); - fn generate_dummy_work(ctx: &TestingContext) -> CommandBuffer { let buffer = ctx.device.create_buffer(&BufferDescriptor { label: None, diff --git a/wgpu/tests/queue_transfer.rs b/wgpu/tests/queue_transfer.rs index 4b3c0f111a..90310ea6e7 100644 --- a/wgpu/tests/queue_transfer.rs +++ b/wgpu/tests/queue_transfer.rs @@ -5,8 +5,6 @@ use std::num::NonZeroU32; use crate::common::{fail, initialize_test, TestParameters}; use wasm_bindgen_test::*; -wasm_bindgen_test_configure!(run_in_browser); - #[test] #[wasm_bindgen_test] fn queue_write_texture_overflow() { diff --git a/wgpu/tests/resource_descriptor_accessor.rs b/wgpu/tests/resource_descriptor_accessor.rs index 051a46706c..cbb3aac422 100644 --- a/wgpu/tests/resource_descriptor_accessor.rs +++ b/wgpu/tests/resource_descriptor_accessor.rs @@ -1,8 +1,6 @@ use crate::common::{initialize_test, TestParameters}; use wasm_bindgen_test::*; -wasm_bindgen_test_configure!(run_in_browser); - /// Buffer's size and usage can be read back. #[test] #[wasm_bindgen_test] diff --git a/wgpu/tests/resource_error.rs b/wgpu/tests/resource_error.rs index 0631998273..716c646a7d 100644 --- a/wgpu/tests/resource_error.rs +++ b/wgpu/tests/resource_error.rs @@ -1,8 +1,6 @@ use crate::common::{fail, initialize_test, valid, TestParameters}; use wasm_bindgen_test::*; -wasm_bindgen_test_configure!(run_in_browser); - #[test] #[wasm_bindgen_test] fn bad_buffer() { diff --git a/wgpu/tests/root.rs b/wgpu/tests/root.rs index 3772e8d0f9..053c700744 100644 --- a/wgpu/tests/root.rs +++ b/wgpu/tests/root.rs @@ -1,3 +1,5 @@ +use wasm_bindgen_test::wasm_bindgen_test_configure; + // All files containing tests mod common; @@ -18,3 +20,5 @@ mod texture_bounds; mod vertex_indices; mod write_texture; mod zero_init_texture_after_discard; + +wasm_bindgen_test_configure!(run_in_browser); diff --git a/wgpu/tests/write_texture.rs b/wgpu/tests/write_texture.rs index b13d94960d..9d351ed70c 100644 --- a/wgpu/tests/write_texture.rs +++ b/wgpu/tests/write_texture.rs @@ -5,8 +5,6 @@ use crate::common::{initialize_test, TestParameters}; use std::num::NonZeroU32; use wasm_bindgen_test::*; -wasm_bindgen_test_configure!(run_in_browser); - #[test] #[wasm_bindgen_test] fn write_texture_subset() { diff --git a/wgpu/tests/zero_init_texture_after_discard.rs b/wgpu/tests/zero_init_texture_after_discard.rs index 05a52b9f9a..3c584eb7e4 100644 --- a/wgpu/tests/zero_init_texture_after_discard.rs +++ b/wgpu/tests/zero_init_texture_after_discard.rs @@ -3,8 +3,6 @@ use std::num::NonZeroU32; use crate::common::{initialize_test, TestParameters}; use wasm_bindgen_test::*; -wasm_bindgen_test_configure!(run_in_browser); - // Checks if discarding a color target resets its init state, causing a zero read of this texture when copied in after submit of the encoder. #[test] #[wasm_bindgen_test] From 5d8065e790a9a070d8ae9d1896d2d1083fddb8e7 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Fri, 2 Dec 2022 21:30:25 +0100 Subject: [PATCH 14/33] Rename GH Actions job by @cwfitzgerald Co-authored-by: Connor Fitzgerald --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index acc780beb0..3c20c9ebe1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -162,7 +162,7 @@ jobs: cargo doc --target ${{ matrix.target }} -p wgpu -p wgpu-core -p wgpu-info -p player --all-features --no-deps wasm-test: - name: Test Wasm + name: Test Webassembly runs-on: ubuntu-latest steps: - name: checkout repo From c6d6589984b8d7b02b2dd90090a0c74c518543fc Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Fri, 2 Dec 2022 21:31:52 +0100 Subject: [PATCH 15/33] Comment indentation Co-authored-by: Connor Fitzgerald --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c20c9ebe1..dd660da5fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -174,11 +174,11 @@ jobs: toolchain: stable profile: minimal override: true -# doesn't work for this project because of https://github.com/rustwasm/wasm-pack/issues/1180 -# - name: install wasm-pack -# uses: jetli/wasm-pack-action@v0.4.0 -# -# install from fork until this is merged: https://github.com/rustwasm/wasm-pack/pull/1185 + # doesn't work for this project because of https://github.com/rustwasm/wasm-pack/issues/1180 + # - name: install wasm-pack + # uses: jetli/wasm-pack-action@v0.4.0 + # + # install from fork until this is merged: https://github.com/rustwasm/wasm-pack/pull/1185 - name: install wasm-pack run: | cargo install --git https://github.com/haraldreingruber/wasm-pack wasm-pack From 9b572306667fed501742c426d3706ed168de3302 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Fri, 2 Dec 2022 22:11:12 +0100 Subject: [PATCH 16/33] Unify initalize_adapter() --- wgpu/tests/common/mod.rs | 57 +++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/wgpu/tests/common/mod.rs b/wgpu/tests/common/mod.rs index 10c49643ab..68d143c723 100644 --- a/wgpu/tests/common/mod.rs +++ b/wgpu/tests/common/mod.rs @@ -1,16 +1,14 @@ //! This module contains common test-only code that needs to be shared between the examples and the tests. #![allow(dead_code)] // This module is used in a lot of contexts and only parts of it will be used -use std::panic::{catch_unwind, AssertUnwindSafe}; - -use wgt::{Backends, DeviceDescriptor, DownlevelCapabilities, Features, Limits}; - -use wgpu::{Adapter, Device, DownlevelFlags, Instance, Queue}; +use std::panic::{AssertUnwindSafe, catch_unwind}; #[cfg(all(target_arch = "wasm32", feature = "webgl"))] use wasm_bindgen::JsCast; #[cfg(all(target_arch = "wasm32", feature = "webgl"))] use web_sys::HtmlCanvasElement; +use wgpu::{Adapter, Device, DownlevelFlags, Instance, Queue, Surface}; +use wgt::{Backends, DeviceDescriptor, DownlevelCapabilities, Features, Limits}; pub mod image; @@ -330,37 +328,42 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te } } -#[cfg(not(all(target_arch = "wasm32", feature = "webgl")))] fn initialize_adapter() -> Adapter { - let backend_bits = wgpu::util::backend_bits_from_env().unwrap_or_else(Backends::all); - let instance = Instance::new(backend_bits); + let instance; + let backend_bits; + let mut compatible_surface; + + #[cfg(not(all(target_arch = "wasm32", feature = "webgl")))] + { + backend_bits = wgpu::util::backend_bits_from_env().unwrap_or_else(Backends::all); + instance = Instance::new(backend_bits); + + compatible_surface = None; + } + + #[cfg(all(target_arch = "wasm32", feature = "webgl"))] + { + backend_bits = Backends::GL; + instance = Instance::new(backend_bits); + + // On wasm, append a canvas to the document body for initializing the adapter + delete_html_canvas(); // if there is a previous one + let canvas = create_html_canvas(); + let surface = instance.create_surface_from_canvas(&canvas); + + compatible_surface = Some(surface); + } + + let compatible_surface: Option<&Surface> = compatible_surface.as_ref(); pollster::block_on(wgpu::util::initialize_adapter_from_env_or_default( &instance, backend_bits, - None, + compatible_surface, )) .expect("could not find suitable adapter on the system") } -#[cfg(all(target_arch = "wasm32", feature = "webgl"))] -fn initialize_adapter() -> Adapter { - // On wasm, append a canvas to the document body for initializing the adapter - delete_html_canvas(); // if there is a previous one - let canvas = create_html_canvas(); - - let instance = Instance::new(Backends::GL); - let surface = instance.create_surface_from_canvas(&canvas); - - pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions { - power_preference: wgpu::PowerPreference::default(), - force_fallback_adapter: false, - // Request an adapter which can render to our surface - compatible_surface: Some(&surface), - })) - .expect("could not find suitable adapter on the system") -} - #[cfg(all(target_arch = "wasm32", feature = "webgl"))] fn create_html_canvas() -> HtmlCanvasElement { web_sys::window() From 0da5165bb44cdcc5204831e032f4f3c8c6ebf1b2 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Fri, 2 Dec 2022 22:40:13 +0100 Subject: [PATCH 17/33] Implement SurfaceGuard --- wgpu/tests/common/mod.rs | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/wgpu/tests/common/mod.rs b/wgpu/tests/common/mod.rs index 68d143c723..6fb5d11fa2 100644 --- a/wgpu/tests/common/mod.rs +++ b/wgpu/tests/common/mod.rs @@ -175,7 +175,7 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te // We don't actually care if it fails let _ = env_logger::try_init(); - let adapter = initialize_adapter(); + let (adapter, _) = initialize_adapter(); let adapter_info = adapter.get_info(); let adapter_lowercase_name = adapter_info.name.to_lowercase(); @@ -185,18 +185,12 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te let missing_features = parameters.required_features - adapter_features; if !missing_features.is_empty() { - #[cfg(all(target_arch = "wasm32", feature = "webgl"))] - delete_html_canvas(); - // TODO: we probably should use log crate here for logging also to wasm console println!("TEST SKIPPED: MISSING FEATURES {:?}", missing_features); return; } if !parameters.required_limits.check_limits(&adapter_limits) { - #[cfg(all(target_arch = "wasm32", feature = "webgl"))] - delete_html_canvas(); - println!("TEST SKIPPED: LIMIT TOO LOW"); return; } @@ -204,9 +198,6 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te let missing_downlevel_flags = parameters.required_downlevel_properties.flags - adapter_downlevel_capabilities.flags; if !missing_downlevel_flags.is_empty() { - #[cfg(all(target_arch = "wasm32", feature = "webgl"))] - delete_html_canvas(); - println!( "TEST SKIPPED: MISSING DOWNLEVEL FLAGS {:?}", missing_downlevel_flags @@ -217,9 +208,6 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te if adapter_downlevel_capabilities.shader_model < parameters.required_downlevel_properties.shader_model { - #[cfg(all(target_arch = "wasm32", feature = "webgl"))] - delete_html_canvas(); - println!( "TEST SKIPPED: LOW SHADER MODEL {:?}", adapter_downlevel_capabilities.shader_model @@ -284,9 +272,6 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te }); if let Some((reason, true)) = expected_failure_reason { - #[cfg(all(target_arch = "wasm32", feature = "webgl"))] - delete_html_canvas(); - println!("EXPECTED TEST FAILURE SKIPPED: {:?}", reason); return; } @@ -328,10 +313,10 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te } } -fn initialize_adapter() -> Adapter { +fn initialize_adapter() -> (Adapter, SurfaceGuard) { let instance; let backend_bits; - let mut compatible_surface; + let compatible_surface; #[cfg(not(all(target_arch = "wasm32", feature = "webgl")))] { @@ -347,7 +332,6 @@ fn initialize_adapter() -> Adapter { instance = Instance::new(backend_bits); // On wasm, append a canvas to the document body for initializing the adapter - delete_html_canvas(); // if there is a previous one let canvas = create_html_canvas(); let surface = instance.create_surface_from_canvas(&canvas); @@ -356,12 +340,23 @@ fn initialize_adapter() -> Adapter { } let compatible_surface: Option<&Surface> = compatible_surface.as_ref(); - pollster::block_on(wgpu::util::initialize_adapter_from_env_or_default( + let adapter = pollster::block_on(wgpu::util::initialize_adapter_from_env_or_default( &instance, backend_bits, compatible_surface, )) - .expect("could not find suitable adapter on the system") + .expect("could not find suitable adapter on the system"); + + (adapter, SurfaceGuard) +} + +struct SurfaceGuard; + +#[cfg(all(target_arch = "wasm32", feature = "webgl"))] +impl Drop for SurfaceGuard { + fn drop(&mut self) { + delete_html_canvas(); + } } #[cfg(all(target_arch = "wasm32", feature = "webgl"))] From 553cca27d57d86e685fdb84435c8dc53a733dbcf Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Fri, 2 Dec 2022 23:04:59 +0100 Subject: [PATCH 18/33] Use log instead of println... ...so it is visible in the browser as well. --- wgpu/tests/common/mod.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/wgpu/tests/common/mod.rs b/wgpu/tests/common/mod.rs index 6fb5d11fa2..61f38662db 100644 --- a/wgpu/tests/common/mod.rs +++ b/wgpu/tests/common/mod.rs @@ -173,7 +173,10 @@ impl TestParameters { } pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(TestingContext)) { // We don't actually care if it fails + #[cfg(not(target_arch = "wasm32"))] let _ = env_logger::try_init(); + #[cfg(target_arch = "wasm32")] + let _ = console_log::init_with_level(log::Level::Info); let (adapter, _) = initialize_adapter(); @@ -186,19 +189,19 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te let missing_features = parameters.required_features - adapter_features; if !missing_features.is_empty() { // TODO: we probably should use log crate here for logging also to wasm console - println!("TEST SKIPPED: MISSING FEATURES {:?}", missing_features); + log::info!("TEST SKIPPED: MISSING FEATURES {:?}", missing_features); return; } if !parameters.required_limits.check_limits(&adapter_limits) { - println!("TEST SKIPPED: LIMIT TOO LOW"); + log::info!("TEST SKIPPED: LIMIT TOO LOW"); return; } let missing_downlevel_flags = parameters.required_downlevel_properties.flags - adapter_downlevel_capabilities.flags; if !missing_downlevel_flags.is_empty() { - println!( + log::info!( "TEST SKIPPED: MISSING DOWNLEVEL FLAGS {:?}", missing_downlevel_flags ); @@ -208,7 +211,7 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te if adapter_downlevel_capabilities.shader_model < parameters.required_downlevel_properties.shader_model { - println!( + log::info!( "TEST SKIPPED: LOW SHADER MODEL {:?}", adapter_downlevel_capabilities.shader_model ); @@ -272,7 +275,7 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te }); if let Some((reason, true)) = expected_failure_reason { - println!("EXPECTED TEST FAILURE SKIPPED: {:?}", reason); + log::info!("EXPECTED TEST FAILURE SKIPPED: {:?}", reason); return; } @@ -300,7 +303,7 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te // We got the conditions we expected if let Some((expected_reason, _)) = expected_failure_reason { // Print out reason for the failure - println!( + log::info!( "GOT EXPECTED TEST FAILURE DUE TO {}: {:?}", failure_cause, expected_reason ); From 81c0480eb60ad5ab270b2eb28d9e49d20d1979d1 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Fri, 2 Dec 2022 23:43:10 +0100 Subject: [PATCH 19/33] Add more tests --- wgpu/tests/clear_texture.rs | 1 - wgpu/tests/instance.rs | 3 +++ wgpu/tests/shader/numeric_builtins.rs | 2 ++ wgpu/tests/shader/struct_layout.rs | 4 ++++ wgpu/tests/shader_primitive_index/mod.rs | 3 +++ wgpu/tests/vertex_indices/mod.rs | 5 +++++ 6 files changed, 17 insertions(+), 1 deletion(-) diff --git a/wgpu/tests/clear_texture.rs b/wgpu/tests/clear_texture.rs index c714a318a2..294f219cca 100644 --- a/wgpu/tests/clear_texture.rs +++ b/wgpu/tests/clear_texture.rs @@ -305,7 +305,6 @@ fn clear_texture_tests( } #[test] -#[wasm_bindgen_test] fn clear_texture_2d_uncompressed() { initialize_test( TestParameters::default().features(wgpu::Features::CLEAR_TEXTURE), diff --git a/wgpu/tests/instance.rs b/wgpu/tests/instance.rs index c5de0480bd..1ead17c57e 100644 --- a/wgpu/tests/instance.rs +++ b/wgpu/tests/instance.rs @@ -1,4 +1,7 @@ +use wasm_bindgen_test::*; + #[test] +#[wasm_bindgen_test] fn initialize() { let _ = wgpu::Instance::new( wgpu::util::backend_bits_from_env().unwrap_or_else(wgpu::Backends::all), diff --git a/wgpu/tests/shader/numeric_builtins.rs b/wgpu/tests/shader/numeric_builtins.rs index 83b278cfbf..c215054cc3 100644 --- a/wgpu/tests/shader/numeric_builtins.rs +++ b/wgpu/tests/shader/numeric_builtins.rs @@ -1,3 +1,4 @@ +use wasm_bindgen_test::*; use wgpu::{DownlevelFlags, Limits}; use crate::{ @@ -40,6 +41,7 @@ fn create_numeric_builtin_test() -> Vec { } #[test] +#[wasm_bindgen_test] fn numeric_builtins() { initialize_test( TestParameters::default() diff --git a/wgpu/tests/shader/struct_layout.rs b/wgpu/tests/shader/struct_layout.rs index 2250143b5f..c0bba4d1ed 100644 --- a/wgpu/tests/shader/struct_layout.rs +++ b/wgpu/tests/shader/struct_layout.rs @@ -1,5 +1,6 @@ use std::fmt::Write; +use wasm_bindgen_test::*; use wgpu::{Backends, DownlevelFlags, Features, Limits}; use crate::{ @@ -177,6 +178,7 @@ fn create_struct_layout_tests(storage_type: InputStorageType) -> Vec } #[test] +#[wasm_bindgen_test] fn uniform_input() { initialize_test( TestParameters::default() @@ -193,6 +195,7 @@ fn uniform_input() { } #[test] +#[wasm_bindgen_test] fn storage_input() { initialize_test( TestParameters::default() @@ -209,6 +212,7 @@ fn storage_input() { } #[test] +#[wasm_bindgen_test] fn push_constant_input() { initialize_test( TestParameters::default() diff --git a/wgpu/tests/shader_primitive_index/mod.rs b/wgpu/tests/shader_primitive_index/mod.rs index 5e6c6b1b70..f0d771bb26 100644 --- a/wgpu/tests/shader_primitive_index/mod.rs +++ b/wgpu/tests/shader_primitive_index/mod.rs @@ -1,6 +1,7 @@ use crate::common::{initialize_test, TestParameters, TestingContext}; use std::num::NonZeroU32; use wgpu::util::{align_to, DeviceExt}; +use wasm_bindgen_test::*; // // These tests render two triangles to a 2x2 render target. The first triangle @@ -37,6 +38,7 @@ use wgpu::util::{align_to, DeviceExt}; // buffer [3, 4, 5, 0, 1, 2]. This also swaps the resulting pixel colors. // #[test] +#[wasm_bindgen_test] fn draw() { // // +-----+-----+ @@ -61,6 +63,7 @@ fn draw() { } #[test] +#[wasm_bindgen_test] fn draw_indexed() { // // +-----+-----+ diff --git a/wgpu/tests/vertex_indices/mod.rs b/wgpu/tests/vertex_indices/mod.rs index 177b857448..f222bda443 100644 --- a/wgpu/tests/vertex_indices/mod.rs +++ b/wgpu/tests/vertex_indices/mod.rs @@ -1,6 +1,7 @@ use std::num::NonZeroU64; use wgpu::util::DeviceExt; +use wasm_bindgen_test::*; use crate::common::{initialize_test, TestParameters, TestingContext}; @@ -131,6 +132,7 @@ fn pulling_common( } #[test] +#[wasm_bindgen_test] fn draw() { initialize_test(TestParameters::default().test_features_limits(), |ctx| { pulling_common(ctx, &[0, 1, 2, 3, 4, 5], |cmb| { @@ -140,6 +142,7 @@ fn draw() { } #[test] +#[wasm_bindgen_test] fn draw_vertex_offset() { initialize_test( TestParameters::default() @@ -155,6 +158,7 @@ fn draw_vertex_offset() { } #[test] +#[wasm_bindgen_test] fn draw_instanced() { initialize_test(TestParameters::default().test_features_limits(), |ctx| { pulling_common(ctx, &[0, 1, 2, 3, 4, 5], |cmb| { @@ -164,6 +168,7 @@ fn draw_instanced() { } #[test] +#[wasm_bindgen_test] fn draw_instanced_offset() { initialize_test( TestParameters::default() From fd9c5284efbceea9483a4a773e9169f26ae26afd Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Fri, 2 Dec 2022 23:52:25 +0100 Subject: [PATCH 20/33] Fixes build because of merged master changes --- wgpu/tests/common/mod.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/wgpu/tests/common/mod.rs b/wgpu/tests/common/mod.rs index 61f38662db..ad28af7d84 100644 --- a/wgpu/tests/common/mod.rs +++ b/wgpu/tests/common/mod.rs @@ -1,7 +1,7 @@ //! This module contains common test-only code that needs to be shared between the examples and the tests. #![allow(dead_code)] // This module is used in a lot of contexts and only parts of it will be used -use std::panic::{AssertUnwindSafe, catch_unwind}; +use std::panic::{catch_unwind, AssertUnwindSafe}; #[cfg(all(target_arch = "wasm32", feature = "webgl"))] use wasm_bindgen::JsCast; @@ -305,7 +305,8 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te // Print out reason for the failure log::info!( "GOT EXPECTED TEST FAILURE DUE TO {}: {:?}", - failure_cause, expected_reason + failure_cause, + expected_reason ); } } else if let Some((reason, _)) = expected_failure_reason { @@ -337,8 +338,10 @@ fn initialize_adapter() -> (Adapter, SurfaceGuard) { // On wasm, append a canvas to the document body for initializing the adapter let canvas = create_html_canvas(); - let surface = instance.create_surface_from_canvas(&canvas); - + let surface = instance + .create_surface_from_canvas(&canvas) + .expect("could not create surface from canvas"); + compatible_surface = Some(surface); } From a56cc2dde1bcf7c7dcbc193290eb3583860ebc43 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Fri, 2 Dec 2022 23:51:38 +0100 Subject: [PATCH 21/33] Cargo fmt --- wgpu/tests/shader_primitive_index/mod.rs | 2 +- wgpu/tests/vertex_indices/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu/tests/shader_primitive_index/mod.rs b/wgpu/tests/shader_primitive_index/mod.rs index f0d771bb26..a7f68936f2 100644 --- a/wgpu/tests/shader_primitive_index/mod.rs +++ b/wgpu/tests/shader_primitive_index/mod.rs @@ -1,7 +1,7 @@ use crate::common::{initialize_test, TestParameters, TestingContext}; use std::num::NonZeroU32; -use wgpu::util::{align_to, DeviceExt}; use wasm_bindgen_test::*; +use wgpu::util::{align_to, DeviceExt}; // // These tests render two triangles to a 2x2 render target. The first triangle diff --git a/wgpu/tests/vertex_indices/mod.rs b/wgpu/tests/vertex_indices/mod.rs index f222bda443..2c739e8b3d 100644 --- a/wgpu/tests/vertex_indices/mod.rs +++ b/wgpu/tests/vertex_indices/mod.rs @@ -1,7 +1,7 @@ use std::num::NonZeroU64; -use wgpu::util::DeviceExt; use wasm_bindgen_test::*; +use wgpu::util::DeviceExt; use crate::common::{initialize_test, TestParameters, TestingContext}; From e54508c99588ce37305ce737bb9aa44bdc35d211 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Fri, 2 Dec 2022 23:59:33 +0100 Subject: [PATCH 22/33] Fix GH action syntax --- .github/workflows/ci.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5714f2b80..89576f56c7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -178,13 +178,12 @@ jobs: toolchain: stable profile: minimal override: true - # doesn't work for this project because of https://github.com/rustwasm/wasm-pack/issues/1180 - # - name: install wasm-pack - # uses: jetli/wasm-pack-action@v0.4.0 - # - # install from fork until this is merged: https://github.com/rustwasm/wasm-pack/pull/1185 - - name: install wasm-pack + + - name: install wasm-pack # install from fork until this is merged: https://github.com/rustwasm/wasm-pack/pull/1185 run: | + # replace with "install wasm-pack action", which doesn't work for this project because of https://github.com/rustwasm/wasm-pack/issues/1180 + # - name: install wasm-pack + # uses: jetli/wasm-pack-action@v0.4.0 cargo install --git https://github.com/haraldreingruber/wasm-pack wasm-pack - name: execute tests From 68b179582adc49e2459dc8405a87a82d59e11992 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Sun, 4 Dec 2022 23:22:27 +0100 Subject: [PATCH 23/33] Use log::info to be also visible in wasm test --- wgpu/tests/clear_texture.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wgpu/tests/clear_texture.rs b/wgpu/tests/clear_texture.rs index 294f219cca..0e8a75f3b0 100644 --- a/wgpu/tests/clear_texture.rs +++ b/wgpu/tests/clear_texture.rs @@ -203,9 +203,11 @@ fn single_texture_clear_test( size: wgpu::Extent3d, dimension: wgpu::TextureDimension, ) { - println!( + log::info!( "clearing texture with {:?}, dimension {:?}, size {:?}", - format, dimension, size + format, + dimension, + size ); let texture = ctx.device.create_texture(&wgpu::TextureDescriptor { From 8140608c5c8aa8539a53817fbc25c6c185196d90 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Tue, 6 Dec 2022 23:33:27 -0500 Subject: [PATCH 24/33] Update .github/workflows/ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 89576f56c7..70848a5466 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -166,7 +166,7 @@ jobs: cargo doc --target ${{ matrix.target }} -p wgpu -p wgpu-core -p wgpu-info -p player --all-features --no-deps wasm-test: - name: Test Webassembly + name: Test WebAssembly runs-on: ubuntu-latest steps: - name: checkout repo From 3b34bcddcc7d856ccbb2e90de0edead1d75dc233 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Thu, 8 Dec 2022 10:49:59 +0100 Subject: [PATCH 25/33] Implement PR feedback --- wgpu/tests/common/mod.rs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/wgpu/tests/common/mod.rs b/wgpu/tests/common/mod.rs index ad28af7d84..e624fc7919 100644 --- a/wgpu/tests/common/mod.rs +++ b/wgpu/tests/common/mod.rs @@ -3,10 +3,6 @@ use std::panic::{catch_unwind, AssertUnwindSafe}; -#[cfg(all(target_arch = "wasm32", feature = "webgl"))] -use wasm_bindgen::JsCast; -#[cfg(all(target_arch = "wasm32", feature = "webgl"))] -use web_sys::HtmlCanvasElement; use wgpu::{Adapter, Device, DownlevelFlags, Instance, Queue, Surface}; use wgt::{Backends, DeviceDescriptor, DownlevelCapabilities, Features, Limits}; @@ -188,7 +184,6 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te let missing_features = parameters.required_features - adapter_features; if !missing_features.is_empty() { - // TODO: we probably should use log crate here for logging also to wasm console log::info!("TEST SKIPPED: MISSING FEATURES {:?}", missing_features); return; } @@ -318,23 +313,16 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te } fn initialize_adapter() -> (Adapter, SurfaceGuard) { - let instance; - let backend_bits; + let backend_bits = wgpu::util::backend_bits_from_env().unwrap_or_else(Backends::all); + let instance = Instance::new(backend_bits); let compatible_surface; #[cfg(not(all(target_arch = "wasm32", feature = "webgl")))] { - backend_bits = wgpu::util::backend_bits_from_env().unwrap_or_else(Backends::all); - instance = Instance::new(backend_bits); - compatible_surface = None; } - #[cfg(all(target_arch = "wasm32", feature = "webgl"))] { - backend_bits = Backends::GL; - instance = Instance::new(backend_bits); - // On wasm, append a canvas to the document body for initializing the adapter let canvas = create_html_canvas(); @@ -366,7 +354,9 @@ impl Drop for SurfaceGuard { } #[cfg(all(target_arch = "wasm32", feature = "webgl"))] -fn create_html_canvas() -> HtmlCanvasElement { +fn create_html_canvas() -> web_sys::HtmlCanvasElement { + use wasm_bindgen::JsCast; + web_sys::window() .and_then(|win| win.document()) .and_then(|doc| { From d79b16d929f372c9ae9a706f01ecbe6af9b222e7 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Thu, 8 Dec 2022 10:54:01 +0100 Subject: [PATCH 26/33] Revert "Revert "Also run wasm tests for firefox"" This reverts commit 7eee9104b29d95c792eda452e1972d481bdb1f9c. --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70848a5466..a6845aaede 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -186,7 +186,12 @@ jobs: # uses: jetli/wasm-pack-action@v0.4.0 cargo install --git https://github.com/haraldreingruber/wasm-pack wasm-pack - - name: execute tests + - name: execute tests (Firefox) + run: | + cd wgpu + wasm-pack test --headless --firefox --features webgl + + - name: execute tests (Chrome) run: | cd wgpu wasm-pack test --headless --chrome --features webgl From 521ff86984e7c76aa732b0e62f53869fa8dfe5d7 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Thu, 8 Dec 2022 11:07:18 +0100 Subject: [PATCH 27/33] Add setup firefox step to CI script --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6845aaede..833aefebee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -186,6 +186,9 @@ jobs: # uses: jetli/wasm-pack-action@v0.4.0 cargo install --git https://github.com/haraldreingruber/wasm-pack wasm-pack + - name: Setup firefox + uses: browser-actions/setup-firefox@latest + - name: execute tests (Firefox) run: | cd wgpu From 7529eb91f5da754eb7a083a6b574feb893873a51 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Thu, 8 Dec 2022 11:16:08 +0100 Subject: [PATCH 28/33] Revert "Add setup firefox step to CI script" This reverts commit 521ff86984e7c76aa732b0e62f53869fa8dfe5d7. --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 833aefebee..a6845aaede 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -186,9 +186,6 @@ jobs: # uses: jetli/wasm-pack-action@v0.4.0 cargo install --git https://github.com/haraldreingruber/wasm-pack wasm-pack - - name: Setup firefox - uses: browser-actions/setup-firefox@latest - - name: execute tests (Firefox) run: | cd wgpu From cf4a05c3adef3fd5fd9f6b4ca339892c230b9154 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Thu, 8 Dec 2022 11:20:01 +0100 Subject: [PATCH 29/33] Test gfx.prefer-mesa-llvmpipe config for Firefox CI tests --- wgpu/webdriver.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 wgpu/webdriver.json diff --git a/wgpu/webdriver.json b/wgpu/webdriver.json new file mode 100644 index 0000000000..aed31b4d0b --- /dev/null +++ b/wgpu/webdriver.json @@ -0,0 +1,13 @@ +{ + "moz:firefoxOptions": { + "prefs": { + "gfx.prefer-mesa-llvmpipe": true + }, + "args": [ + ] + }, + "goog:chromeOptions": { + "args": [ + ] + } +} \ No newline at end of file From dda910a53cd7ac8b54f9bf00e08a2f8d84391ee6 Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Thu, 8 Dec 2022 16:45:28 +0100 Subject: [PATCH 30/33] Revert "Test gfx.prefer-mesa-llvmpipe config for Firefox CI tests" This reverts commit cf4a05c3adef3fd5fd9f6b4ca339892c230b9154. --- wgpu/webdriver.json | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 wgpu/webdriver.json diff --git a/wgpu/webdriver.json b/wgpu/webdriver.json deleted file mode 100644 index aed31b4d0b..0000000000 --- a/wgpu/webdriver.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "moz:firefoxOptions": { - "prefs": { - "gfx.prefer-mesa-llvmpipe": true - }, - "args": [ - ] - }, - "goog:chromeOptions": { - "args": [ - ] - } -} \ No newline at end of file From f4a4e1dc464b0b8b85bb69dc755757dc6a1d807c Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Thu, 8 Dec 2022 16:46:14 +0100 Subject: [PATCH 31/33] Revert "Also run wasm tests for firefox" This reverts commit 8a3f00fae570311583b6910226d0e36de64e9871. --- .github/workflows/ci.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6845aaede..70848a5466 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -186,12 +186,7 @@ jobs: # uses: jetli/wasm-pack-action@v0.4.0 cargo install --git https://github.com/haraldreingruber/wasm-pack wasm-pack - - name: execute tests (Firefox) - run: | - cd wgpu - wasm-pack test --headless --firefox --features webgl - - - name: execute tests (Chrome) + - name: execute tests run: | cd wgpu wasm-pack test --headless --chrome --features webgl From da9eec86ddd7b1d62b424896d08f612ca68a1bfc Mon Sep 17 00:00:00 2001 From: Harald Reingruber Date: Thu, 8 Dec 2022 22:56:20 +0100 Subject: [PATCH 32/33] Fixes test expected to fail for wasm (texture_bounds.rs) --- wgpu/tests/texture_bounds.rs | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/wgpu/tests/texture_bounds.rs b/wgpu/tests/texture_bounds.rs index 2796815198..635dac8480 100644 --- a/wgpu/tests/texture_bounds.rs +++ b/wgpu/tests/texture_bounds.rs @@ -1,30 +1,32 @@ //! Tests for texture copy bounds checks. -use crate::common::{initialize_test, TestParameters}; +use crate::common::{fail_if, initialize_test, TestParameters}; use std::num::NonZeroU32; +use wasm_bindgen_test::*; #[test] +#[wasm_bindgen_test] fn bad_copy_origin() { fn try_origin(origin: wgpu::Origin3d, size: wgpu::Extent3d, should_panic: bool) { - let mut parameters = TestParameters::default(); - if should_panic { - parameters = parameters.failure(); - } + let parameters = TestParameters::default(); initialize_test(parameters, |ctx| { let texture = ctx.device.create_texture(&TEXTURE_DESCRIPTOR); let data = vec![255; BUFFER_SIZE as usize]; - ctx.queue.write_texture( - wgpu::ImageCopyTexture { - texture: &texture, - mip_level: 0, - origin, - aspect: wgpu::TextureAspect::All, - }, - &data, - BUFFER_COPY_LAYOUT, - size, - ); + + fail_if(&ctx.device, should_panic, || { + ctx.queue.write_texture( + wgpu::ImageCopyTexture { + texture: &texture, + mip_level: 0, + origin, + aspect: wgpu::TextureAspect::All, + }, + &data, + BUFFER_COPY_LAYOUT, + size, + ) + }); }); } From a79a3befd728e6a1d7ac9f84ca72fb3c3635999c Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 8 Dec 2022 19:54:57 -0500 Subject: [PATCH 33/33] Add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb07c09bcd..80dedd5c0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -148,6 +148,7 @@ Additionally `Surface::get_default_config` now returns an Option and returns Non - Update the `minimum supported rust version` to 1.64 - Use cargo 1.64 workspace inheritance feature. By @jinleili in [#3107](https://github.com/gfx-rs/wgpu/pull/3107) - Move `ResourceMetadata` into its own module. By @jimblandy in [#3213](https://github.com/gfx-rs/wgpu/pull/3213) +- Add WebAssembly testing infrastructure. By @haraldreingruber in [#3238](https://github.com/gfx-rs/wgpu/pull/3238) #### Vulkan