wgpu: the shared GPU layer
One GPU API for Vulkan, Metal, D3D and the browser.
wgpu is a Rust implementation of the WebGPU API that runs on Metal, Vulkan, Direct3D 12, OpenGL and, in a browser, the real WebGPU. Application code is the same everywhere. The first step is always the same: create an instance, ask for an adapter (a physical GPU), then open a device and a queue. The output below is from the Mac that built this book.
use book_error::Result;
fn main() -> Result<()> {
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle());
// Ask for the best GPU the OS and drivers will give us. Having no GPU is a
// normal condition, so this is an error value and not a panic.
let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions::default()))?;
let info = adapter.get_info();
println!("{} via {:?}", info.name, info.backend);
// A device is the logical connection; the queue submits work to it.
let (_device, _queue) = pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor::default()))?;
Ok(())
} Intel(R) Iris(TM) Plus Graphics via MetalThe adapter reports which backend it used: here an Intel GPU through Metal. Note the constructor: in wgpu 30 an InstanceDescriptor has no Default; you pick new_without_display_handle() or new_with_display_handle(), so that the OpenGL backend can be told whether a display exists. This is the sort of change that shows up in every major version.
fn main() {
// Metal on macOS, Vulkan/GL on Linux, D3D12 on Windows, WebGPU in a browser.
let mut desc = wgpu::InstanceDescriptor::new_without_display_handle();
desc.backends = wgpu::Backends::PRIMARY;
let instance = wgpu::Instance::new(desc);
// No usable GPU? Ask for a software adapter instead: the route a
// "software rendering" fallback takes.
let options = wgpu::RequestAdapterOptions {
force_fallback_adapter: true,
..Default::default()
};
match pollster::block_on(instance.request_adapter(&options)) {
Ok(a) => println!("fallback: {}", a.get_info().name),
Err(e) => println!("no software adapter here: {e}"),
}
} no software adapter here: No suitable graphics adapter found; noop not requested, vulkan support not compiled in, metal had no fallback adapters, dx12 support not compiled in, gl not requested, webgpu support not compiled inforce_fallback_adapter asks for a software implementation, the route a "no GPU available" mode would take. On this Mac none exists and wgpu says exactly why. That is the reason several frameworks keep a CPU renderer (Floem's README describes one built on tiny-skia, and Slint has a software renderer) and a reason software paths keep appearing in this ecosystem. wgpu is now the common GPU layer under egui, Slint, Vello and Floem, and versions 29 and 30 shipped in 2026.