Skip to content
This repository has been archived by the owner on Jun 18, 2021. It is now read-only.

Commit

Permalink
Add web backend
Browse files Browse the repository at this point in the history
  • Loading branch information
grovesNL committed Mar 17, 2020
1 parent 82c8f34 commit 1084bbd
Show file tree
Hide file tree
Showing 8 changed files with 1,686 additions and 509 deletions.
114 changes: 100 additions & 14 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,26 @@ default = []
# Make Vulkan backend available on platforms where it is by default not, e.g. macOS
vulkan = ["wgn/vulkan-portability"]

[dependencies.wgn]
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.wgn]
package = "wgpu-native"
version = "0.4"
git = "https://github.com/gfx-rs/wgpu"
rev = "39f17e50754aba6beeeabdd868ddfd700f9710c5"
#path = "../wgpu/wgpu-native"
#git = "https://github.com/gfx-rs/wgpu"
#rev = "39f17e50754aba6beeeabdd868ddfd700f9710c5"
path = "../wgpu/wgpu-native"

[dependencies.wgc]
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.wgc]
package = "wgpu-core"
version = "0.1"
git = "https://github.com/gfx-rs/wgpu"
rev = "39f17e50754aba6beeeabdd868ddfd700f9710c5"
#path = "../wgpu/wgpu-core"
#git = "https://github.com/gfx-rs/wgpu"
#rev = "39f17e50754aba6beeeabdd868ddfd700f9710c5"
path = "../wgpu/wgpu-core"

[dependencies.wgt]
package = "wgpu-types"
version = "0.1"
git = "https://github.com/gfx-rs/wgpu"
rev = "39f17e50754aba6beeeabdd868ddfd700f9710c5"
#path = "../wgpu/wgpu-types"
#git = "https://github.com/gfx-rs/wgpu"
#rev = "39f17e50754aba6beeeabdd868ddfd700f9710c5"
path = "../wgpu/wgpu-types"

[dependencies]
arrayvec = "0.5"
Expand All @@ -51,11 +51,97 @@ raw-window-handle = "0.3"

[dev-dependencies]
cgmath = "0.17"
env_logger = "0.7"
glsl-to-spirv = "0.1"
#glsl-to-spirv = "0.1"
log = "0.4"
png = "0.15"
winit = "0.22"
winit = { version = "0.22", features = ["web-sys"] }
rand = "0.7.2"
zerocopy = "0.2"
futures = "0.3"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
env_logger = "0.7"

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2.59"
web-sys = { version = "0.3.36", features = [
"Document",
"Navigator",
"Node",
"NodeList",
"Gpu",
"GpuAdapter",
"GpuBindGroup",
"GpuBindGroupBinding",
"GpuBindGroupDescriptor",
"GpuBindGroupLayout",
"GpuBindGroupLayoutBinding",
"GpuBindGroupLayoutDescriptor",
"GpuBlendDescriptor",
"GpuBlendFactor",
"GpuBlendOperation",
"GpuBindingType",
"GpuBuffer",
"GpuBufferBinding",
"GpuBufferDescriptor",
"GpuCanvasContext",
"GpuColorDict",
"GpuColorStateDescriptor",
"GpuCommandBuffer",
"GpuCommandBufferDescriptor",
"GpuCommandEncoder",
"GpuCommandEncoderDescriptor",
"GpuCompareFunction",
"GpuComputePassDescriptor",
"GpuComputePassEncoder",
"GpuComputePipeline",
"GpuComputePipelineDescriptor",
"GpuCullMode",
"GpuDepthStencilStateDescriptor",
"GpuDevice",
"GpuDeviceDescriptor",
"GpuFrontFace",
"GpuIndexFormat",
"GpuInputStepMode",
"GpuLimits",
"GpuLoadOp",
"GpuPipelineLayout",
"GpuPipelineLayoutDescriptor",
"GpuPowerPreference",
"GpuPrimitiveTopology",
"GpuProgrammableStageDescriptor",
"GpuQueue",
"GpuRasterizationStateDescriptor",
"GpuRenderPassColorAttachmentDescriptor",
"GpuRenderPassDepthStencilAttachmentDescriptor",
"GpuRenderPassDescriptor",
"GpuRenderPassEncoder",
"GpuRenderPipeline",
"GpuRenderPipelineDescriptor",
"GpuRequestAdapterOptions",
"GpuSampler",
"GpuShaderModule",
"GpuShaderModuleDescriptor",
"GpuStencilOperation",
"GpuStencilStateFaceDescriptor",
"GpuStoreOp",
"GpuSwapChain",
"GpuSwapChainDescriptor",
"GpuTexture",
"GpuTextureFormat",
"GpuTextureViewDimension",
"GpuTextureView",
"GpuVertexAttributeDescriptor",
"GpuVertexBufferLayoutDescriptor",
"GpuVertexFormat",
"GpuVertexStateDescriptor",
"GpuVertexAttributeDescriptor",
"HtmlCanvasElement",
"Window",
]}
js-sys = "0.3.36"
wasm-bindgen-futures = "0.4.9"

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
console_error_panic_hook = "0.1.6"
console_log = "0.1.2"
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ The `hello-triangle` and `hello-compute` examples show bare-bones setup without
cargo run --example hello-compute 1 2 3 4
```

#### Run Examples on the Web (`wasm32-unknown-unknown`)

To run examples on the `wasm32-unknown-unknown` target, first build the example as usual, then run `wasm-bindgen`:

```bash
# Install or update wasm-bindgen-cli
cargo install -f wasm-bindgen-cli
# Build with the wasm target
RUSTFLAGS=--cfg=web_sys_unstable_apis cargo build --example hello-triangle --target wasm32-unknown-unknown
# Generate bindings in a `target/generated` directory
wasm-bindgen target/wasm32-unknown-unknown/debug/examples/hello-triangle.wasm --out-dir target/generated --web
```

## Friends

Shout out to the following projects that work best with wgpu-rs:
Expand Down
41 changes: 17 additions & 24 deletions examples/hello-compute/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use std::{convert::TryInto as _, str::FromStr};
use zerocopy::AsBytes as _;
use std::{convert::TryInto, str::FromStr};

async fn run() {
let numbers = if std::env::args().len() == 1 {
let numbers = if std::env::args().len() <= 1 {
let default = vec![1, 2, 3, 4];
log::info!("No numbers were provided, defaulting to {:?}", default);
default
} else {
std::env::args()
.skip(1)
.map(|s| u32::from_str(&s).expect("You must pass a list of positive integers!"))
.map(|s| u32::from_str(&s)
.expect("You must pass a list of positive integers!"))
.collect()
};

Expand Down Expand Up @@ -109,28 +110,20 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
}
}

fn main() {
env_logger::init();
futures::executor::block_on(run());
#[cfg(target_arch = "wasm32")]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen::prelude::wasm_bindgen(start))]
pub fn wasm_main() {
console_log::init().expect("could not initialize log");
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
wasm_bindgen_futures::spawn_local(run());
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_compute_1(){
let input = vec!(1, 2, 3, 4);
futures::executor::block_on(assert_execute_gpu(input, vec!(0, 1, 7, 2)));
}

#[test]
fn test_compute_2(){
let input = vec!(5, 23, 10, 9);
futures::executor::block_on(assert_execute_gpu(input, vec!(5, 15, 6, 19)));
}
#[cfg(target_arch = "wasm32")]
fn main() {
}

async fn assert_execute_gpu(input: Vec<u32>, expected: Vec<u32>){
assert_eq!(execute_gpu(input).await, expected);
}
#[cfg(not(target_arch = "wasm32"))]
fn main() {
env_logger::init();
futures::executor::block_on(run());
}
36 changes: 30 additions & 6 deletions examples/hello-triangle/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use winit::{
async fn run(event_loop: EventLoop<()>, window: Window) {
let size = window.inner_size();
let surface = wgpu::Surface::create(&window);

let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
Expand Down Expand Up @@ -35,10 +34,12 @@ async fn run(event_loop: EventLoop<()>, window: Window) {

let bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[] });

let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &bind_group_layout,
bindings: &[],
});

let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[&bind_group_layout],
});
Expand All @@ -62,7 +63,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
}),
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
color_states: &[wgpu::ColorStateDescriptor {
format: wgpu::TextureFormat::Bgra8UnormSrgb,
format: wgpu::TextureFormat::Bgra8Unorm,
color_blend: wgpu::BlendDescriptor::REPLACE,
alpha_blend: wgpu::BlendDescriptor::REPLACE,
write_mask: wgpu::ColorWrite::ALL,
Expand All @@ -77,7 +78,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) {

let mut sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::Bgra8UnormSrgb,
format: wgpu::TextureFormat::Bgra8Unorm,
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Mailbox,
Expand All @@ -86,7 +87,8 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
let mut swap_chain = device.create_swap_chain(&surface, &sc_desc);

event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
// TODO: ControlFlow::Poll;
*control_flow = ControlFlow::Wait;
match event {
Event::MainEventsCleared => window.request_redraw(),
Event::WindowEvent { event: WindowEvent::Resized(size), .. } => {
Expand Down Expand Up @@ -126,9 +128,31 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
}
});
}

#[cfg(target_arch = "wasm32")]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen::prelude::wasm_bindgen(start))]
pub fn wasm_main() {
main();
}

fn main() {
let event_loop = EventLoop::new();
let window = winit::window::Window::new(&event_loop).unwrap();
env_logger::init();
futures::executor::block_on(run(event_loop, window));
#[cfg(not(target_arch = "wasm32"))]
{
env_logger::init();
futures::executor::block_on(run(event_loop, window));
}
#[cfg(target_arch = "wasm32")]
{
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
use winit::platform::web::WindowExtWebSys;
// 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");
wasm_bindgen_futures::spawn_local(run(event_loop, window));
}
}
14 changes: 13 additions & 1 deletion src/backend/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
pub(crate) mod native_gpu_future;
#[cfg(target_arch = "wasm32")]
mod web;
#[cfg(target_arch = "wasm32")]
pub use web::*;

#[cfg(not(target_arch = "wasm32"))]
mod native;

#[cfg(not(target_arch = "wasm32"))]
pub use native::*;

#[cfg(not(target_arch = "wasm32"))]
mod native_gpu_future;
Loading

0 comments on commit 1084bbd

Please sign in to comment.