Skip to content

Commit

Permalink
Adapting existing tests to be run with wasm in browser
Browse files Browse the repository at this point in the history
  • Loading branch information
haraldreingruber committed Dec 1, 2022
1 parent 4fdb8a0 commit ca95dad
Show file tree
Hide file tree
Showing 15 changed files with 137 additions and 231 deletions.
4 changes: 4 additions & 0 deletions wgpu/tests/buffer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use crate::common::{initialize_test, TestParameters, TestingContext};
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
use wasm_bindgen_test::*;

wasm_bindgen_test_configure!(run_in_browser);

fn test_empty_buffer_range(ctx: &TestingContext, buffer_size: u64, label: &str) {
let status = Arc::new(AtomicBool::new(false));
Expand Down Expand Up @@ -97,6 +100,7 @@ fn test_empty_buffer_range(ctx: &TestingContext, buffer_size: u64, label: &str)
}

#[test]
// #[wasm_bindgen_test] // 'Buffer slices can not be empty', wgpu\src\lib.rs:2402:39
fn empty_buffer() {
initialize_test(
TestParameters::default(),
Expand Down
4 changes: 4 additions & 0 deletions wgpu/tests/buffer_usages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
use crate::common::{fail_if, initialize_test, TestParameters};
use wgt::BufferAddress;
use wasm_bindgen_test::*;

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();
Expand Down
5 changes: 5 additions & 0 deletions wgpu/tests/clear_texture.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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),
Expand All @@ -315,6 +319,7 @@ fn clear_texture_2d_uncompressed() {
}

#[test]
#[wasm_bindgen_test]
fn clear_texture_d32_s8() {
initialize_test(
TestParameters::default()
Expand Down
91 changes: 82 additions & 9 deletions wgpu/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(target_arch = "wasm32")]
use wasm_bindgen::JsCast;
#[cfg(target_arch = "wasm32")]
use web_sys::HtmlCanvasElement;

pub mod image;

const CANVAS_ID: &str = "test-canvas";

async fn initialize_device(
adapter: &Adapter,
features: Features,
Expand Down Expand Up @@ -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();
Expand All @@ -187,18 +187,28 @@ 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;
}

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
Expand All @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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::<web_sys::HtmlCanvasElement>().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<T>(device: &wgpu::Device, callback: impl FnOnce() -> T) -> T {
device.push_error_scope(wgpu::ErrorFilter::Validation);
Expand Down
5 changes: 5 additions & 0 deletions wgpu/tests/device.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 4 additions & 0 deletions wgpu/tests/encoder.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down
8 changes: 8 additions & 0 deletions wgpu/tests/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions wgpu/tests/queue_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions wgpu/tests/resource_descriptor_accessor.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
5 changes: 5 additions & 0 deletions wgpu/tests/resource_error.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion wgpu/tests/root.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// All files containing tests
mod common;

mod buffer;
mod buffer_copy;
mod buffer_usages;
mod clear_texture;
Expand All @@ -16,6 +17,5 @@ mod shader;
mod shader_primitive_index;
mod texture_bounds;
mod vertex_indices;
mod wasm;
mod write_texture;
mod zero_init_texture_after_discard;
11 changes: 0 additions & 11 deletions wgpu/tests/shader.wgsl

This file was deleted.

Loading

0 comments on commit ca95dad

Please sign in to comment.