Architecture - gfx-rs/wgpu GitHub Wiki
Architecture
Here's an overview of wgpu's architecture:
Working through this diagram from the bottom up:
- 
Each operating system provides its own API (or APIs) for getting at the GPU: - 
On Windows, Direct3D is the primary GPU programming API, but Vulkan and OpenGL are often also available. 
- 
On macOS, Metal is the official GPU programming API, although OpenGL is still around for legacy programs, and the MoltenVK open source project implements the Vulkan API on top of Metal. 
- 
On Linux, the Mesa library supports Vulkan and OpenGL. 
 If you want to write an application that runs on all three of these platforms, you have a few options: - 
You could target Vulkan, and for macOS support embed MoltenVK, or require your users to install it. 
- 
You could target OpenGL, which is no longer being developed and is missing many modern features, and worry that macOS will drop support for it altogether. 
- 
You could port it to all three native platform APIs: Direct3D, Vulkan, and Metal. This would be a lot of code. 
- 
Or, you could just use wgpu! 
 
- 
- 
The wgpu_halcrate implements a portable Rust API that can use any of the platform-specific APIs mentioned above as a backend: a program that useswgpu_halcorrectly should behave consistently regardless of what platform you're running on.However, wgpu_hal's interface is completely unsafe; you must follow all of its safety requirements to the letter to avoid provoking undefined behavior from the underlying platforms. These requirements are complex, and not well-documented. Andwgpu_halperforms almost no validation beyond the minimum necessary to ensure portability.
- 
The wgpu_corecrate builds onwgpu_halto provide a API with a similar flavor, preserving its portability, and adding full bullet-proof validation. By "bullet-proof", we mean thatwgpu_coreis intended to be driven by untrusted code, like web content using the WebGPU API.wgpu_coreonly assumes that Rust's safety rules are respected. Safe Rust code should not be able to cause a crash usingwgpu_core.This means that wgpu_coreis fully responsible for things like tracking resource lifetimes, generating barriers for usage transitions, checking parameters, and so on. We cover its duties in more detail below.The wgpu_corecrate's API is designed to be easy to use from other languages via foreign function interfaces (FFI). This restricts the Rust features we can use in the API somewhat. But this makeswgpu_corethe best dependency for crates likewgpu_nativeand applications like Deno and Firefox that have their own binding systems.
- 
The wgpucrate provides an idiomatic Rust API on top ofwgpu_core, inheriting its validation and portability. This is what most users in the Rust ecosystem will want.
Other WebGPU implementations
Note that wgpu represents only one possible way to implement the WebGPU API; Google's Dawn and WebKit's WebGPU module are other WebGPU implementations used in production.
Concepts
Lifetime tracking, resource locking
TODO (why/how)
Tracker, handling of barriers
Unlike Vulkan & DX12, WebGPU does not track resource barriers (more info). Therefore, wgpu needs to track and insert barriers.
ResourceTracker keeps track of the current usage of a single kind type of resource.
TrackerSet ("the" tracker) has ResourceTracker for every type.
Since every CommandBuffer is recorded independently, each of them has a TrackerSet. Each render pass has a separate TrackerSet, and so does each bind group. These tracker sets flow into the parent trackers:
- When a bind group is set in a render pass, it's tracked resources are merged into the pass resources.
- When a render pass is finished recording, it's tracker is merged into the command buffer's tracker, with needed barriers issued.
- Command buffer trackers are combined during queue_submitinto the device's tracker. additional resource barriers are generated if necessary.
MemoryInitTracker
Tracks memory initialization state of Buffer resources, i.e. if they have been written to either by the user or by wgpu previously zero-initializing it (WebGPU requires all buffers to behave as-if they are zero inititialized). A MemoryInitTracker tracks a single buffer and allows to insert zero initialization lazily on use. Zero init is inserted if necessary at:
- memory mapping
- queue_submit(for all bindings)
Device maintain
TODO (what/why)
TODO
What else is non-trivial?
API Tracing
Enabled via feature flag. Allows to record all usage (WebGPU api functions essentially) to a .ron file. Any additional data (uploaded data to buffer etc.) is stored in additional files.
A trace can be replayed with the Player compiled from the same wgpu revision.
Used for testing and bug reporting.