v22.0.0 (Our first major version release!)
Our first major version release!
For the first time ever, WGPU is being released with a major version (i.e., 22.* instead of 0.22.*)! Maintainership has decided to fully adhere to Semantic Versioning's recommendations for versioning production software. According to SemVer 2.0.0's Q&A about when to use 1.0.0 versions (and beyond):
How do I know when to release 1.0.0?
If your software is being used in production, it should probably already be 1.0.0. If you have a stable API on which users have come to depend, you should be 1.0.0. If you’re worrying a lot about backward compatibility, you should probably already be 1.0.0.
It is a well-known fact that WGPU has been used for applications and platforms already in production for years, at this point. We are often concerned with tracking breaking changes, and affecting these consumers' ability to ship. By releasing our first major version, we publicly acknowledge that this is the case. We encourage other projects in the Rust ecosystem to follow suit.
Note that while we start to use the major version number, WGPU is not "going stable", as many Rust projects do. We anticipate many breaking changes before we fully comply with the WebGPU spec., which we expect to take a small number of years.
Overview
A major (pun intended) theme of this release is incremental improvement. Among the typically large set of bug fixes, new features, and other adjustments to WGPU by the many contributors listed below, @Wumpf and @teoxoy have merged a series of many simplifications to WGPU's internals and, in one case, to the render and compute pass recording APIs. Many of these change WGPU to use atomically reference-counted resource tracking (i.e., Arc<…>
), rather than using IDs to manage the lifetimes of platform-specific graphics resources in a registry of separate reference counts. This has led us to diagnose and fix many long-standing bugs, and net some neat performance improvements on the order of 40% or more of some workloads.
While the above is exciting, we acknowledge already finding and fixing some (easy-to-fix) regressions from the above work. If you migrate to WGPU 22 and encounter such bugs, please engage us in the issue tracker right away!
Major Changes
Lifetime bounds on wgpu::RenderPass
& wgpu::ComputePass
wgpu::RenderPass
& wgpu::ComputePass
recording methods (e.g. wgpu::RenderPass:set_render_pipeline
) no longer impose a lifetime constraint to objects passed to a pass (like pipelines/buffers/bindgroups/query-sets etc.).
This means the following pattern works now as expected:
let mut pipelines: Vec<wgpu::RenderPipeline> = ...;
// ...
let mut cpass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor::default());
cpass.set_pipeline(&pipelines[123]);
// Change pipeline container - this requires mutable access to `pipelines` while one of the pipelines is in use.
pipelines.push(/* ... */);
// Continue pass recording.
cpass.set_bindgroup(...);
Previously, a set pipeline (or other resource) had to outlive pass recording which often affected wider systems,
meaning that users needed to prove to the borrow checker that Vec<wgpu::RenderPipeline>
(or similar constructs)
aren't accessed mutably for the duration of pass recording.
Furthermore, you can now opt out of wgpu::RenderPass
/wgpu::ComputePass
's lifetime dependency on its parent wgpu::CommandEncoder
using wgpu::RenderPass::forget_lifetime
/wgpu::ComputePass::forget_lifetime
:
fn independent_cpass<'enc>(encoder: &'enc mut wgpu::CommandEncoder) -> wgpu::ComputePass<'static> {
let cpass: wgpu::ComputePass<'enc> = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor::default());
cpass.forget_lifetime()
}
wgpu::RenderPass
/wgpu::ComputePass
is pending for a given wgpu::CommandEncoder
, creation of a compute or render pass is an error and invalidates the wgpu::CommandEncoder
.
forget_lifetime
can be very useful for library authors, but opens up an easy way for incorrect use, so use with care.
This method doesn't add any additional overhead and has no side effects on pass recording.
By @Wumpf in #5569, #5575, #5620, #5768 (together with @kpreid), #5671, #5794, #5884.
Querying shader compilation errors
Wgpu now supports querying shader compilation info.
This allows you to get more structured information about compilation errors, warnings and info:
...
let lighting_shader = ctx.device.create_shader_module(include_wgsl!("lighting.wgsl"));
let compilation_info = lighting_shader.get_compilation_info().await;
for message in compilation_info
.messages
.iter()
.filter(|m| m.message_type == wgpu::CompilationMessageType::Error)
{
let line = message.location.map(|l| l.line_number).unwrap_or(1);
println!("Compile error at line {line}");
}
By @stefnotch in #5410
64 bit integer atomic support in shaders.
Add support for 64 bit integer atomic operations in shaders.
Add the following flags to wgpu_types::Features
:
-
SHADER_INT64_ATOMIC_ALL_OPS
enables all atomic operations onatomic<i64>
and
atomic<u64>
values. -
SHADER_INT64_ATOMIC_MIN_MAX
is a subset of the above, enabling only
AtomicFunction::Min
andAtomicFunction::Max
operations onatomic<i64>
and
atomic<u64>
values in theStorage
address space. These are the only 64-bit
atomic operations available on Metal as of 3.1.
Add corresponding flags to naga::valid::Capabilities
. These are supported by the
WGSL front end, and all Naga backends.
Platform support:
-
On Direct3d 12, in
D3D12_FEATURE_DATA_D3D12_OPTIONS9
, if
AtomicInt64OnTypedResourceSupported
andAtomicInt64OnGroupSharedSupported
are
both available, then both wgpu features described above are available. -
On Metal,
SHADER_INT64_ATOMIC_MIN_MAX
is available on Apple9 hardware, and on
hardware that advertises both Apple8 and Mac2 support. This also requires Metal
Shading Language 2.4 or later. Metal does not yet support the more general
SHADER_INT64_ATOMIC_ALL_OPS
. -
On Vulkan, if the
VK_KHR_shader_atomic_int64
extension is available with both the
shader_buffer_int64_atomics
andshader_shared_int64_atomics
features, then both
wgpu features described above are available.
A compatible surface is now required for request_adapter()
on WebGL2 + enumerate_adapters()
is now native only.
When targeting WebGL2, it has always been the case that a surface had to be created before calling request_adapter()
.
We now make this requirement explicit.
Validation was also added to prevent configuring the surface with a device that doesn't share the same underlying
WebGL2 context since this has never worked.
Calling enumerate_adapters()
when targeting WebGPU used to return an empty Vec
and since we now require users
to pass a compatible surface when targeting WebGL2, having enumerate_adapters()
doesn't make sense.
New features
General
- Added
as_hal
forBuffer
to access wgpu created buffers form wgpu-hal. By @JasondeWolff in #5724 include_wgsl!
is now callable in const contexts by @9SMTM6 in #5872- Added memory allocation hints to
DeviceDescriptor
by @nical in #5875MemoryHints::Performance
, the default, favors performance over memory usage and will likely cause large amounts of VRAM to be allocated up-front. This hint is typically good for games.MemoryHints::MemoryUsage
favors memory usage over performance. This hint is typically useful for smaller applications or UI libraries.MemoryHints::Manual
allows the user to specify parameters for the underlying GPU memory allocator. These parameters are subject to change.- These hints may be ignored by some backends. Currently only the Vulkan and D3D12 backends take them into account.
Naga
-
Added -D, --defines option to naga CLI to define preprocessor macros by @theomonnom in #5859
-
Added type upgrades to SPIR-V atomic support. Added related infrastructure. Tracking issue is here. By @schell in #5775.
-
Implement
WGSL
'sunpack4xI8
,unpack4xU8
,pack4xI8
andpack4xU8
. By @VlaDexa in #5424 -
Began work adding support for atomics to the SPIR-V frontend. Tracking issue is here. By @schell in #5702.
-
In hlsl-out, allow passing information about the fragment entry point to omit vertex outputs that are not in the fragment inputs. By @Imberflur in #5531
-
In spv-out, allow passing
acceleration_structure
as a function argument. By @kvark in #5961let writer: naga::back::hlsl::Writer = /* ... */; -writer.write(&module, &module_info); +writer.write(&module, &module_info, None);
-
HLSL & MSL output can now be added conditionally on the target via the
msl-out-if-target-apple
andhlsl-out-if-target-windows
features. This is used in wgpu-hal to no longer compile with MSL output whenmetal
is enabled & MacOS isn't targeted and no longer compile with HLSL output whendx12
is enabled & Windows isn't targeted. By @Wumpf in #5919
Vulkan
WebGPU
- Added support for pipeline-overridable constants to the WebGPU backend by @DouglasDwyer in #5688
Changes
General
- Unconsumed vertex outputs are now always allowed. Removed
StageError::InputNotConsumed
,Features::SHADER_UNUSED_VERTEX_OUTPUT
, and associated validation. By @Imberflur in #5531 - Avoid introducing spurious features for optional dependencies. By @bjorn3 in #5691
wgpu::Error
is nowSync
, making it possible to be wrapped inanyhow::Error
oreyre::Report
. By @nolanderc in #5820- Added benchmark suite. By @cwfitzgerald in #5694, compute passes by @Wumpf in #5767
- Improve performance of
.submit()
by 39-64% (.submit()
+.poll()
by 22-32%). By @teoxoy in #5910 - The
trace
wgpu feature has been temporarily removed. By @teoxoy in #5975
Metal
-
Removed the
link
Cargo feature.This was used to allow weakly linking frameworks. This can be achieved with putting something like the following in your
.cargo/config.toml
instead:[target.'cfg(target_vendor = "apple")'] rustflags = ["-C", "link-args=-weak_framework Metal -weak_framework QuartzCore -weak_framework CoreGraphics"]
Bug Fixes
General
- Ensure render pipelines have at least 1 target. By @ErichDonGubler in #5715
wgpu::ComputePass
now internally takes ownership ofQuerySet
for bothwgpu::ComputePassTimestampWrites
as well as timestamp writes and statistics query, fixing crashes when destroyingQuerySet
before ending the pass. By @Wumpf in #5671- Validate resources passed during compute pass recording for mismatching device. By @Wumpf in #5779
- Fix staging buffers being destroyed too early. By @teoxoy in #5910
- Fix attachment byte cost validation panicking with native only formats. By @teoxoy in #5934
- [wgpu] Fix leaks from auto layout pipelines. By @teoxoy in #5971
- [wgpu-core] Fix length of copy in
queue_write_texture
(causing UB). By @teoxoy in #5973 - Add missing same device checks. By @teoxoy in #5980
GLES / OpenGL
- Fix
ClearColorF
,ClearColorU
andClearColorI
commands being issued beforeSetDrawColorBuffers
#5666 - Replace
glClear
withglClearBufferF
becauseglDrawBuffers
requires that the ith buffer must beCOLOR_ATTACHMENTi
orNONE
#5666 - Return the unmodified version in driver_info. By @valaphee in #5753