Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mikbry/awesome-webgpu
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: IoTone/awesome-webgpu
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Able to merge. These branches can be automatically merged.
  • 2 commits
  • 6 files changed
  • 1 contributor

Commits on Oct 20, 2024

  1. Add a sample helloworld

    truedat101 committed Oct 20, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    db33ce9 View commit details
  2. Add docs

    truedat101 committed Oct 20, 2024
    Copy the full SHA
    fbdb0bf View commit details
2 changes: 2 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -37,7 +37,9 @@ WebGPU is a work in progress Web standard from [W3C](https://www.w3.org/) for mo
- [Working Draft](https://www.w3.org/TR/WGSL/)
- [Editor's Draft](https://gpuweb.github.io/gpuweb/wgsl/)

### Rust

- [WebGPU Showcase Rust](https://wgpu.rs/)
### API documentations
- [API quick reference and documentation](https://webgpu.rocks/) - WebGPU.rocks.
- [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API) - MDN WebGPU API references.
26 changes: 26 additions & 0 deletions tutorial-webgpu-y-wsgl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Overview

This is based on learnings from

https://www.amazon.com/WebGPU-WGSL-Example-Ray-Tracing-Simulations/dp/B0CYLFP88G/

## Install

- rust
- cargo
- cargo install webgpu

## Build

- cargo build

## Run

- cargo run

## Attributions

- ch3: https://github.com/gfx-rs/wgpu/tree/trunk/examples/src/hello_triangle



40 changes: 40 additions & 0 deletions tutorial-webgpu-y-wsgl/ch3/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Created by https://www.toptal.com/developers/gitignore/api/rust,visualstudiocode
# Edit at https://www.toptal.com/developers/gitignore?templates=rust,visualstudiocode

### Rust ###
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets

# Local History for Visual Studio Code
.history/

# Built Visual Studio Code Extensions
*.vsix

### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide

# End of https://www.toptal.com/developers/gitignore/api/rust,visualstudiocode

14 changes: 14 additions & 0 deletions tutorial-webgpu-y-wsgl/ch3/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "ch3"
version = "0.1.0"
edition = "2021"

[dependencies]
wgpu = { version = "22.1.0", default-features = false, features = [
"wgsl",
"dx12",
"metal",
] }
winit = { version = "0.29", features = ["android-native-activity"] }
env_logger = "0.11"
pollster = "0.3"
179 changes: 179 additions & 0 deletions tutorial-webgpu-y-wsgl/ch3/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
use std::borrow::Cow;
use winit::{
event::{Event, WindowEvent},
event_loop::EventLoop,
window::Window,
};

async fn run(event_loop: EventLoop<()>, window: Window) {
let mut size = window.inner_size();
size.width = size.width.max(1);
size.height = size.height.max(1);

let instance = wgpu::Instance::default();

let surface = instance.create_surface(&window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::default(),
force_fallback_adapter: false,
// Request an adapter which can render to our surface
compatible_surface: Some(&surface),
})
.await
.expect("Failed to find an appropriate adapter");

// Create the logical device and command queue
let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
label: None,
required_features: wgpu::Features::empty(),
// Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain.
required_limits: wgpu::Limits::downlevel_webgl2_defaults()
.using_resolution(adapter.limits()),
memory_hints: wgpu::MemoryHints::MemoryUsage,
},
None,
)
.await
.expect("Failed to create device");

// Load the shaders from disk
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
});

let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: None,
bind_group_layouts: &[],
push_constant_ranges: &[],
});

let swapchain_capabilities = surface.get_capabilities(&adapter);
let swapchain_format = swapchain_capabilities.formats[0];

let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: None,
layout: Some(&pipeline_layout),
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main", // Some("vs_main"),
buffers: &[],
compilation_options: Default::default(),
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main", // Some("fs_main"),
compilation_options: Default::default(),
targets: &[Some(swapchain_format.into())],
}),
primitive: wgpu::PrimitiveState::default(),
depth_stencil: None,
multisample: wgpu::MultisampleState::default(),
multiview: None,
cache: None,
});

let mut config = surface
.get_default_config(&adapter, size.width, size.height)
.unwrap();
surface.configure(&device, &config);

let window = &window;
event_loop
.run(move |event, target| {
// Have the closure take ownership of the resources.
// `event_loop.run` never returns, therefore we must do this to ensure
// the resources are properly cleaned up.
let _ = (&instance, &adapter, &shader, &pipeline_layout);

if let Event::WindowEvent {
window_id: _,
event,
} = event
{
match event {
WindowEvent::Resized(new_size) => {
// Reconfigure the surface with the new size
config.width = new_size.width.max(1);
config.height = new_size.height.max(1);
surface.configure(&device, &config);
// On macos the window needs to be redrawn manually after resizing
window.request_redraw();
}
WindowEvent::RedrawRequested => {
let frame = surface
.get_current_texture()
.expect("Failed to acquire next swap chain texture");
let view = frame
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
let mut encoder =
device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: None,
});
{
let mut rpass =
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: None,
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
});
rpass.set_pipeline(&render_pipeline);
rpass.draw(0..3, 0..1);
}

queue.submit(Some(encoder.finish()));
frame.present();
}
WindowEvent::CloseRequested => target.exit(),
_ => {}
};
}
})
.unwrap();
}

pub fn main() {
let event_loop = EventLoop::new().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();
pollster::block_on(run(event_loop, window));
}
#[cfg(target_arch = "wasm32")]
{
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
console_log::init().expect("could not initialize logger");
wasm_bindgen_futures::spawn_local(run(event_loop, window));
}
}
11 changes: 11 additions & 0 deletions tutorial-webgpu-y-wsgl/ch3/src/shader.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@vertex
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> {
let x = -f32(i32(in_vertex_index) - 1);
let y = -f32(i32(in_vertex_index & 1u) * 2 - 1);
return vec4<f32>(x, y, 0.0, 1);
}

@fragment
fn fs_main() -> @location(0) vec4<f32> {
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}