wasm is building

web
Ben Hansen 3 years ago
parent e683f9de4c
commit 0da913d253

148
Cargo.lock generated

@ -38,9 +38,9 @@ checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
[[package]]
name = "ahash"
version = "0.7.5"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "991984e3fd003e7ba02eb724f87a0f997b78677c46c0e91f8424ad7394c9886a"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
"getrandom",
"once_cell",
@ -227,9 +227,9 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
[[package]]
name = "bumpalo"
version = "3.7.1"
version = "3.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538"
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
[[package]]
name = "bytemuck"
@ -348,12 +348,6 @@ dependencies = [
"libloading 0.7.1",
]
[[package]]
name = "claxon"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bfbf56724aa9eca8afa4fcfadeb479e722935bb2a0900c2d37e0cc477af0688"
[[package]]
name = "cmake"
version = "0.1.46"
@ -440,6 +434,26 @@ dependencies = [
"winit",
]
[[package]]
name = "console_error_panic_hook"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
dependencies = [
"cfg-if 1.0.0",
"wasm-bindgen",
]
[[package]]
name = "console_log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501a375961cef1a0d44767200e66e4a559283097e91d0730b1d75dfb2f8a1494"
dependencies = [
"log",
"web-sys",
]
[[package]]
name = "copyless"
version = "0.1.5"
@ -568,6 +582,7 @@ dependencies = [
"parking_lot",
"stdweb",
"thiserror",
"wasm-bindgen",
"web-sys",
"winapi",
]
@ -856,8 +871,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if 1.0.0",
"js-sys",
"libc",
"wasi",
"wasm-bindgen",
]
[[package]]
@ -1083,9 +1100,9 @@ checksum = "90953f308a79fe6d62a4643e51f848fbfddcd05975a38e69fdf4ab86a7baf7ca"
[[package]]
name = "instant"
version = "0.1.11"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if 1.0.0",
"js-sys",
@ -1168,22 +1185,11 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "lewton"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "777b48df9aaab155475a83a7df3070395ea1ac6902f5cd062b8f2b028075c030"
dependencies = [
"byteorder",
"ogg",
"tinyvec",
]
[[package]]
name = "libc"
version = "0.2.103"
version = "0.2.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce"
[[package]]
name = "libloading"
@ -1306,26 +1312,6 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c64630dcdd71f1a64c435f54885086a0de5d6a12d104d69b165fb7d5286d677"
[[package]]
name = "minimp3"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "985438f75febf74c392071a975a29641b420dd84431135a6e6db721de4b74372"
dependencies = [
"minimp3-sys",
"slice-deque",
"thiserror",
]
[[package]]
name = "minimp3-sys"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e21c73734c69dc95696c9ed8926a2b393171d98b3f5f5935686a26a487ab9b90"
dependencies = [
"cc",
]
[[package]]
name = "miniz_oxide"
version = "0.3.7"
@ -1347,9 +1333,9 @@ dependencies = [
[[package]]
name = "mio"
version = "0.7.13"
version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
dependencies = [
"libc",
"log",
@ -1652,15 +1638,6 @@ dependencies = [
"cc",
]
[[package]]
name = "ogg"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6951b4e8bf21c8193da321bcce9c9dd2e13c858fe078bf9054a288b419ae5d6e"
dependencies = [
"byteorder",
]
[[package]]
name = "once_cell"
version = "1.8.0"
@ -1749,9 +1726,9 @@ checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
[[package]]
name = "pkg-config"
version = "0.3.20"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb"
checksum = "10e2fcbb64ecbe64c8e040a386c3104d384583af58b956d870aaaf229df6e66d"
[[package]]
name = "png"
@ -1778,12 +1755,20 @@ dependencies = [
"anyhow",
"bytemuck",
"cgmath",
"console_error_panic_hook",
"console_log",
"fs_extra",
"getrandom",
"glob",
"log",
"naga",
"pollster",
"rand",
"rayon",
"rodio",
"shaderc",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"wgpu",
"wgpu_glyph",
"winit",
@ -1990,18 +1975,15 @@ version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d98f5e557b61525057e2bc142c8cd7f0e70d75dc32852309bec440e6e046bf9"
dependencies = [
"claxon",
"cpal",
"hound",
"lewton",
"minimp3",
]
[[package]]
name = "ron"
version = "0.6.5"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45005aa836116903a49cf3461474da697cfe66221762c6e95871092009ec86d6"
checksum = "86018df177b1beef6c7c8ef949969c4f7cb9a9344181b92486b23c79995bdaa4"
dependencies = [
"base64",
"bitflags",
@ -2123,17 +2105,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
[[package]]
name = "slice-deque"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31ef6ee280cdefba6d2d0b4b78a84a1c1a3f3a4cec98c2d4231c8bc225de0f25"
dependencies = [
"libc",
"mach",
"winapi",
]
[[package]]
name = "slotmap"
version = "1.0.6"
@ -2267,21 +2238,6 @@ dependencies = [
"weezl",
]
[[package]]
name = "tinyvec"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tobj"
version = "2.0.4"
@ -2294,7 +2250,7 @@ version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "267a53ebc1139c69d3feedc33a381c382b2e3b0c47f44f48679e90c4a69b8dac"
dependencies = [
"ahash 0.7.5",
"ahash 0.7.6",
]
[[package]]
@ -2824,9 +2780,9 @@ dependencies = [
[[package]]
name = "wgpu-core"
version = "0.11.0"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45af76ba5545b61a6904f26cdcf4287329144ae9e12f0c23ec4c9be982d675a6"
checksum = "3bdcbfa4885b32c2b1feb2faeb8b6a76065b752b8f08751b82f994e937687f46"
dependencies = [
"arrayvec",
"bitflags",
@ -2848,9 +2804,9 @@ dependencies = [
[[package]]
name = "wgpu-hal"
version = "0.11.2"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11095a81f4406b1e594dab7dc35d6508409d364e62458f2e5b07b3edc7aca517"
checksum = "0e493835d9edb153d5c8a9d8d016e1811dbe32ddb707a110be1453c7b051d3ec"
dependencies = [
"arrayvec",
"ash",
@ -2991,7 +2947,9 @@ dependencies = [
"raw-window-handle",
"scopeguard",
"smithay-client-toolkit",
"wasm-bindgen",
"wayland-client",
"web-sys",
"winapi",
"x11-dl",
]

@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Adapted from https://github.com/gfx-rs/wgpu/blob/master/run-wasm-example.sh
set -e
cargo build --bin pong --target wasm32-unknown-unknown
mkdir -p target/wasm-examples/pong
wasm-bindgen --target web --out-dir target/wasm-examples/pong target/wasm32-unknown-unknown/debug/pong.wasm
cp index.template.html target/wasm-examples/pong/index.html

@ -6,7 +6,6 @@ edition = "2018"
[dependencies]
winit = "0.25"
shaderc = "0.7"
anyhow = "1.0"
bytemuck = { version = "1.4", features = [ "derive" ] }
cgmath = "0.18"
@ -14,10 +13,27 @@ pollster = "0.2"
wgpu = { version = "0.11", features = ["spirv"]}
wgpu_glyph = "0.15"
rand = "0.8"
rodio = "0.14"
rodio = { version = "0.14", default-features = false, features = ["wav"] }
log = "0.4"
[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.6"
console_log = "0.2.0"
getrandom = { version = "0.2", features = ["js"] }
rodio = { version = "0.14", default-features = false, features = ["wasm-bindgen", "wav"] }
wasm-bindgen = "0.2.76"
wasm-bindgen-futures = "0.4.20"
web-sys = { version = "0.3.53", features = [
"Document",
"Window",
"Element",
]}
winit = { version = "0.25", features = ["web-sys"] }
wgpu = { version = "0.11", features = ["spirv", "webgl"]}
[build-dependencies]
anyhow = "1.0"
fs_extra = "1.2"
glob = "0.3"
shaderc = "0.7"
rayon = "1.4"
naga = { version = "0.7", features = ["glsl-in", "spv-out", "wgsl-out"]}

@ -1,81 +1,97 @@
use anyhow::*;
use fs_extra::copy_items;
use fs_extra::dir::CopyOptions;
use glob::glob;
use std::fs::{read_to_string, write};
use std::path::PathBuf;
use naga::back::wgsl;
use naga::front::glsl::Options;
use naga::front::glsl::Parser;
use rayon::prelude::*;
use std::env;
use std::{fs::read_to_string, path::PathBuf};
struct ShaderData {
src: String,
src_path: PathBuf,
spv_path: PathBuf,
kind: shaderc::ShaderKind,
}
pub fn load_shader(src_path: PathBuf) -> Result<()> {
let extension = src_path
.extension()
.context("File has no extension")?
.to_str()
.context("Extension cannot be converted to &str")?;
let kind = match extension {
"vert" => naga::ShaderStage::Vertex,
"frag" => naga::ShaderStage::Fragment,
"comp" => naga::ShaderStage::Compute,
_ => bail!("Unsupported shader: {}", src_path.display()),
};
let src = read_to_string(src_path.clone())?;
// let spv_path = src_path.with_extension(format!("{}.spv", extension));
let wgsl_path = src_path.with_extension(format!("{}.wgsl", extension));
let mut parser = Parser::default();
let options = Options::from(kind);
let module = match parser.parse(&options, &src) {
Ok(it) => it,
Err(errors) => {
bail!(
"Failed to compile shader: {}\nErrors:\n{:#?}",
src_path.display(),
errors
);
}
};
impl ShaderData {
pub fn load(src_path: PathBuf) -> Result<Self> {
let extension = src_path
.extension()
.context("File has no extension")?
.to_str()
.context("Extension cannot be converted to &str")?;
let kind = match extension {
"vert" => shaderc::ShaderKind::Vertex,
"frag" => shaderc::ShaderKind::Fragment,
"comp" => shaderc::ShaderKind::Compute,
_ => bail!("Unsupported shader: {}", src_path.display()),
};
let info = naga::valid::Validator::new(
naga::valid::ValidationFlags::all(),
naga::valid::Capabilities::empty(),
)
.validate(&module)?;
std::fs::write(wgsl_path, wgsl::write_string(&module, &info)?)?;
let src = read_to_string(src_path.clone())?;
let spv_path = src_path.with_extension(format!("{}.spv", extension));
// let flags = spv::WriterFlags::DEBUG | spv::WriterFlags::ADJUST_COORDINATE_SPACE;
// let options = spv::Options {
// flags,
// ..Default::default()
// };
// let spv = spv::write_vec(&module, &info, &options)?;
// let dis = rspirv::dr::load_words(spv)
// .expect("Unable to disassemble shader")
// .disassemble();
// std::fs::write(spv_path, &spv)?;
Ok(Self {
src,
src_path,
spv_path,
kind,
})
}
Ok(())
}
fn main() -> Result<()> {
// This tells cargo to rerun this script if something in /src/ changes.
println!("cargo:rerun-if-changed=src/*");
// Collect all shaders recursively within /src/
let mut shader_paths = [
glob("./res/**/*.vert")?,
glob("./res/**/*.frag")?,
glob("./res/**/*.comp")?,
];
// UDPATED!
let shader_paths = {
let mut data = Vec::new();
data.extend(glob("./res/**/*.vert")?);
data.extend(glob("./res/**/*.frag")?);
data.extend(glob("./res/**/*.comp")?);
data
};
// This could be parallelized
let shaders = shader_paths
.iter_mut()
.flatten()
.map(|glob_result| ShaderData::load(glob_result?))
// UPDATED!
// This is parallelized
shader_paths
.into_par_iter()
.map(|glob_result| load_shader(glob_result?))
.collect::<Vec<Result<_>>>()
.into_iter()
.collect::<Result<Vec<_>>>()?;
let mut compiler = shaderc::Compiler::new().context("Unable to create shader compiler")?;
// This can't be parallelized. The [shaderc::Compiler] is not
// thread safe. Also, it creates a lot of resources. You could
// spawn multiple processes to handle this, but it would probably
// be better just to only compile shaders that have been changed
// recently.
for shader in shaders {
// This tells cargo to rerun this script if something in /src/ changes.
println!(
"cargo:rerun-if-changed={}",
shader.src_path.as_os_str().to_str().unwrap()
);
// This tells cargo to rerun this script if something in /res/ changes.
println!("cargo:rerun-if-changed=res/*");
let compiled = compiler.compile_into_spirv(
&shader.src,
shader.kind,
shader.src_path.to_str().unwrap(),
"main",
None,
)?;
write(shader.spv_path, compiled.as_binary_u8())?;
}
let out_dir = env::var("OUT_DIR")?;
let mut copy_options = CopyOptions::new();
let mut paths_to_copy = Vec::new();
copy_options.overwrite = true;
paths_to_copy.push("res/");
copy_items(&paths_to_copy, out_dir, &copy_options)?;
Ok(())
}

@ -0,0 +1,17 @@
struct FragmentOutput {
[[location(0)]] fColor: vec4<f32>;
};
var<private> fColor: vec4<f32>;
fn main1() {
fColor = vec4<f32>(f32(1));
return;
}
[[stage(fragment)]]
fn main() -> FragmentOutput {
main1();
let e3: vec4<f32> = fColor;
return FragmentOutput(e3);
}

@ -0,0 +1,20 @@
struct VertexOutput {
[[builtin(position)]] member: vec4<f32>;
};
var<private> aPosition1: vec2<f32>;
var<private> gl_Position: vec4<f32>;
fn main1() {
let e2: vec2<f32> = aPosition1;
gl_Position = vec4<f32>(e2, f32(0), f32(1));
return;
}
[[stage(vertex)]]
fn main([[location(0)]] aPosition: vec2<f32>) -> VertexOutput {
aPosition1 = aPosition;
main1();
let e5: vec4<f32> = gl_Position;
return VertexOutput(e5);
}

@ -24,6 +24,22 @@ fn main() {
.unwrap();
window.set_cursor_visible(false);
#[cfg(target_arch = "wasm32")]
{
use winit::platform::web::WindowExtWebSys;
console_log::init_with_level(log::Level::Info).expect("Could't initialize logger");
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
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 cavas to document body.");
}
log::info!("Setup...");
let mut render = pollster::block_on(render::Render::new(&window, &video_mode));
let mut state = state::State {
ball: state::Ball {
@ -90,11 +106,15 @@ fn main() {
game_state: state::GameState::MainMenu,
};
log::info!("Sound...");
let sound_system = sound::SoundSystem::new();
let sound_pack = sound::SoundPack::new();
let mut events = Vec::new();
let mut input = Input::new();
log::info!("Initializing Systems...");
let mut menu_system = system::MenuSystem;
let mut serving_system = system::ServingSystem::new();
let mut play_system = system::PlaySystem;
@ -108,6 +128,8 @@ fn main() {
window.set_visible(true);
log::info!("Event Loop...");
event_loop.run(move |event, _, control_flow| {
*control_flow = if state.game_state == state::GameState::Quiting {
ControlFlow::Exit
@ -154,7 +176,7 @@ fn main() {
}
state::Event::Score(_) => {
sound_system.queue(sound_pack.bounce());
} // _ => {}
}
}
}
events.clear();

@ -81,8 +81,8 @@ impl Render {
&pipeline_layout,
config.format,
&[Vertex::DESC],
wgpu::include_spirv!("../../res/shaders/textured.vert.spv"),
wgpu::include_spirv!("../../res/shaders/textured.frag.spv"),
wgpu::include_wgsl!("../../res/shaders/textured.vert.wgsl"),
wgpu::include_wgsl!("../../res/shaders/textured.frag.wgsl"),
);
let vertex_buffer = device.create_buffer(&wgpu::BufferDescriptor {

@ -0,0 +1,23 @@
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<!--
This is adapted from https://github.com/gfx-rs/wgpu/blob/master/run-wasm-example.sh
Eventually I'll have all the examples create there own components for vuepress to
use, but this will do for now.
-->
<script type="module">
import init from "./pong.js";
window.addEventListener("load", () => {
init();
});
</script>
</body>
</html>
Loading…
Cancel
Save