mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-21 22:33:49 +00:00
Revamp Examples to Match Website (#4765)
* Revamp examples to match website * Small fixes * Fix stencil_triangles on resize * Fix * Fix everything
This commit is contained in:
parent
ebcfd25b58
commit
7a37229630
38
.github/workflows/publish.yml
vendored
38
.github/workflows/publish.yml
vendored
@ -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/
|
||||
|
37
Cargo.lock
generated
37
Cargo.lock
generated
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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::<web_sys::HtmlCanvasElement>()
|
||||
.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 }
|
||||
}
|
||||
|
@ -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::<web_sys::HtmlCanvasElement>()
|
||||
.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));
|
||||
}
|
||||
}
|
||||
|
@ -170,10 +170,10 @@ async fn get_data<T: bytemuck::Pod>(
|
||||
);
|
||||
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();
|
||||
}
|
||||
|
@ -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<String> {
|
||||
@ -42,71 +160,70 @@ fn get_example_name() -> Option<String> {
|
||||
}
|
||||
}
|
||||
|
||||
fn print_unknown_example(result: Option<String>) {
|
||||
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<String>) {}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn print_unknown_example(result: Option<String>) {
|
||||
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)();
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -129,10 +129,10 @@ async fn run(_path: Option<String>) {
|
||||
|
||||
// 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();
|
||||
|
@ -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.
|
||||
{
|
||||
|
@ -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,
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 546 KiB |
Binary file not shown.
Before Width: | Height: | Size: 536 KiB |
Binary file not shown.
Before Width: | Height: | Size: 456 KiB |
BIN
examples/src/skybox/screenshot_astc.png
Normal file
BIN
examples/src/skybox/screenshot_astc.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 384 KiB |
BIN
examples/src/skybox/screenshot_bc1.png
Normal file
BIN
examples/src/skybox/screenshot_bc1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 370 KiB |
BIN
examples/src/skybox/screenshot_etc2.png
Normal file
BIN
examples/src/skybox/screenshot_etc2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 316 KiB |
@ -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) {
|
||||
|
@ -141,10 +141,10 @@ async fn run(_path: Option<String>) {
|
||||
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();
|
||||
|
@ -347,11 +347,27 @@ async fn run(event_loop: EventLoop<()>, window: Arc<Window>) {
|
||||
|
||||
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::<web_sys::HtmlCanvasElement>()
|
||||
.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.");
|
||||
|
122
examples/static/index.html
Normal file
122
examples/static/index.html
Normal file
@ -0,0 +1,122 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
|
||||
<style type="text/css">
|
||||
:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0px;
|
||||
background: #fff;
|
||||
font-family: "Calibri", "Arial", sans-serif;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.banner {
|
||||
background: #dee;
|
||||
padding: 0.5em 0;
|
||||
border-bottom: 1px solid #abb;
|
||||
}
|
||||
|
||||
.banner-prefix {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 0.8em;
|
||||
padding: 0;
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
.backend-list-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.backend-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.item-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.example-link {
|
||||
margin-left: 7px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
.backend-name {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.main-canvas {
|
||||
margin: 0;
|
||||
/* This allows the flexbox to grow to max size, this is needed for WebGPU */
|
||||
flex: 1;
|
||||
/* This forces CSS to ignore the width/height of the canvas, this is needed for WebGL */
|
||||
contain: size;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="root">
|
||||
<div class="banner">
|
||||
<div class="banner-prefix">
|
||||
<p>
|
||||
<a href="../index.html">
|
||||
Back to home page
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="backend-list-container">
|
||||
<div class="backend-list">
|
||||
<p class="backend-name">WebGL2</p>
|
||||
<div class="item-list" id="webgl2-list">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="backend-list">
|
||||
<p class="backend-name">WebGPU</p>
|
||||
<div class="item-list" id="webgpu-list">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<canvas class="main-canvas" id="canvas"></canvas>
|
||||
</div>
|
||||
<script type="module">
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const backend = params.get("backend");
|
||||
const example = params.get("example");
|
||||
if (backend !== null && example !== null) {
|
||||
import(`./${backend}.js`).then((module) => module.default());
|
||||
} else {
|
||||
window.location.assign(
|
||||
`${window.location.href}?backend=webgl2&example=hello_triangle`
|
||||
);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -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"] }
|
||||
|
||||
|
@ -11,7 +11,7 @@ async fn read_png(path: impl AsRef<Path>, width: u32, height: u32) -> Option<Vec
|
||||
Ok(f) => 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
|
||||
);
|
||||
|
422
xtask/Cargo.lock
generated
422
xtask/Cargo.lock
generated
@ -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",
|
||||
|
@ -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:
|
||||
# <https://github.com/rukai/cargo-run-wasm/pull/37>
|
||||
cargo-run-wasm = { version = "0.3.2", git = "https://github.com/ErichDonGubler/cargo-run-wasm", branch = "expose-args", optional = true }
|
||||
|
||||
[workspace]
|
||||
|
@ -8,6 +8,8 @@ Usage: xtask <COMMAND>
|
||||
|
||||
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<Subcommand> {
|
||||
let subcmd = args
|
||||
.subcommand()
|
||||
|
@ -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!(),
|
||||
}
|
||||
|
97
xtask/src/run_wasm.rs
Normal file
97
xtask/src/run_wasm.rs
Normal file
@ -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(())
|
||||
}
|
33
xtask/src/util.rs
Normal file
33
xtask/src/util.rs
Normal file
@ -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(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user