| Crates.io | minwebgpu |
| lib.rs | minwebgpu |
| version | 0.2.0 |
| created_at | 2024-09-10 07:12:03.543931+00 |
| updated_at | 2025-08-09 20:18:23.393792+00 |
| description | Minimal WebGPU toolkit for modern graphics programming with compute shaders and rendering pipelines |
| homepage | https://github.com/Wandalen/cgtools/tree/master/module/min/minwebgpu |
| repository | https://github.com/Wandalen/cgtools |
| max_upload_size | |
| id | 1370123 |
| size | 188,984 |
Modern WebGPU wrapper for next-generation web graphics
A safe, ergonomic Rust wrapper around WebGPU for high-performance graphics and compute in the browser. Built for the future of web graphics with compute shader support, modern rendering pipelines, and optimal WebAssembly integration.
[dependencies]
minwebgpu = { workspace = true, features = ["enabled"] }
wasm-bindgen = "0.2"
web-sys = "0.3"
use minwebgpu as gpu;
use wasm_bindgen::prelude::*;
#[wasm_bindgen(start)]
pub async fn main() -> Result<(), JsValue> {
// Get WebGPU adapter and device
let instance = gpu::Instance::new()?;
let adapter = instance.request_adapter().await?;
let device = adapter.request_device().await?;
// Create canvas and surface
let canvas = gpu::canvas::make()?;
let surface = instance.create_surface(&canvas)?;
Ok(())
}
use minwebgpu as gpu;
// WGSL vertex shader
let vertex_shader = r#"
@vertex
fn vs_main(@location(0) position: vec2<f32>) -> @builtin(position) vec4<f32> {
return vec4<f32>(position, 0.0, 1.0);
}
"#;
// WGSL fragment shader
let fragment_shader = r#"
@fragment
fn fs_main() -> @location(0) vec4<f32> {
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
"#;
// Create shader modules
let vs_module = gpu::shader::create(&device, vertex_shader);
let fs_module = gpu::shader::create(&device, fragment_shader);
// Create render pipeline
let pipeline = gpu::render_pipeline::desc(
gpu::VertexState::new(&vs_module)
.buffer(&vertex_layout)
)
.fragment(
gpu::FragmentState::new(&fs_module)
.target(gpu::ColorTargetState::new().format(surface_format))
)
.primitive(gpu::PrimitiveState::new().triangle_list())
.create(&device)?;
use minwebgpu as gpu;
// WGSL compute shader
let compute_shader = r#"
@group(0) @binding(0) var<storage, read_write> data: array<f32>;
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
let index = global_id.x;
if (index >= arrayLength(&data)) { return; }
data[index] = data[index] * 2.0;
}
"#;
// Create compute pipeline
let compute_module = gpu::shader::create(&device, compute_shader);
let compute_pipeline = gpu::compute_pipeline::desc(
gpu::ComputeState::new(&compute_module)
).create(&device)?;
// Create storage buffer
let buffer = gpu::BufferInitDescriptor::new(
&input_data,
gpu::BufferUsage::STORAGE | gpu::BufferUsage::COPY_SRC
).create(&device)?;
// Dispatch compute work
let mut encoder = device.create_command_encoder();
let mut compute_pass = encoder.begin_compute_pass();
compute_pass.set_pipeline(&compute_pipeline);
compute_pass.set_bind_group(0, &bind_group);
compute_pass.dispatch_workgroups(workgroup_count, 1, 1);
compute_pass.end();
| Module | Description | Key Types |
|---|---|---|
instance |
WebGPU instance and adapter | Instance, Adapter |
device |
Device and queue management | Device, Queue |
shader |
WGSL shader compilation | ShaderModule, create() |
buffer |
Buffer operations | Buffer, BufferInitDescriptor |
texture |
Texture management | Texture, TextureView, Sampler |
render_pipeline |
Render pipeline creation | RenderPipeline, desc() |
compute_pipeline |
Compute pipeline creation | ComputePipeline, desc() |
command |
Command encoding | CommandEncoder, RenderPass, ComputePass |
WebGPU uses descriptor-based pipeline creation:
let pipeline = gpu::render_pipeline::desc(
gpu::VertexState::new(&vs_module)
.buffer(&vertex_buffer_layout)
)
.fragment(
gpu::FragmentState::new(&fs_module)
.target(gpu::ColorTargetState::new().format(gpu::TextureFormat::Bgra8unormSrgb))
)
.primitive(gpu::PrimitiveState::new().triangle_list())
.depth_stencil(gpu::DepthStencilState::new())
.multisample(gpu::MultisampleState::new().count(4))
.create(&device)?;
Type-safe buffer operations:
// Vertex buffer
let vertices: [Vertex; 3] = [...];
let vertex_buffer = gpu::BufferInitDescriptor::new(
&vertices,
gpu::BufferUsage::VERTEX
).create(&device)?;
// Uniform buffer
let uniforms = UniformData { ... };
let uniform_buffer = gpu::BufferInitDescriptor::new(
&uniforms,
gpu::BufferUsage::UNIFORM | gpu::BufferUsage::COPY_DST
).create(&device)?;
Resource binding for shaders:
let bind_group_layout = device.create_bind_group_layout(&gpu::BindGroupLayoutDescriptor {
entries: &[
gpu::BindGroupLayoutEntry::uniform(0, gpu::ShaderStage::VERTEX),
gpu::BindGroupLayoutEntry::texture(1, gpu::ShaderStage::FRAGMENT),
gpu::BindGroupLayoutEntry::sampler(2, gpu::ShaderStage::FRAGMENT),
],
});
let bind_group = device.create_bind_group(&gpu::BindGroupDescriptor {
layout: &bind_group_layout,
entries: &[
gpu::BindGroupEntry::buffer(0, &uniform_buffer),
gpu::BindGroupEntry::texture_view(1, &texture_view),
gpu::BindGroupEntry::sampler(2, &sampler),
],
});
// Parallel array processing
let compute_pipeline = gpu::compute_pipeline::desc(
gpu::ComputeState::new(&compute_module)
).create(&device)?;
// Dispatch with workgroups
compute_pass.dispatch_workgroups(
(data_size + 63) / 64, // Round up to workgroup size
1,
1
);
let pipeline = gpu::render_pipeline::desc(vertex_state)
.fragment(
gpu::FragmentState::new(&fs_module)
.target(gpu::ColorTargetState::new().format(gpu::TextureFormat::Rgba8unorm))
.target(gpu::ColorTargetState::new().format(gpu::TextureFormat::Rgba16Float))
)
.create(&device)?;
// Create mappable buffer
let buffer = device.create_buffer(&gpu::BufferDescriptor {
size: data.len() as u64,
usage: gpu::BufferUsage::MAP_READ | gpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
// Map and read data
let buffer_slice = buffer.slice(..);
buffer_slice.map_async(gpu::MapMode::Read).await?;
let data = buffer_slice.get_mapped_range();
// Process data...
buffer.unmap();
WebGPU requires modern browser support:
# Build for web
wasm-pack build --target web --out-dir pkg
# Development with trunk
trunk serve --release
Part of the CGTools workspace. Feel free to submit issues and pull requests on GitHub.
MIT