rust-gpu v0.8
As we keep following Rust's release cadence, it's time for another release of Rust-GPU!
Our project aimed at making Rust a first class language and ecosystem for GPU programming.
You can read more about why we at Embark started this project in the original announcement.
For Rust-GPU 0.8.0
, the Rust nightly version has been updated to nightly-2023-04-15
,
so make sure to update your rust-toolchain.toml
file when upgrading to Rust-GPU 0.8.0
.
This Rust nightly is equivalent (in language and library features) to the stable Rust 1.70.0
version, released this week.
As usual, you can find a complete list of changes in the changelog, but keep reading for the highlights.
The SPIR-🇹 shader IR framework is now mandatory
Our SPIR-🇹 shader IR framework started with the goal of allowing us to work with GPU shaders beyond the limitations of manipulating them in their standard SPIR-V form (which is what Rust-GPU has been doing). Back in Rust-GPU 0.4.0
, we introduced it as opt-in (behind a --spirt
flag), and in Rust-GPU 0.6.0
it became enabled by default (with a --no-spirt
opt-out).
While the role it plays in Rust-GPU is still minimal by default (with some experiments behind flags), almost all our plans for improving Rust-GPU's support for the Rust language (such as the qptr
experiment) revolve around relying more and more on it, for every step necessary to map Rust semantics onto GPU shader (SPIR-V) semantics.
With this focus on SPIR-🇹 in mind, and to avoid the maintenance cost of duplicate codepaths and testing (not to mention an eventual feature parity gap), we've decided to remove --no-spirt
, making SPIR-🇹 mandatory going forward.
How may users be impacted by the removal of --no-spirt
?
The most obvious reason one would've used --no-spirt
in previous Rust-GPU versions is to work around bugs or incompatibilities unique to SPIR-🇹, which, while entirely possible, is not something we are aware of being done in practice.
If you do encounter such bugs, please report them as a Rust-GPU GitHub issue (and/or as a SPIR-🇹 issue, if the nature of the bug is unambiguous).
But more commonly, --no-spirt
has been used by wgpu
users to work around naga
issue #1977.
wgpu
uses naga
internally for shader language (and SPIR-V) support, and Rust-GPU loops may cause it to error with:
Shader validation error:
┌─ :1:1
│
1 │
│ naga::Function [1]
Function [1] '' is invalid
The `break` is used outside of a `loop` or `switch` context
While --no-spirt
didn't guarantee naga
would behave correctly, it did work in more cases than with SPIR-🇹 enabled.
(this was due to some differences in how structured control-flow is represented - SPIR-V supports both while
and do
-while
loops, but naga
only implemented while
loops initially, and SPIR-🇹 always emits do
-while
loops)
That naga
bug has since been fixed, and the fix is present in:
naga 0.11.1
, for users ofwgpu 0.15
naga 0.12.1
, for users ofwgpu 0.16
- future
naga
versions (starting with0.13
, to be used by futurewgpu
versions)
If you've been using --no-spirt
to work around this naga
bug, you should be able to update to one of the above versions by using cargo update -p naga
, and you can search for "naga"
in Cargo.lock
(or cargo tree
) to check its version.
Further error reporting improvements
Rust-GPU 0.7.0
improved error reporting in some respects, but there were still limitations in how much detail we could record in SPIR-V to be used for error reporting. We've since started using a custom "extended instruction set" (SPIR-V OpExtInst
) to give us additional flexibility.
The main improvement is in replacing the basic standard SPIR-V file:line:col
debuginfo (OpLine
), with a custom one that supports source location ranges as well (which is normally expected of all Rust diagnostics).
Using the same example as the Rust-GPU 0.7.0
release notes:
old (standard) approach | new (custom) approach (0.8.0 ) |
---|---|
We've also added support to our inliner to generate custom debuginfo, to distinguish inlined callee code, from the surrounding caller code. While most errors are reported before any functions are inlined, all SPIR-🇹 passes currently run after the inliner, and in the future diagnostics could ideally be reported at the very end (to maximize the chances of the underlying issue to be legalized away, instead of being reported as an error to the user).
This is the same example, but with RUSTGPU_CODEGEN_ARGS="--no-early-report-zombies"
(which delays some reporting):
without any inliner debuginfo support | with inliner debuginfo support (0.8.0 ) |
---|---|
For the first error, all functions were inlined and "called by" didn't even show up in the diagnostics at all, but now it does. There are still some differences between the two errors, but all the useful information should always be present now.